/java-design-pattern

java设计模式学习及demo

Primary LanguageJava

java-design-pattern

一、 什么是设计模式

设计模式(Design Patterns)是一套被反复使用、多数人知晓的、经过分类编目的代码设计经验的总结。它们提供了解决软件设计中常见问题的通用解决方案,是对面向对象设计中常见问题的总结与提炼。

主要特点

•	可重用性:设计模式解决的是软件开发中的一些通用问题,这些问题经常在不同的上下文中出现。设计模式通过提供通用的解决方案,使开发者能够重用经过验证的设计。
•	可扩展性:通过使用设计模式,代码可以在未来的需求变化中更容易被扩展,而不会造成过多的改动。
•	灵活性:设计模式的应用使得代码更加灵活,能够应对不同场景的需求变化。

二、 设计原则

1. 单一指责原则

单一职责原则(Single Responsibility Principle,简称 SRP)是面向对象编程中SOLID五大设计原则之一。每个类都应该只有一个职责(或功能),如果某个类承担了过多的职责,那么当某个职责变化时,可能会影响到类的其他职责。 单一职责原则的定义

一个类或模块应该仅有一个引起它变化的原因。

为什么需要单一职责原则?

1.	降低复杂性:如果一个类负责太多职责,它会变得过于复杂,难以维护和扩展。通过将不同职责拆分到不同的类中,代码的清晰度会提高。
2.	提高可维护性:职责明确的类更容易维护和修改。当某个需求变动时,只需要修改相关的类,不会影响到其他不相关的功能,降低了修改错误的风险。
3.	提高可复用性:职责单一的类往往更加独立,可以在不同的项目或上下文中重复使用,而不会引入额外的依赖。
4.	提高可测试性:类职责单一后,测试会变得更加容易,因为每个类只需要测试其一个职责,不会因为复杂的相互依赖而导致测试困难。

2. 开闭原则

开闭原则(Open/Closed Principle,简称 OCP)是面向对象设计的五大原则之一,倡导软件实体(如类、模块、函数)应该对扩展开放,对修改关闭。这是实现代码灵活性和可维护性的重要原则。

开闭原则的定义

一个软件实体应该对扩展开放,对修改关闭。

这意味着在软件开发过程中,当需要改变某个功能时,我们应该通过扩展来实现,而不是通过修改现有代码来完成。即,不需要去更改已有的代码,而是通过增加新的代码来应对需求变化。这可以减少引入错误的风险,并保持系统的稳定性。

为什么需要开闭原则?

1.	降低风险:修改现有代码时,很可能会引入新的 bug 或破坏已有功能。通过扩展新功能的方式,现有代码保持不变,降低了这种风险。
2.	提高可维护性:开闭原则使得代码在面对新需求时不需要频繁修改,而是可以通过增加新类或方法来适应需求,保持代码稳定。
3.	增强扩展性:当应用程序遵循开闭原则时,开发人员可以很容易地为系统增加新的功能,而不需要大规模修改现有代码。

如何实现开闭原则?

开闭原则的核心**是多态性和依赖抽象。通常可以通过以下方法来实现:

1.	使用抽象类或接口:通过定义接口或抽象类来约束行为,允许具体实现类自行扩展。
2.	使用继承和多态:利用继承关系,在基类不变的前提下,扩展新的子类来添加新功能。
3.	组合和委托:通过将职责委托给其他类来实现功能的扩展,而不是修改现有类。

3. 里氏替换原则

里氏替换原则(Liskov Substitution Principle,简称 LSP)是面向对象设计的五大原则之一,最早由计算机科学家 Barbara Liskov 提出。它的核心**是,子类对象必须能够替换父类对象,并且保证原有程序逻辑不被破坏。换句话说,程序中的父类能够被其子类替换,且不会导致程序出错。

里氏替换原则的定义

子类必须能够替换父类,且程序功能不受影响。

通俗来说,当你使用一个父类对象时,任何用到这个父类的地方都可以用其子类替换,并且不应该产生意外行为。如果子类无法完全替代父类,就说明子类违背了里氏替换原则。

为什么需要里氏替换原则?

1.	代码可维护性:遵循 LSP 可以避免子类对父类行为的破坏,确保系统在扩展时不会引入错误,从而提高代码的可维护性。
2.	代码复用:通过继承父类,子类可以复用父类的代码,避免重复编写相同的功能。
3.	提高灵活性:如果子类能够无缝替代父类,系统的扩展性和灵活性都会得到增强,允许系统更加容易地添加新功能或修改现有功能。

