1 策略模式
1.1 定义
策略模式定义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户。
1.2 结构图

1.3 代码
1 2 3
| abstract class Strategy { public abstract void AlgorithmInterface(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class ConcreteStrategyA extends Strategy { @override public void AlgorighmInterface() { } } class ConcreteStrategyB extends Strategy { @override public void AlgorighmInterface() { } } class ConcreteStrategyC extends Strategy { @override public void AlgorighmInterface() { } }
|
1 2 3 4 5 6 7 8 9 10
| class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void ContextInterface() { strategy.AlgorighmInterface(); } }
|
1.4 总结
策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
策略模式的Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。
2 装饰模式
2.1 定义
装饰模式定义:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。
2.2 结构图

2.3 代码
1 2 3
| interface Component { void Operation(); }
|
1 2 3 4 5 6
| public class ConcreteComponent implements Component { @override void Operation() { } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| public abstract class Decorator implements Component { protected Component component; public void setComponent(Component component) { this.component = component; } @override public void Operation() { if (component != null) { component.operation(); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class ConcreteDecoratorA extends Decorator { private String addedState; @override public void Opertaion() { super.opertion(); addedState = "new state"; } } class ConcreteDecoratorB extends Decorator { @override public void Operation() { super.opertaion(); AddedBehavior(); } private void AddedBehavior() { } }
|
1 2 3 4 5 6 7 8
| public static void main() { ConcreteDecoratorA d1 = new ConcreteDecoratorA(); ConcreteDecoratorB d2 = new ConcreteDecoratorB(); d2.setComponent(d1); d2.Operation(); }
|
具体实现中可能会与结构图有不同,如直接让Decorator
抽象类继承ConcreteComponent
类。
2.4 总结
装饰模式是为已有功能动态地添加更多功能的一种方式。
装饰模式提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。
3 代理模式
3.1 定义
代理模式定义:为其他对象提供一种代理以控制对这个对象的访问。
3.2 结构图

3.3 代码
1 2 3
| public abstract class Subject { public abstarct void Request(); }
|
1 2 3 4 5 6
| public class RealSubject extends Subject { @override public void Request() { } }
|
1 2 3 4 5 6 7 8 9 10
| public class Proxy extends Subject { RealSubject realSubject; @override public void Request() { if (realSubject == null) { realSubject = new RealSubject(); } realSubject.Request(); } }
|
3.4 总结
- 代理模式通常有如下几钟用途:
- 代理模式的主要优点:
- 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
- 代理对象可以扩展目标对象的功能;
- 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性;
4 工厂方法模式
4.1 定义
工厂方法模式定义:定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
4.2 结构图

4.3 代码
1 2
| class ConcreteProduct implements Product { }
|
1 2 3
| interface Factory { Product FactoryMethod(); }
|
1 2 3 4 5 6 7 8
| class ConcreteFactory implements Factory { @override public Product FactoryMethod() { Product product = new ConcreteProduct(); return product; } }
|
4.4 总结
- 优点
- 符合开闭原则
- 符合单一职责原则
- 不使用静态工厂方法,可以形成基于继承的等级结构
5 原型模式
5.1 定义
原型模式定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
5.2 结构图

5.3 代码
1 2 3 4
| public abstract class Prototype { private String id; public abstract Prototype Clone(); }
|
1 2 3 4 5 6 7
| class ConcretePrototype extends Prototype { @override public Protytpe Clone() { return newObject; } }
|
5.4 总结
具体实现时无需创建Prototype
接口,直接实现Java
中的Cloneable
接口即可。同时克隆时注意深拷贝和浅拷贝的问题。
6 模板方法模式
6.1 定义
模板方法模式定义:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
6.2 结构图

6.3 代码
1 2 3 4 5 6 7 8 9 10
| abstract class TemplateClass { public abstract void PrimitiveOpeartion1(); public abstract void PrimitiveOpeartion2();
public void TemplateMethod() { PrimitiveOpeartion1(); PrimitiveOpeartion2(); } }
|
1 2 3 4 5 6 7 8 9 10
| public class ConcreteClass extends TemplateClass { @override public void PrimitiveOperation1() { } @override public void PrimitiveOperation2() { } }
|
实现类实现抽象模板中定义的抽象方法。
6.4 总结
模板方法模式提供了一个很好的代码复用平台
。因为有时候,会遇到由一系列步骤构成的过程需要执行。这个过程从高层次上看是相同的,但有些步骤的实现可能不同。这时候,通常就应该要考虑用模板方法模式了。当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现。我们通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。
7 外观模式
7.1 定义
外观模式定义:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得子系统更加容易使用。
7.2 结构图

7.3 代码
1 2 3 4 5 6 7 8 9 10 11
| class SubSystemOne { public void MethodOne() { } }
class SubSystemTwo { public void MethodTwo() { } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Facade { private SubSystemOne subSystemOne; private SubSystemTwo subSystemTwo;
public Facade() { subSystemOne = new SubSystemOne(); subSystemTwo = new SubSystemTwo(); }
public void MethodA() { subSystemOne.MethodOne(); subSystemTwo.MethodTwo(); }
public void MethodB() { subSystemTwo.MethodTwo(); } }
|
7.4 总结
首先,在设计初期阶段,应该要有意识的将不同的两个层分离,比如经典的三层架构,就需要考虑在数据访问层和业务逻辑层、业务逻辑层和表示层的层与层之间建立外观Facade,这样可以为复杂的子系统提供一个简单的接口,使得耦合大大降低。其次,在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂,大多数的模式使用时也都会产生很多很小的类,这本是好事,但也给外部调用它们的用户程序带来了使用上的困难,增加外观Facade可以提供一个简单的接口,减少它们之间的依赖。第三,在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,但因为它包含非常重要的功能,新的需求开发必须要依赖于它。此时用外观模式Facade也是非常合适的。你可以为新系统开发一个外观Facade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作。
8 建造者模式
8.1 定义
建造者模式定义:也叫生成器模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
8.2 结构图

8.3 代码
1 2 3 4 5 6 7 8 9 10 11
| class Product { List<String> parts = new ArrayList<>(); public void Add(String part) { parts.add(part); }
public void Show() { } }
|
1 2 3 4 5
| interface Builder { void BuildPartA(); void BuildPartB(); Product GetResult(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class ConcreteBuilder implements Builder { private Product product = new Product(); @override public void BuilderPartA() { product.Add("部件A"); } @override public void BuilderPartB() { product.Add("部件B"); } @override public Product GetResult() { return product; } }
|
1 2 3 4 5 6
| class Director { public void Construct(Builder builder) { builder.BuildPartA(); builder.BuildPartB(); } }
|
8.4 总结
主要是用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。
9 观察者模式
9.1 定义
观察者模式:也叫做发布-订阅模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
9.2 结构图
