適配器模式
定義
適配器模式(英語:adapter pattern)有時候也稱包裝樣式或者包裝。將一個類的接口轉接成用戶所期待的。一個適配使得因接口不兼容而不能在一起工作的類工作在一起。
有兩類適配器模式:
1. 對象適配器模式 - 對象適配器通過關聯滿足用戶期待接口,還降低了代碼間的不良耦合。在工作中推薦使用“對象適配”。
2. 類適配器模式 - 這種適配器模式下,適配器繼承自已實現的類(一般多重繼承),java中沒有多重繼承,所以這里不做介紹。
實現
1. Target - 定義Client需要使用的方法。
2. Adapter - 繼承或者實現Target,適配Adaptee的方法到Target。
3. Adaptee - 定義一個已經存在的方法。
4. Client - 調用Target中的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public class Adaptee { public void specificRequest(){ System.out.println( "Hello, I am from Adaptee!" ); } } public interface Target { public void request(); } public class Adapter implements Target { Adaptee adaptee; public Adapter(){ adaptee = new Adaptee(); } public void request(){ adaptee.specificRequest(); } } public class Client { public static void main(String[] args) { Target target = new Adapter(); target.request(); } } |
要實現類適配器模式,我們需要Adapter繼承Adaptee。
適用場景
1. 你想使用一個舊類,而它的接口不符合你的需求,那么可以使用Adapter類來作為中介類。
2. 你想創建一個可以通用的類,該類可以調用一些不相關的類的接口來供你使用。
橋接模式
動機
有些時候一個抽象應該有不同的實現,比如,保存數據時有兩種方式,一種是文件方式,一種是數據庫方式,通常的做法是繼承保存數據的類,然后實現不同的保存方式。這樣做的問題就是難于修改和擴展保存方式,運行時無法切換保存方式。
定義
橋接模式是軟件設計模式中最復雜的模式之一,它將事物的抽象部分與它的實現部分分離,使它們都可以獨立地變化。
如“圓形”、“三角形”歸于抽象的“形狀”之下,而“畫圓”、“畫三角”歸于實現行為的“畫圖”類之下,然后由“形狀”調用“畫圖”。
1. Abstraction - 定義抽象方法。
2. AbstractionImpl - 使用實現接口來實現抽象方法。
3. Implementor - 為具體實現行為定義接口。
4. ConcreteImplementor1, ConcreteImplementor2 - 實現Implementor接口。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
/** "Implementor" */ interface DrawingAPI { public void drawCircle( double x, double y, double radius); } /** "ConcreteImplementor" 1/2 */ class DrawingAPI1 implements DrawingAPI { public void drawCircle( double x, double y, double radius) { System.out.printf( "API1.circle at %f:%f radius %f\n" , x, y, radius); } } /** "ConcreteImplementor" 2/2 */ class DrawingAPI2 implements DrawingAPI { public void drawCircle( double x, double y, double radius) { System.out.printf( "API2.circle at %f:%f radius %f\n" , x, y, radius); } } /** "Abstraction" */ interface Shape { public void draw(); // low-level public void resizeByPercentage( double pct); // high-level } /** "Refined Abstraction" */ class CircleShape implements Shape { private double x, y, radius; private DrawingAPI drawingAPI; public CircleShape( double x, double y, double radius, DrawingAPI drawingAPI) { this .x = x; this .y = y; this .radius = radius; this .drawingAPI = drawingAPI; } // low-level i.e. Implementation specific public void draw() { drawingAPI.drawCircle(x, y, radius); } // high-level i.e. Abstraction specific public void resizeByPercentage( double pct) { radius *= pct; } } /** "Client" */ class BridgePattern { public static void main(String[] args) { Shape[] shapes = new Shape[ 2 ]; shapes[ 0 ] = new CircleShape( 1 , 2 , 3 , new DrawingAPI1()); shapes[ 1 ] = new CircleShape( 5 , 7 , 11 , new DrawingAPI2()); for (Shape shape : shapes) { shape.resizeByPercentage( 2.5 ); shape.draw(); } } } |
實例
1. 動機里面提到的數據保存。
2. 圖形的繪制框架。類似上面代碼中的實現。
適用場景
1. 你不希望抽象和實現有固定的關系,希望可以在運行時修改實現的方式。
2. 抽象和實現部分都可以獨立的擴展,而不相互影響。