4. 依赖倒置原则

依赖倒置原则(Dependency Inversion Principle,简称 DIP)是面向对象设计的五大原则之一,主要目的是通过高层模块和低层模块之间的解耦,提升系统的灵活性和可维护性。

依赖倒置原则的核心**

高层模块不应该依赖于低层模块,两者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。

解释:

•	高层模块:通常是业务逻辑层,处理系统的核心功能。
•	低层模块:通常是基础设施层,例如数据访问、网络通信等。

按照依赖倒置原则的要求:

•	高层模块不应该直接依赖于具体的低层模块(细节实现),而是应该依赖于抽象(例如接口或抽象类),这样可以避免高层模块和低层模块之间的紧密耦合。
•	低层模块(实现类)也应该依赖于抽象(接口或抽象类),而不是直接定义具体的行为。通过这种方式,细节实现可以在不影响高层模块的情况下被替换或修改。

为什么需要依赖倒置原则?

1.	降低耦合:依赖倒置原则能够减少模块之间的依赖,使得模块更加独立。这让系统的扩展和维护更加容易。
2.	提高灵活性:通过依赖于抽象而非具体实现,可以更灵活地替换和扩展系统的功能。
3.	提高可测试性:如果高层模块依赖于抽象,而不是直接依赖低层模块,那么在测试时可以更容易地通过模拟或替换低层模块来进行单元测试。

5. 接口隔离原则

接口隔离原则(Interface Segregation Principle, ISP)是面向对象设计的五大基本原则之一。它的主要**是:

客户端不应该被迫依赖它不需要的接口。

也就是说,接口应该尽量小而专一,避免将多个不相关的功能放到同一个接口中,这样客户端可以只依赖自己需要的接口。

核心**

1.	接口要精简:接口不应该包含客户端不需要的方法,避免“胖接口”(即拥有过多方法的接口)。接口的功能应该尽量专一,避免不相关的方法被强制组合在一起。
2.	为不同的客户端提供专用接口:不同的客户端有不同的需求,每个客户端应该依赖于其专用的接口,避免客户端依赖多余的方法。
3.	避免接口污染:接口污染指的是一个接口提供了太多方法,这些方法并不是每个实现者都需要或者每个调用者都使用的。如果接口中有客户端不需要的内容,会导致实现类冗余,并且接口的变化会导致不必要的修改。

接口隔离原则的好处

•	提高灵活性:通过为不同的客户端提供专用的接口,可以减少接口之间的耦合,增强灵活性。
•	提高代码的可维护性:当接口中的方法只针对特定的业务需求时,接口的修改只会影响相关的实现类和客户端,减少不必要的修改风险。
•	更好的遵循“单一职责原则”:接口的职责更加单一,变得更容易理解、维护和实现。

三、设计模式及实现

1. 创建型模式

1.1 工厂模式

工厂模式是一种创建型设计模式,它通过定义一个用于创建对象的接口,让子类决定实例化哪一个类,主要用来解耦对象的创建过程和使用过程。 在面向对象编程中,直接实例化对象会导致代码的耦合度提高,工厂模式通过将对象的创建过程抽象出来,可以有效地降低代码的耦合度,提高代码的灵活性和可扩展性。

  • 1.1.1 简单工厂模式(Simple Factory) 定义:简单工厂模式是指由一个工厂类来决定创建哪种具体对象的实例。简单工厂模式通常是由静态方法来实现的。

优点:

•	将对象的创建集中在一起,易于管理和维护。
•	客户端不需要了解具体类的创建过程,只需要通过工厂调用即可获得对象实例。

缺点:

•	如果要增加新产品,需要修改工厂类的逻辑,违反了“开闭原则”(对扩展开放,对修改关闭)
  • 1.1.2 工厂方法模式(Factory Method)
  • 1.1.3 抽象工厂模式(Abstract Factory)

1.2 单例模式

1.3 原型模式

1.4 建造者模式

2. 结构型模式

2.1 适配器模式

2.2 桥接模式

2.3 装饰器模式

2.4 外观模式

2.5 享元模式

2.6 代理模式

3. 行为型模式

3.1 策略模式

3.2 模板方法模式

3.3 观察者模式

3.4 迭代器模式

3.5 责任链模式

3.6 命令模式

3.7 状态模式

3.8 备忘录模式

3.9 解释器模式

3.10 中介者模式

4. 小结及应用案例

4.1 设计模式总结

4.2 应用案例及实践