设计模式
装饰器模式
装饰器模式(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