模式的定義
將抽象部分與實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立的變化炕矮。
模式的使用場(chǎng)景
如果一個(gè)系統(tǒng)需要在構(gòu)件的抽象化角色和具體化角色之間添加更多的靈活性么夫,避免在兩個(gè)層次之間建立靜態(tài)的聯(lián)系。設(shè)計(jì)要求實(shí)現(xiàn)化角色的任何改變不應(yīng)當(dāng)影響客戶端吧享,或者實(shí)現(xiàn)化角色的改變對(duì)客戶端是完全透明的魏割。需要跨越多個(gè)平臺(tái)的圖形和窗口系統(tǒng)上。一個(gè)類存在兩個(gè)獨(dú)立變化的維度钢颂,且兩個(gè)維度都需要進(jìn)行擴(kuò)展钞它。
UML類圖
角色介紹
抽象化(Abstraction)角色:抽象化給出的定義,并保存一個(gè)對(duì)實(shí)現(xiàn)化對(duì)象的引用殊鞭。 修正抽象化(Refined Abstraction)角色:擴(kuò)展抽象化角色遭垛,改變和修正父類對(duì)抽象化的定義。實(shí)現(xiàn)化(Implementor)角色:這個(gè)角色給出實(shí)現(xiàn)化角色的接口操灿,但不給出具體的實(shí)現(xiàn)锯仪。必須指出的是,這個(gè)接 口不一定和抽象化角色的接口定義相同趾盐,實(shí)際上庶喜,這兩個(gè)接口可以非常不一樣。實(shí)現(xiàn)化角色應(yīng)當(dāng)只給出底層操作救鲤,而抽象化角色應(yīng)當(dāng)只給出基于底層操作的更高一層的操作久窟。具體實(shí)現(xiàn)化(ConcreteImplementor)角色:這個(gè)角色給出實(shí)現(xiàn)化角色接口的具體實(shí)現(xiàn)。
模式的簡(jiǎn)單實(shí)現(xiàn)
- 介紹
其實(shí)Java的虛擬機(jī)就是一個(gè)很好的例子本缠,在不同平臺(tái)平臺(tái)上斥扛,用不同的虛擬機(jī)進(jìn)行實(shí)現(xiàn),這樣只需把Java程序編譯成符合虛擬機(jī)規(guī)范的文件丹锹,且只用編譯一次稀颁,便在不同平臺(tái)上都能工作芬失。 但是這樣說(shuō)比較抽象,用一個(gè)簡(jiǎn)單的例子來(lái)實(shí)現(xiàn)bridge模式匾灶。
編寫(xiě)一個(gè)程序棱烂,使用兩個(gè)繪圖的程序的其中一個(gè)來(lái)繪制矩形或者原型,同時(shí)粘昨,在實(shí)例化矩形的時(shí)候垢啼,它要知道使用繪圖程序1(DP1)還是繪圖程序2(DP2)窜锯。
(ps:假設(shè)dp1和dp2的繪制方式不一樣张肾,它們是用不同方式進(jìn)行繪制,示例代碼锚扎,不討論過(guò)多細(xì)節(jié))
- 實(shí)現(xiàn)源碼
首先是兩個(gè)繪圖程序dp1,dp2
//具體的繪圖程序類dp1
public class DP1 {
public void draw_1_Rantanle(){
System.out.println("使用DP1的程序畫(huà)矩形");
}
public void draw_1_Circle(){
System.out.println("使用DP1的程序畫(huà)圓形");
}
}
//具體的繪圖程序類dp2
public class DP2 {
public void drawRantanle(){
System.out.println("使用DP2的程序畫(huà)矩形");
}
public void drawCircle(){
System.out.println("使用DP2的程序畫(huà)圓形");
}
}
接著?抽象的形狀Shape和兩個(gè)派生類:矩形Rantanle和圓形Circle
//抽象化角色Abstraction
abstract class Shape {
//持有實(shí)現(xiàn)的角色I(xiàn)mplementor(作圖類)
protected Drawing myDrawing;
public Shape(Drawing drawing) {
this.myDrawing = drawing;
}
abstract public void draw();
//保護(hù)方法drawRectangle
protected void drawRectangle(){
//this.impl.implmentation()
myDrawing.drawRantangle();
}
//保護(hù)方法drawCircle
protected void drawCircle(){
//this.impl.implmentation()
myDrawing.drawCircle();
}
}
//修正抽象化角色Refined Abstraction(矩形)
public class Rantangle extends Shape{
public Rantangle(Drawing drawing) {
super(drawing);
}
@Override
public void draw() {
drawRectangle();
}
}
//修正抽象化角色Refined Abstraction(圓形)
public class Circle extends Shape {
public Circle(Drawing drawing) {
super(drawing);
}
@Override
public void draw() {
drawCircle();
}
}
最后吞瞪,我們的實(shí)現(xiàn)繪圖的Drawing和分別實(shí)現(xiàn)dp1的V1Drawing和dp2的V2Drawing
//實(shí)現(xiàn)化角色I(xiàn)mplementor
//implmentation兩個(gè)方法,畫(huà)圓和畫(huà)矩形
public interface Drawing {
public void drawRantangle();
public void drawCircle();
}
//具體實(shí)現(xiàn)化邏輯ConcreteImplementor
//實(shí)現(xiàn)了接口方法驾孔,使用DP1進(jìn)行繪圖
public class V1Drawing implements Drawing{
DP1 dp1;
public V1Drawing() {
dp1 = new DP1();
}
@Override
public void drawRantangle() {
dp1.draw_1_Rantanle();
}
@Override
public void drawCircle() {
dp1.draw_1_Circle();
}
}
//具體實(shí)現(xiàn)化邏輯ConcreteImplementor
//實(shí)現(xiàn)了接口方法芍秆,使用DP2進(jìn)行繪圖
public class V2Drawing implements Drawing{
DP2 dp2;
public V2Drawing() {
dp2 = new DP2();
}
@Override
public void drawRantangle() {
dp2.drawRantanle();
}
@Override
public void drawCircle() {
dp2.drawCircle();
}
}
在這個(gè)示例中,圖形Shape類有兩種類型翠勉,圓形和矩形妖啥,為了使用不同的繪圖程序繪制圖形,把實(shí)現(xiàn)的部分進(jìn)行了分離对碌,構(gòu)成了Drawing類層次結(jié)構(gòu)荆虱,包括V1Drawing和V2Drawing。在具體實(shí)現(xiàn)類中朽们,V1Drawing控制著DP1程序進(jìn)行繪圖怀读,V2Drawing控制著DP2程序進(jìn)行繪圖,以及保護(hù)的方法drawRantangle,drawCircle(Shape類中) 骑脱。