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