设计模式学习笔记
简介
设计模式(Design pattern),是世界顶级优秀开发者长期经验的科学总结。有助于设计开发出优秀的程序应用和解决开发过程中的一些问题。
使用设计模式利于代码的工程化,可靠性。每一种设计模式都是优秀工程师针对特定问题抽象模型而建立的解决方案。
GOF(四人帮,全拼Gang of Four)
Design Patterns - Elements of Reusable Object-Oriented Software(中文译名:设计模式 - 可复用的面向对象软件元素)该书首次提出软件开发中的设计模式的概念。
四位作者Erich Gamma
、Richard Helm
、Ralph Johnson
和John Vlissides
合称GOF,设计模式住哟啊基于以下面向对象的设计原则:
- 对接口编程而不是对实现编程。
- 优先使用对象组合而不是继承。
设计模式的使用
设计模式在软件开发中的两个主要用途:
开发人员的共同平台
设计模式提供了标准的术语系统,具体到特定场景,便于开发人员理解和使用统一标准。
最佳的实践
设计模式的总结是IT界优秀编程经验的总结,有助于开发者的快速提升。
设计模式的类型
设计模式参考书中提到共有23中设计模式。大致可分为三类:
创建型模式(Creation Patterns)
结构型模式(Structural Patterns)
行为型模式(Behavioral Patterns)
还有另一类设计模式:
J2EE
设计模式
序号 | 模式&描述 | 包括 |
---|---|---|
1 | 创建型模式(5):创建对象而隐藏创建逻辑的模式,且不适用新的运算符直接实例化对象。利于开发者灵活创建和使用实例对象。 | 工厂模式(Factory Pattern)、抽象工厂模式(Abstract Factory Pattern)、单例模式(singleton Pattern)、建造者模式(Builder Pattern)、原型模式(Prototype Pattern) |
2 | 结构型模式(8):关注类和对象的组合。继承的概念用于组合接口和定义组合对象,获得其功能。 | 适配器模式(Adapter Pattern)、桥接模式(Bridge Pattern)、过滤器模式(Filter、Criteria Pattern)、组合模式(Composite Pattern)、装饰器模式(Decorator Pattern)、外观模式(Facade Pattern)、享元模式(Flyweight Pattern)、代理模式(Proxy Pattern) |
3 | 行为型模式(12):关注对象间的通讯 | 责任链模式(Chain of Responsibility Pattern)、命令模式(Command Pattern)、解释器模式(Interpreter Pattern)、迭代器模式(Iterator Pattern)、中介者模式(Mediator Pattern)、备忘录模式(Memento Pattern)、观察者模式(Observer Pattern)、状态模式(State Pattern)、空对象模式(Null Object Pattern)、策略模式(Strategy Pattern)、模板模式(Template Pattern)、访问者模式(Visitor Pattern) |
4 | J2EE模式(8):特别关注表示层。 | MVC模式(MVC Pattern)、业务代表模式(Business Delegate Pattern)、组合实体模式(Composite Entity Pattern)、数据访问对象模式(Data Access Object Pattern)、前端控制器模式(Front Controller Pattern)、拦击过滤器模式(Intercepting Filter Pattern)、服务定位器模式(Service Locator Pattern)、传输对象模式(Transfer Object Pattern) |
设计模式关系图:
设计模式六大原则
开闭原则(Open Close Principle)
对扩展开放、对修改关闭。使用接口和抽象类来实现代码的热插拔功能效果。
里氏代换原则(Liskov Substitution Principle)
里氏代换原则是面向对象设计的基本原则之一。任何基类可以出现的地方,子类一定可以出现。==LSP==是继承服用的基石,是对开闭原则的补充。
依赖倒转原则(Dependence Inversion Principle)
本原则是开闭原则的基础:针对接口编程,依赖于抽象而不依赖于具体。
接口隔离原则(Interface Segregation Principle)
多个隔离的接口优于单个接口。降低类之间的耦合度。
迪米特法则/最少指导原则(Demeter Principle)
一个实体应尽量少的与其他实体之间发生相互作用,相对独立。
合成复用原则(Composite Reuse Principle)
尽量使用合成/聚合的方式,而不是使用继承。
一、工厂模式
工厂模式(Factory Pattern)是java中最常用的设计模式之一。属于创建型模式,提供了较佳的创建对象方式。
介绍
- 定义一个创建对象的接口,让其子类决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
- 用于解决接口选择的问题,在明确地计划不同条件下创建不同实例时候,使用该模式。
- 使子类实现工厂接口,返回一个抽象的产品,创建过程在子类中执行。
举个栗子:购买汽车,用户只需去工厂提车,而不需关注车辆的生产与组装。
优点:
- 调用便利,只需知道工厂名即可创建对象。
- 扩展性高,新增产品只需扩展工厂类即可。
- 封装性好,公开接口而屏蔽创建逻辑。
缺点:
- 新增产品成本高,需要新增一个具体类和对象实现工厂,从而增加了系统的负责与依赖。
注意事项:
作为创建型模式,可随地使用工厂模式,一般用于复杂对象的工厂化,简单对象直接
new
。
实现
如下图创建一个Shapte
接口和实现Shape
接口的几个实体类。定义工厂类ShapeFactory
。然后用FactoryPatternDemo来演示使用Shape Factory获取Shape对象。向Shape Factory传递参数(CIRCLE/RECTANGLE/SQUARE),来确定获取类型。
创建接口
shape.java
public interface Shape{ void draw(); }
创建接口实现类
rectangle.java
public class Rectangle implements Shape { @override public void draw(){ System.out.println("Inside Rectangle:: draw() method."); } }
square.java
public class Square implements Shape { @override public void draw(){ System.out.println("Inside Square:: draw() method."); } }
circle.java
public class Circle implements Shape { @override public void draw(){ System.out.println("Inside Circle:: draw() method."); } }
创建一个工厂,生成给定信息的实体类对象
ShapeFactory.java
public class ShapeFactory { //使用getShape方法获取形状类型的对象 public Shape getShape(String shapeType){ if(shapeType == null){ return null; } if(shapeType.equalsIgnoreCase("CIRCLE")){ return new Circle(); } else if (shapeType.equalsIgnoreCase("RECTANGLE")){ return new Rectangle(); } else if (shapeType.equalsIgnoreCase("SQUARE")){ return new Square(); } return null; } }
使用工厂,演示demo
FactoryPatternDemo.java
public class FactoryPatternDemo { public static void main(String[] args){ ShapeFactory shapeFactory = new ShapeFactory(); //获取Circle对象,调用其draw方法 Shape circle = shapeFactory.getShape("CIRCLE"); circle.draw(); //获取Square对象,调用draw方法 Shape square = shapeFactory.getShape("SQUARE"); square.draw(); //获取Rectangle对象,调用draw方法 Shape rect = shapeFactory.getShape("RECTANGLE"); rect.draw(); } }
输出结果
Inside Circle:: draw() method. Inside Square:: draw() method. Inside Rectangle:: draw() method.