1. 概述
在开发过程中,对于较大型项目使用常见的数据模式来管理对象的创建,可以提高系统的可扩展性和可维护性。设计模式的核心是为了 找到变化,封装变化。
什么是变化变化包含对象的创建、使用和销毁。这里面包含6种设计原则和23种设计模式。
1.1 设计原则
6种设计原则有:单一职责原则、里氏替换原则、依赖倒置原则、开闭原则、迪米特法则、接口隔离原则。
-
单一职责原则:又称单一功能原则。一个类应该只有一个引起它变化的原因。换句话说,一个类应该只有一项职责。这样可以保证类的内聚性,并且降低类之间的耦合性。优点是:降低类的负责度、提高类的可读性和提高系统的可维护性。
-
开闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。这意味着当需要添加新功能时,应该尽量通过扩展已有代码来实现,而不是修改已有代码。
-
里氏替换原则:子类应该能够替换父类并且不影响程序的正确性。这意味着在使用继承时,子类不能修改父类已有的行为,而只能扩展父类的功能。
-
接口隔离原则:客户端不应该依赖于它不需要的接口。一个类应该只提供它需要的接口,而不应该强迫客户端依赖于它不需要的接口。
-
依赖倒置原则:高层模块不应该依赖于低层模块,它们都应该依赖于抽象。抽象不应该依赖于具体实现,而具体实现应该依赖于抽象。
-
迪米特法则:一个对象应该对其他对象保持最少的了解。换句话说,一个对象只应该与它直接相互作用的对象发生交互,而不应该与其它任何对象发生直接的交互。这样可以降低类之间的耦合性,提高系统的灵活性和可维护性。
1.2 设计模式
总体来说设计模式分为三大类:
创建型模式,共5种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共7种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
2. 设计模式介绍
设计模式(Design Patterns)是软件开发中针对常见问题提供的最佳实践解决方案,它们能够提高代码的可复用性、可维护性和可扩展性。根据其用途,设计模式通常被划分为三大类:创建型模式 、结构型模式 和行为型模式。以下是23种常见的设计模式介绍:
2.1 创建型模式(Creational Patterns)
这些模式主要关注对象的创建机制,抽象化对象的创建过程。
1. 单例模式(Singleton Pattern)
-
目的:确保一个类只有一个实例,并提供全局访问点。
-
应用场景:数据库连接池、线程池等。
-
实现:私有构造函数,静态实例变量,提供公共的获取实例的方法。
javapublic class Singleton { private static Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
2. 工厂方法模式(Factory Method Pattern)
-
目的:定义一个创建对象的接口,让子类决定实例化哪一个类。
-
应用场景:当创建对象的过程需要灵活性时。
-
实现:通过工厂方法来生成不同的对象。
csharppublic interface Product { void operation(); } public class ConcreteProduct implements Product { @Override public void operation() { System.out.println("Product Operation"); } } public abstract class Creator { public abstract Product createProduct(); } public class ConcreteCreator extends Creator { @Override public Product createProduct() { return new ConcreteProduct(); } }
3. 抽象工厂模式(Abstract Factory Pattern)
-
目的:提供一个接口用于创建相关或依赖的对象,而无需指定具体类。
-
应用场景:需要创建一系列相关对象时。
-
实现:提供多个工厂类,创建一系列相关产品。
csharppublic interface AbstractFactory { ProductA createProductA(); ProductB createProductB(); } public class ConcreteFactory1 implements AbstractFactory { @Override public ProductA createProductA() { return new ConcreteProductA1(); } @Override public ProductB createProductB() { return new ConcreteProductB1(); } }
4. 建造者模式(Builder Pattern)
-
目的:使用多个简单的对象一步步构建一个复杂的对象。
-
应用场景:当需要构建一个复杂的对象且其构建过程步骤复杂时。
-
实现:通过建造者类封装对象的创建过程。
typescriptpublic class Product { private String part1; private String part2; public void setPart1(String part1) { this.part1 = part1; } public void setPart2(String part2) { this.part2 = part2; } } public class Builder { private Product product = new Product(); public Builder buildPart1() { product.setPart1("Part1"); return this; } public Builder buildPart2() { product.setPart2("Part2"); return this; } public Product build() { return product; } }
5. 原型模式(Prototype Pattern)
-
目的:通过复制现有的实例来创建新对象,而不是通过构造函数创建。
-
应用场景:当对象的创建代价较大,或者不希望重复构建相同的对象时。
-
实现:通过克隆现有对象来创建新对象。
kotlinpublic class Prototype implements Cloneable { @Override public Prototype clone() { try { return (Prototype) super.clone(); } catch (CloneNotSupportedException e) { return null; } } }
2.2 结构型模式(Structural Patterns)
这些模式主要关注如何通过组合类和对象来形成更大的结构。
6. 适配器模式(Adapter Pattern)
-
目的:将一个类的接口转换成客户端所期望的另一个接口。
-
应用场景:当接口不兼容但需要合作时。
-
实现:通过适配器类来转换接口。
csharppublic interface Target { void request(); } public class Adaptee { public void specificRequest() { System.out.println("Specific request"); } } public class Adapter implements Target { private Adaptee adaptee; public Adapter(Adaptee adaptee) { this.adaptee = adaptee; } @Override public void request() { adaptee.specificRequest(); } }
7. 桥接模式(Bridge Pattern)
-
目的:将抽象部分与实现部分分离,使它们都可以独立地变化。
-
应用场景:当不希望在继承中增加大量的子类时。
-
实现:通过桥接接口和实现类来分离抽象和实现。
csharppublic interface Implementor { void operationImpl(); } public class ConcreteImplementorA implements Implementor { @Override public void operationImpl() { System.out.println("ConcreteImplementorA operation"); } } public abstract class Abstraction { protected Implementor implementor; public Abstraction(Implementor implementor) { this.implementor = implementor; } public abstract void operation(); } public class RefinedAbstraction extends Abstraction { public RefinedAbstraction(Implementor implementor) { super(implementor); } @Override public void operation() { implementor.operationImpl(); } }
8. 组合模式(Composite Pattern)
-
目的:将对象组合成树形结构以表示"部分-整体"的层次结构。
-
应用场景:当需要处理部分和整体对象的层次结构时。
-
实现:通过递归结构组合对象。
typescriptpublic interface Component { void operation(); } public class Leaf implements Component { @Override public void operation() { System.out.println("Leaf operation"); } } public class Composite implements Component { private List<Component> children = new ArrayList<>(); public void add(Component component) { children.add(component); } @Override public void operation() { for (Component child : children) { child.operation(); } } }
9. 装饰者模式(Decorator Pattern)
-
目的:动态地给一个对象添加一些额外的职责(功能)。
-
应用场景:需要动态添加功能,避免过多的子类继承。
-
实现:通过装饰类封装原对象,增强其功能。
csharppublic interface Component { void operation(); } public class ConcreteComponent implements Component { @Override public void operation() { System.out.println("Concrete Component operation"); } } public class Decorator implements Component { private Component component; public Decorator(Component component) { this.component = component; } @Override public void operation() { component.operation(); System.out.println("Decorator added functionality"); } }
10. 外观模式(Facade Pattern)
-
目的:为复杂的子系统提供一个统一的接口,简化客户端的调用。
-
应用场景:当需要简化接口调用时。
-
实现:通过外观类提供统一接口,隐藏复杂子系统。
csharppublic class SubSystemA { public void operationA() { System.out.println("Subsystem A operation"); } } public class SubSystemB { public void operationB() { System.out.println("Subsystem B operation"); } } public class Facade { private SubSystemA systemA = new SubSystemA(); private SubSystemB systemB = new SubSystemB(); public void operation() { systemA.operationA(); systemB.operationB(); } }
11. 享元模式(Flyweight Pattern)
-
目的:通过共享对象来减少内存使用,尤其是当对象的数量非常庞大时。
-
应用场景:大量相似对象的场景,如文本编辑器中的字符对象。
-
实现:通过共享相同的内部状态来节省内存。
typescriptpublic interface Flyweight { void operation(); } public class ConcreteFlyweight implements Flyweight { private String intrinsicState; public ConcreteFlyweight(String intrinsicState) { this.intrinsicState = intrinsicState; } @Override public void operation() { System.out.println("Intrinsic state: " + intrinsicState); } } public class FlyweightFactory { private Map<String, Flyweight> flyweights = new HashMap<>(); public Flyweight getFlyweight(String intrinsicState) { if (!flyweights.containsKey(intrinsicState)) { flyweights.put(intrinsicState, new ConcreteFlyweight(intrinsicState)); } return flyweights.get(intrinsicState); } }
12. 代理模式(Proxy Pattern)
-
目的:为其他对象提供代理,以控制对该对象的访问。
-
应用场景:远程代理、虚拟代理、安全代理等。
-
实现:通过代理类控制对真实对象的访问。
typescriptpublic interface RealSubject { void request(); } public class RealSubjectImpl implements RealSubject { @Override public void request() { System.out.println("RealSubject request"); } } public class Proxy implements RealSubject { private RealSubjectImpl realSubject; @Override public void request() { if (realSubject == null) { realSubject = new RealSubjectImpl(); } realSubject.request(); } }
2.3 行为型模式(Behavioral Patterns)
这些模式主要关注对象之间的通信和交互方式。
13. 责任链模式(Chain of Responsibility Pattern)
-
目的:避免请求发送者与接收者之间的耦合,使多个对象都有机会处理这个请求。
-
应用场景:请求处理链,如审批流程。
-
实现:通过链式结构将请求传递给多个处理者。
javapublic abstract class Handler { protected Handler next; public void setNext(Handler next) { this.next = next; } public abstract void handleRequest(int request); } public class ConcreteHandler1 extends Handler { @Override public void handleRequest(int request) { if (request < 10) { System.out.println("Handler1 handles the request"); } else if (next != null) { next.handleRequest(request); } } }
14. 命令模式(Command Pattern)
-
目的:将请求封装成一个对象,使得请求的发送者和接收者解耦。
-
应用场景:需要把操作封装成对象,或者实现撤销操作。
-
实现:将请求封装为命令对象,并通过接收者对象执行。
csharppublic interface Command { void execute(); } public class ConcreteCommand implements Command { private Receiver receiver; public ConcreteCommand(Receiver receiver) { this.receiver = receiver; } @Override public void execute() { receiver.action(); } } public class Receiver { public void action() { System.out.println("Receiver action executed"); } } public class Invoker { private Command command; public void setCommand(Command command) { this.command = command; } public void invoke() { command.execute(); } }
15. 解释器模式(Interpreter Pattern)
-
目的:为特定的语言定义文法规则,并通过解释执行这些规则。
-
应用场景:需要处理某种语言或表达式的解释问题,如正则表达式引擎。
-
实现:定义文法规则并创建解释器类来解释和执行。
kotlinpublic interface Expression { boolean interpret(String context); } public class TerminalExpression implements Expression { private String data; public TerminalExpression(String data) { this.data = data; } @Override public boolean interpret(String context) { return context.contains(data); } }
16. 迭代器模式(Iterator Pattern)
-
目的:提供一种方法顺序访问集合对象中的元素,而不暴露集合对象的内部表示。
-
应用场景:需要遍历集合元素时。
-
实现:通过迭代器类来访问集合中的元素。
typescriptpublic interface Iterator { boolean hasNext(); Object next(); } public class ConcreteIterator implements Iterator { private List<Object> list; private int position = 0; public ConcreteIterator(List<Object> list) { this.list = list; } @Override public boolean hasNext() { return position < list.size(); } @Override public Object next() { return hasNext() ? list.get(position++) : null; } }
17. 中介者模式(Mediator Pattern)
-
目的:通过一个中介者对象来协调各个对象之间的交互,而不是直接通信。
-
应用场景:当多个类之间有复杂的交互时。
-
实现:通过一个中介者类来管理和协调不同对象之间的通信。
typescriptpublic class Mediator { private Colleague colleague1; private Colleague colleague2; public void setColleague1(Colleague colleague1) { this.colleague1 = colleague1; } public void setColleague2(Colleague colleague2) { this.colleague2 = colleague2; } public void communicate(String message) { // Mediates communication System.out.println("Mediator: " + message); } }
18. 备忘录模式(Memento Pattern)
-
目的:在不暴露对象实现细节的情况下,捕获对象的内部状态并在需要时恢复该状态。
-
应用场景:需要保存和恢复对象的状态,如撤销操作。
-
实现:通过备忘录类来保存对象的状态。
typescriptpublic class Memento { private String state; public Memento(String state) { this.state = state; } public String getState() { return state; } } public class Originator { private String state; public void setState(String state) { this.state = state; } public Memento saveState() { return new Memento(state); } public void restoreState(Memento memento) { this.state = memento.getState(); } }
19. 观察者模式(Observer Pattern)
-
目的:定义对象间的一对多依赖,当一个对象改变状态时,所有依赖它的对象都会得到通知并自动更新。
-
应用场景:事件处理和监听器,如UI更新、订阅推送。
-
实现:通过主题(Subject)和观察者(Observer)类来管理通知。
typescriptpublic interface Observer { void update(String message); } public class ConcreteObserver implements Observer { @Override public void update(String message) { System.out.println("Received message: " + message); } } public class Subject { private List<Observer> observers = new ArrayList<>(); public void addObserver(Observer observer) { observers.add(observer); } public void notifyObservers(String message) { for (Observer observer : observers) { observer.update(message); } } }
20. 状态模式(State Pattern)
-
目的:允许对象在其内部状态改变时改变其行为。
-
应用场景:状态转换系统,状态变化影响对象行为的场景。
-
实现:通过状态类和上下文类来管理状态转换。
csharppublic interface State { void handle(); } public class ConcreteStateA implements State { @Override public void handle() { System.out.println("Handle in State A"); } } public class Context { private State state; public void setState(State state) { this.state = state; } public void request() { state.handle(); } }
21. 策略模式(Strategy Pattern)
-
目的:定义一系列算法,将每个算法封装起来,并使它们可以互换。
-
应用场景:需要多种行为或算法的应用场景,如排序、支付等。
-
实现:通过策略接口和具体策略类来提供不同的行为。
csharppublic interface Strategy { void execute(); } public class ConcreteStrategyA implements Strategy { @Override public void execute() { System.out.println("Executing Strategy A"); } } public class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void executeStrategy() { strategy.execute(); } }
22. 模板方法模式(Template Method Pattern)
-
目的:定义一个算法的骨架,并允许子类在不改变算法结构的情况下重定义算法的某些步骤。
-
应用场景:算法结构不变,但某些步骤可能变化时。
-
实现:通过模板方法和抽象方法将可变部分交给子类实现。
javapublic abstract class AbstractClass { public void templateMethod() { step1(); step2(); } protected abstract void step1
23. 访问者模式(Visitor Pattern)
- 目的:访问者模式允许你在不改变元素类的前提下,定义作用于这些元素的新操作。通过访问者模式,你可以将新的操作添加到现有的对象结构中,而无需修改这些对象。。
- 应用场景:当你需要对一组对象进行不同的操作,并且不希望修改这些对象的代码。需要对一个对象结构中的元素进行各种操作时,操作较多并且需要分开实现时,使用访问者模式更加灵活。
- 实现 :
-
元素接口(Element) :这是所有被访问元素的接口,通常定义一个
accept
方法,接受访问者对象。 -
具体元素(ConcreteElement) :实现元素接口,表示对象结构中的元素。
-
访问者接口(Visitor) :定义每个访问者的
visit
方法,这些方法用于访问不同类型的元素。 -
具体访问者(ConcreteVisitor) :实现访问者接口,定义对每个具体元素执行的操作。
-
java
// 1. 定义元素接口
public interface Item {
void accept(Visitor visitor);
}
// 2. 具体元素:书籍
public class Book implements Item {
private double price;
public Book(double price) {
this.price = price;
}
public double getPrice() {
return price;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
// 3. 具体元素:CD
public class CD implements Item {
private double price;
public CD(double price) {
this.price = price;
}
public double getPrice() {
return price;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
// 4. 定义访问者接口
public interface Visitor {
void visit(Book book);
void visit(CD cd);
}
// 5. 具体访问者:用于计算折扣
public class DiscountVisitor implements Visitor {
@Override
public void visit(Book book) {
double discountPrice = book.getPrice() * 0.9; // 10%折扣
System.out.println("Discounted price of book: " + discountPrice);
}
@Override
public void visit(CD cd) {
double discountPrice = cd.getPrice() * 0.85; // 15%折扣
System.out.println("Discounted price of CD: " + discountPrice);
}
}
// 6. 使用访问者模式
public class Main {
public static void main(String[] args) {
Item book = new Book(100);
Item cd = new CD(50);
Visitor discountVisitor = new DiscountVisitor();
book.accept(discountVisitor);
cd.accept(discountVisitor);
}
}
3. 总结
-
创建型模式主要关注对象的创建方式,减少系统对具体类的依赖。
-
结构型模式关注类和对象的组织结构,帮助提高代码复用性和系统的灵活性。
-
行为型模式关注对象之间的行为交互和职责分配,提供灵活的通信机制。