??? 1:代理模式:
??? 為其它對象提供一種代理以控制對目標對象的訪問。即第三方對象通過訪問代理對象而達到訪問目標對象之目的,與此同時,代理對象在訪問目標對象前后加入特定的邏輯以實現功能的擴展。
???? 以靜態代理為例:
package?static_proxy;
public?interface?Movable?{
????public?void?move();
}
package?static_proxy;
import?java.util.Random;
public?class?Tank?implements?Movable?{
????@Override
????public?void?move()?{
????????System.out.println("?Tank?is?moving?
?");
????????try?{
????????????Thread.sleep(new?Random().nextInt(1000));
????????}?catch?(InterruptedException?e)?{
????????????e.printStackTrace();
????????}
????}
}
package?static_proxy;
public?class?TankLogProxy?implements?Movable?{
????private?Movable?obj;
????public?TankLogProxy(Movable?obj)?{
????????super();
????????this.obj?=?obj;
????}
????@Override
????public?void?move()?{
????????System.out.println("the?log?is?begin?
?");
????????obj.move();
????????System.out.println("the?log?is?end?
?");
????}
}
package?static_proxy;
public?class?TankTimeProxy?implements?Movable?{????
????private?Movable?obj;
????public?TankTimeProxy(Movable?obj)?{
????????super();
????????this.obj?=?obj;
????}
????@Override
????public?void?move()?{
????????long?begintime?=?System.currentTimeMillis();
????????System.out.println("?Tank?is?begining?to?move?!");
????????obj.move();
????????long?endtime?=?System.currentTimeMillis();
????????System.out.println("?Tank?is?stop?!");
????????System.out.println("move?time?:?"+(endtime-begintime));
????}
}
package?static_proxy;
public?class?Client?{
????/**
?????*?@param?args
?????*/
????public?static?void?main(String[]?args)?{
????????Movable?tankTime?=?new?TankTimeProxy(new?Tank());
????????Movable?tankLog?=?new?TankLogProxy(tankTime);
????????tankLog.move();
????}
}
代理模式:目標對象和代理對象實現同一接口;代理對象訪問目標對象時在其前后加入一定的邏輯實現功能擴展;可多次代理。
2.裝飾者模式:
????
動態地給一個對象添加一些額外的職責。就增加功能來說,裝飾模式相比生成子類更加靈活。
package?decorator;
public?abstract?class?car_parent?{
????//?汽車抽象父類
????private?String?make_address;
????private?int?speed;
????public?String?getMake_address()?{
????????return?make_address;
????}
????public?void?setMake_address(String?make_address)?{
????????this.make_address?=?make_address;
????}
????public?int?getSpeed()?{
????????return?speed;
????}
????public?void?setSpeed(int?speed)?{
????????this.speed?=?speed;
????}
????public?abstract?void?print_face();
}
package?decorator;
public?abstract?class?decorator_parent?extends?car_parent?{
????//?裝飾者父類
????protected?car_parent?car_parent_ref;
????public?decorator_parent(car_parent?carParentRef)?{
????????super();
????????car_parent_ref?=?carParentRef;
????}
????@Override
????public?void?print_face()?{
????????car_parent_ref.print_face();
????}
}
package?decorator;
public?class?decorator_audi_red?extends?decorator_parent?{
????public?decorator_audi_red(car_parent?carParentRef)?{
????????super(carParentRef);
????}
????@Override
????public?void?print_face()?{
????????super.print_face();
????????System.out.println("給 奧迪 噴涂鴉 - 顏色為 紅色火焰");
????}
}
package?decorator;
public?class?decorator_audi_purple?extends?decorator_parent?{
????public?decorator_audi_purple(car_parent?carParentRef)?{
????????super(carParentRef);
????}
????@Override
????public?void?print_face()?{
????????super.print_face();
????????System.out.println("給 奧迪 噴涂鴉 - 顏色為 紫色霞光");
????}
}
package?decorator;
public?class?main_run?{
????public?static?void?main(String[]?args)?{
????????car_parent?audi_sub_ref?=?new?audi_sub();
????????audi_sub_ref.setMake_address("北京市朝陽區");
????????audi_sub_ref.setSpeed(200);
????????
????????decorator_audi_red?decorator_audi_red_ref?=?new?decorator_audi_red(audi_sub_ref);
????????decorator_audi_purple?decorator_audi_purple_ref?=?new?decorator_audi_purple(decorator_audi_red_ref);
????????decorator_audi_purple_ref.print_face();
????}
}
裝飾者模式:裝飾者和被裝飾者應繼承或實現同一父類或接口,以表示它們為同一類對象(非必須);裝飾者對象對被裝飾者對象增加一定的職責;可多次裝飾。
可以發現:代理模式和裝飾者模式上在語法形式上幾乎完全一樣,那么它們的區別在哪里呢?
裝飾者模式:動態地給一個對象添加一些額外的職責。就增加功能來說,裝飾模式相比生成子類更加靈活代理模式:
為其它對象提供一種代理以控制對這個對象的訪問。其實,它們的著重點一個在于“增加”職責,另一個在于“控制”訪問。這是它們最本質的區別。
由此可以看到:學習設計模式重點在于“語義”上把握,而不是追求它的“形式。