没记错的话,在大学里面学习c++一定会遇到下面的这个题目:
写一个函数,实现两个变量值互相交换:
void swap(int* p1,int* p2)
{
int temp;
temp=*p1;
*p1=*p2;
*p2=temp;
}
int main()
{
int i=3,j=5;
swap(&i,&j);
return 0;
}
c/c++中有函数传值有两种方式,一种是值传递,一种是址传递.效果就是值传递的情况下,函数内的操作不会影响到实参.而址传递情况下,函数内的操作会反映到实参.
c语言中使用指针来实现址传递.但是c++中还可以使用变量引用(别名)达到同样的效果.
void swap(int &a,int &b)
{
int temp;
temp=a;
a=b;
b=temp;
}
int main()
{
int i=3,j=5;
swap(i,j);
return 0;
}
java呢?
java中对于基本数据类型是传值,而对于对象来说基本都是引用.
大家在学习java的时候,老师都会讲到这个情况吧?问:
Object a = new Object();
a是什么?
答:对象引用
是不是说,在java中函数传值如果是对象就是像c++一样的引用呢?举个栗子:
package Temp;
/**
* Hello world!
*
*/
public class App
{
//基本数据类型
public static void swapA(int a,int b){
int temp=a;
a=b;
b=temp;
}
//对象引用
public static void swapB(Integer a,Integer b){
Integer temp=a;
a=b;
b=temp;
}
//使用类封装两个操作数
static class Swaper{
private int a;
private int b;
int getA() {
return a;
}
void setA(int a) {
this.a = a;
}
int getB() {
return b;
}
void setB(int b) {
this.b = b;
}
}
//只操作引用对象内的属性
public static void swapC(Swaper swaper){
int temp = swaper.getA();
swaper.setA(swaper.getB());
swaper.setB(temp);
}
//只封装一个数
static class INT{
private int a;
int getValue() {
return a;
}
void setValue(int a) {
this.a = a;
}
}
//对引用直接操作
public static void swapD(INT a,INT b){
INT temp=a;
a=b;
b=temp;
}
public static void main( String[] args )
{
int a=3,b=5;
swapA(a,b);
System.out.println(a+" "+b);//3 5
Integer obj_a=new Integer(3);
Integer obj_b=new Integer(5);
swapB(obj_a,obj_b);
System.out.println(obj_a.toString()+obj_b.toString());//35
Swaper swaper=new Swaper();
swaper.setA(3);
swaper.setB(5);
swapC(swaper);
System.out.println(swaper.getA()+" "+swaper.getB());//5 3
INT I_a=new INT();
I_a.setValue(3);
INT I_b=new INT();
I_b.setValue(5);
swapD(I_a,I_b);
System.out.println(I_a.getValue()+" "+I_b.getValue());//3 5
}
}
看来情况并不是想象中那个样子.java中虽然对象是引用类型,但是却不允许函数改变引用的值.但是可以通过引用改变引用对象内部的属性.
这玩意和设计模式有半毛钱关系吗?
有,而且上面swapC方法,就是建造者模式核心的思想.
建造者模式中有两个主要的类/接口,一个是指挥者类,负责把握建造过程,一个是建造者接口(也可以是类/抽象类)负责统一建造步骤.
//指挥者类
public class Director {
public void construct(Builder builder){//对象引用传值
builder.buildPart1();
builder.buildPart2();
}
}
//建造者抽象 抽象类实现
public abstract class Builder {
public abstract void buildPart1();
public abstract void buildPart2();
}
//具体建造者
public class BuilderA extends Builder {
@Override
public void buildPart1() {
//相关操作
}
@Override
public void buildPart2() {
//相关操作
}
}
//--------------------------------------------------------
//调用时的代码
BuilderA ba=new BuilderA();
Director d=new Director();
d.construct(ba);//操作反馈到builder身上
如果只看指挥者类与具体建造者类之间的调用,这其实就是典型的通过引用改变引用对象内部属性的操作思维.建造者模式只不过这在基础上增加了一个封装的概念使指挥者不再指挥某个具体的类,而是可以指挥一批相似结构的类.
设计模式中,除了建造者模式还有很多设计模式使用了这个思想,比如原型模式与访问者模式.只不过它们不像建造者模式这么直接.当然建造者模式也包含上一集讨论的封装的思想.
设计模式之所以精妙,其实就是它把很多特性巧妙的融合在一起形成类似化学反应一样的效果.
不知道各位看了今天这一集是不是对设计模式有了全新的理解呢?