設計模式
裝飾器模式
裝飾器模式(Decorator Pattern)是一種結構型設計模式,它允許你動態地爲對象添加新的行爲,而不改變其結構或影響其他對象。這種模式通過將對象放入一個“包裝器”(即裝飾器對象)中,以便在保持原始對象類型不變的情況下,擴展或修改其行爲。
- 對象組合:裝飾器模式依賴於對象組合(composition),而不是繼承(inheritance)。你可以將一個對象嵌套在另一個對象中,從而添加額外的功能。
- 遵循接口:裝飾器和被裝飾對象通常都實現相同的接口或繼承相同的父類,因此可以互換使用。
- 動態擴展:裝飾器模式可以在運行時爲對象添加新的功能,而不像繼承那樣在編譯時就固定了行爲。
下麵是一個裝飾器模式的示例代碼
1 2 3 4 5
| interface Coffee { String getDescription(); double getCost(); }
|
1 2 3 4 5 6 7 8 9 10 11 12
| class SimpleCoffee implements Coffee { @Override public String getDescription() { return "Simple Coffee"; }
@Override public double getCost() { return 5.0; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| abstract class CoffeeDecorator implements Coffee { protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) { this.decoratedCoffee = coffee; }
@Override public String getDescription() { return decoratedCoffee.getDescription(); }
@Override public double getCost() { return decoratedCoffee.getCost(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class MilkDecorator extends CoffeeDecorator { public MilkDecorator(Coffee coffee) { super(coffee); }
@Override public String getDescription() { return decoratedCoffee.getDescription() + ", Milk"; }
@Override public double getCost() { return decoratedCoffee.getCost() + 1.5; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class SugarDecorator extends CoffeeDecorator { public SugarDecorator(Coffee coffee) { super(coffee); }
@Override public String getDescription() { return decoratedCoffee.getDescription() + ", Sugar"; }
@Override public double getCost() { return decoratedCoffee.getCost() + 0.5; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class CoffeeShop { public static void main(String[] args) { Coffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);
System.out.println("Description: " + coffee.getDescription()); System.out.println("Cost: $" + coffee.getCost()); } }
|
UML
summary
被修飾的是一個接口(coffee)的實現類(SimpleCoffee),裝飾類的基類是CoffeeDecorator,兩個裝飾器分別是MilkDecorator和SugarDecorator。
在這個場景下,MilkDecorator和SugarDecorator裝飾了SimpleCoffee,擴展了它的功能而且並沒有改變被修飾類的結構和繼承關繫。
適配器模式
適配器模式(Adapter Pattern)是一種結構型設計模式,它用於將一個類的接口轉換成客戶期望的另一個接口,使得原本由於接口不兼容而不能一起工作的類可以協同工作。適配器模式特別有用在你想複用一些現有的類,但它們的接口不符合你的需求時。
- 接口轉換:適配器模式的核心是接口轉換,它通過引入一個適配器類,把現有類的接口轉化爲客戶所期望的接口。
- 類適配器與對象適配器:
- 類適配器:使用繼承來實現適配器功能。
- 對象適配器:使用組合來實現適配器功能,更加靈活,因爲它不依賴於具體的實現而是依賴於接口。
下麵是一個適配器模式的示例代碼
1 2 3 4
| interface PowerSocket { void plugIn(); }
|
1 2 3 4 5 6
| class OldPlug { void connect() { System.out.println("Old plug connected."); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| class PlugAdapter implements PowerSocket { private OldPlug oldPlug;
public PlugAdapter(OldPlug oldPlug) { this.oldPlug = oldPlug; }
@Override public void plugIn() { oldPlug.connect(); } }
|
1 2 3 4 5 6 7 8
| public class AdapterPatternExample { public static void main(String[] args) { OldPlug oldPlug = new OldPlug(); PowerSocket adapter = new PlugAdapter(oldPlug); adapter.plugIn(); } }
|
UML
代理模式
代理模式簡而言之就是在不改變原始接口的前提下,使用另一個接口對原始接口的功能進行擴展。
下麵是一個代理模式的示例代碼
1 2 3 4
| public interface Browser { void request(); }
|
1 2 3 4 5 6 7
| public class BrowserImpl implements Browser { @Override public void request() { System.out.println("Sending Request...."); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Proxy implements Browser { private final Browser browser; public Proxy(BrowserImpl browser) { this.browser = browser; } @Override public void request() { System.out.println("Proxy handling request...."); browser.request(); } }
|
1 2 3 4 5 6 7 8
| public class Client { public static void main(String[] args) { BrowserImpl browser = new BrowserImpl(); Proxy proxy = new Proxy(browser); proxy.request(); } }
|
1 2 3
| Output: Proxy handling request.... Sending Request....
|
UML