23种设计模式被分为三大类:创建型模式、结构型模式、行为型模式
创建型 | 结构型 | 行为型 |
---|---|---|
单例模式 | 适配器模式 | 观察者模式 |
工厂方法模式 | 装饰器模式 | 模板方法模式 |
抽象工厂模式 | 代理模式 | 策略模式 |
建造者模式 | 外观模式 | 命令模式 |
原型模式 | 桥接模式 | 职责链模式 |
- | 组合模式 | 状态模式 |
- | 享元模式 | 访问者模式 |
七大原则:
单例模式(Singleton Pattern)是一种常用的软件设计模式,它保证一个类只有一个实例,并提供了一个全局访问点。分为饿汉式和懒汉式,饿汉式是直接初始化类对象,而懒汉式是需要使用到对象再初始化
以下是单例模式的示例代码:
javapublic class Singleton {
private static Singleton instance;
private Singleton() {
// 私有构造函数,防止其他类从外部创建实例
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
在这个示例中,Singleton 类是一个单例类,它只有一个实例。通过 getInstance() 方法获取单例实例。如果实例不存在,则创建一个新的实例。
单例模式在软件开发中有很多用途。以下是一些常见的应用场景:
数据库连接池:在一个系统中,数据库连接池的实例只需要一个,通过单例模式可以确保每个线程都使用相同的数据库连接池。
日志记录器:日志记录器通常只需要一个实例,通过单例模式可以确保所有的日志信息都写入同一个日志文件中。
配置管理器:在一个系统中,配置管理器只需要一个实例,通过单例模式可以确保所有的配置信息都来自于同一个实例。
线程池:在一个系统中,线程池只需要一个实例,通过单例模式可以确保所有的任务都分配到同一个线程池中执行。
需要注意的是,单例模式并不是适用于所有的场景。在多线程环境下,需要考虑到线程安全问题,可以使用线程安全的单例实现方式。同时,在某些情况下,可能需要根据不同的需求创建多个实例,因此需要根据具体的需求来决定是否使用单例模式。
工厂方法模式(Factory Method Pattern)是一种常用的类创建型设计模式,它提供了一种创建对象的接口,让子类决定实例化哪个类。
工厂方法模式的核心是将创建对象的代码从客户端代码中分离出来,通过一个工厂方法来创建对象。具体工厂类可以根据需要来决定实例化哪个具体产品类。
以下是工厂方法模式的示例代码:
javapublic interface Product {
void doSomething();
}
public class ConcreteProduct1 implements Product {
@Override
public void doSomething() {
System.out.println("ConcreteProduct1 doSomething");
}
}
public class ConcreteProduct2 implements Product {
@Override
public void doSomething() {
System.out.println("ConcreteProduct2 doSomething");
}
}
public class Factory {
public Product createProduct() {
// 根据需要选择具体的具体工厂类,并实例化具体产品类
if (/* 某些条件 */) {
return new ConcreteProduct1();
} else {
return new ConcreteProduct2();
}
}
}
在这个示例中,Product 接口定义了产品的行为,ConcreteProduct1 和 ConcreteProduct2 都是具体的产品类。Factory 类是一个抽象工厂类,它提供了一个工厂方法 createProduct(),用于创建产品对象。具体工厂类可以根据需要来选择实例化哪个具体产品类。
工厂方法模式的应用场景很多,例如:
数据库访问:在一个系统中,数据库访问可以通过工厂方法模式来实现。具体的数据库连接池可以通过工厂方法模式来创建,这样可以根据需要来选择使用不同的数据库连接池。
配置管理:在一个系统中,配置管理可以通过工厂方法模式来实现。具体的配置管理器可以通过工厂方法模式来创建,这样可以根据需要来选择使用不同的配置管理器。
插件系统:在一个系统中,插件系统可以通过工厂方法模式来实现。具体的插件可以通过工厂方法模式来创建,这样可以根据需要来选择使用不同的插件。
工厂方法模式的核心思想是将对象的创建和使用分离开来,达到解耦的目的。具体工厂类可以根据需要来选择实例化哪个具体产品类,这样可以使系统更加灵活和可扩展。同时,工厂方法模式也可以通过依赖注入等方式来实现,使得系统更加可维护和可复用。
抽象工厂模式(Abstract Factory Pattern)是一种工厂模式的扩展,它提供了一个工厂接口,用于创建一系列相关或相互依赖的对象。
抽象工厂模式的核心是将多个产品系列的创建过程封装起来,使得客户端可以不必关心具体的对象创建。
以下是抽象工厂模式的示例代码:
javapublic interface AbstractFactory {
public ProductA createProductA();
public ProductB createProductB();
}
public class ConcreteFactory1 implements AbstractFactory {
public ProductA createProductA() {
return new ConcreteProductA1();
}
public ProductB createProductB() {
return new ConcreteProductB1();
}
}
public class ConcreteFactory2 implements AbstractFactory {
public ProductA createProductA() {
return new ConcreteProductA2();
}
public ProductB createProductB() {
return new ConcreteProductB2();
}
}
建造者模式(Builder Pattern)是一种对象构建模式,它将复杂对象的构建过程抽象出来,使得客户端可以通过指定复杂对象的类型和内容来构建对象,而不需要了解内部的具体构建细节。
建造者模式将一个复杂对象的构建过程分成了几个步骤,通过一个建造者对象来管理每个步骤。客户端只需要通过调用建造者对象的方法来逐步构建对象,而不需要直接操作对象的内部细节。
以下是建造者模式的示例代码:
javapublic class Product {
private String part1;
private String part2;
private String part3;
public Product(String part1, String part2, String part3) {
this.part1 = part1;
this.part2 = part2;
this.part3 = part3;
}
}
public class Builder {
private Product product = new Product("", "", "");
public void setPart1(String part1) {
product.setPart1(part1);
}
public void setPart2(String part2) {
product.setPart2(part2);
}
public void setPart3(String part3) {
product.setPart3(part3);
}
public Product build() {
return product;
}
}
在这个示例中,Product 是一个需要构建的复杂对象,它有三个部件 part1、part2 和 part3。Builder 是一个建造者对象,它通过一系列的 setPart() 方法来逐步构建 Product 对象。客户端只需要通过调用 Builder 对象的方法来逐步构建对象,而不需要直接操作对象的内部细节。
建造者模式可以用于构建复杂的对象,特别是那些需要多个步骤来构建的对象。它将对象的构建过程封装在建造者对象中,使得客户端可以通过简单的调用方法来构建对象,而不需要了解内部的具体构建细节。同时,建造者模式还可以避免暴露对象的内部细节,提高了对象的安全性和可维护性。
原型模式(Prototype Pattern)是一种创建型设计模式,它允许一个对象通过克隆自身的状态来创建新的对象,而无需从零开始构建。
原型模式的核心是将对象的实例化过程延迟到需要时再进行,通过一个原型对象来创建新的对象,而不是通过 new 运算符来实例化对象。
以下是原型模式的示例代码:
javapublic class Prototype implements Cloneable {
private String name;
private int age;
public Prototype(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public Prototype clone() throws CloneNotSupportedException {
return (Prototype) super.clone();
}
}
适配器模式(Adapter Pattern)是一种结构型设计模式,它用于将一个类的接口转换成客户端期望的另一个接口。
适配器模式的核心是将原本不兼容的接口转换成兼容的接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
以下是适配器模式的示例代码:
javapublic interface Target {
public void request();
}
public class Adaptee {
public void specificRequest() {
System.out.println("Adaptee Specific Request");
}
}
public class Adapter extends Adaptee implements Target {
public void request() {
System.out.println("Adapter Request");
specificRequest();
}
}
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许在运行时动态地扩展一个对象的功能。
装饰器模式通过一个装饰器对象来扩展一个对象的功能,这个装饰器对象可以包含额外的责任,并将这些责任添加到原始对象上。
以下是装饰器模式的示例代码:
javapublic interface Component {
public void operation();
}
public class ConcreteComponent implements Component {
public void operation() {
System.out.println("ConcreteComponentOperation");
}
}
public class Decorator extends ConcreteComponent {
private Component component;
public Decorator(Component component) {
this.component = component;
}
public void operation() {
component.operation();
System.out.println("DecoratorOperation");
}
}
代理模式(Proxy Pattern)是一种结构型设计模式,它通过一个代理对象来控制对原始对象的访问。
代理模式将客户端的请求转发给原始对象,但是在转发之前和之后,代理对象可以执行一些额外的操作,例如在访问前检查权限,在访问后记录日志等。
以下是代理模式的示例代码:
javapublic interface Subject {
public void request();
}
public class RealSubject implements Subject {
public void request() {
System.out.println("RealSubject Request");
}
}
public class Proxy implements Subject {
private RealSubject realSubject = new RealSubject();
public void request() {
// 在访问前检查权限等操作
System.out.println("Proxy Request");
realSubject.request();
// 在访问后记录日志等操作
}
}
外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个简单的接口来访问子系统的各个模块。
外观模式将客户端的请求转发给子系统中的其他模块,它隐藏了子系统的复杂性,并提供了客户端和子系统之间的一种松耦合的接口。
以下是外观模式的示例代码:
javapublic class SubSystem {
public void operation1() {
System.out.println("SubSystem Operation 1");
}
public void operation2() {
System.out.println("SubSystem Operation 2");
}
}
public class Facade {
private SubSystem subSystem = new SubSystem();
public void operation() {
subSystem.operation1();
subSystem.operation2();
}
}
桥接模式(Bridge Pattern)是一种结构型设计模式,它允许将实现与抽象分离,从而使得它们可以独立地变化和扩展。
桥接模式通过一个抽象类来实现抽象部分,并通过一个具体类来实现具体部分。 以下是桥接模式的示例代码:
javapublic class Abstraction {
private Implementor implementor;
public void setImplementor(Implementor implementor) {
this.implementor = implementor;
}
public void request() {
implementor.specificRequest();
}
}
public interface Implementor {
public void specificRequest();
}
public class ConcreteImplementorA implements Implementor {
public void specificRequest() {
System.out.println("ConcreteImplementorA Specific Request");
}
}
public class ConcreteImplementorB implements Implementor {
public void specificRequest() {
System.out.println("ConcreteImplementorB Specific Request");
}
}
组合模式(Composite Pattern)是一种结构型设计模式,它创建了对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的层次关系。
组合模式使得用户对单个对象和组合对象的访问具有一致性,能够以一致的方式处理个别对象以及组合对象。
以下是组合模式的示例代码:
javapublic interface Component {
public void operation();
}
public class Leaf implements Component {
public void operation() {
System.out.println("Leaf Operation");
}
}
public class Composite implements Component {
private List<Component> components = new ArrayList<>();
public void add(Component component) {
components.add(component);
}
public void remove(Component component) {
components.remove(component);
}
public void operation() {
for (Component component : components) {
component.operation();
}
}
}
享元模式(Flyweight Pattern)是一种软件设计模式。它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件。通常物件中的部分状态是可以分享。
享元模式能够解决重复对象的内存浪费的问题,当系统中有大量相似对象,需要缓冲池时。不需总是创建新对象,可以从缓冲池里拿。这样可以降低系统内存,同时提高效率,常用于系统底层开发,解决系统的性能问题。
在享元模式中,我们将对象的某些状态分离出来,让多个对象共享这些状态,从而减少内存使用。同时,我们还需要定义一个享元工厂类来管理这些共享对象,并提供一个接口来获取共享对象。
以下是享元模式的示例代码:
javapublic interface Flyweight {
public void operation(int i);
}
public class ConcreteFlyweight implements Flyweight {
private String intrinsicState;
public ConcreteFlyweight(String intrinsicState) {
this.intrinsicState = intrinsicState;
}
public void operation(int extrinsicState) {
System.out.println("ConcreteFlyweight: " + intrinsicState + " " + extrinsicState);
}
}
public class FlyweightFactory {
private Map<String, Flyweight> flyweights = new HashMap<>();
public Flyweight getFlyweight(String key) {
if (!flyweights.containsKey(key)) {
flyweights.put(key, new ConcreteFlyweight(key));
}
return flyweights.get(key);
}
}
观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象状态发生改变时,它的状态会自发地通知所有观察者对象,使得他们能够自动更新自己。
观察者模式可以用于实现事件处理系统,当某个事件触发时,可以自动通知所有相关的观察者对象。
在观察者模式中,有一个主题对象和多个观察者对象,主题对象负责维护观察者对象列表,并提供一个增加和删除观察者对象的方法。当主题对象状态发生改变时,它会通知所有的观察者对象,观察者对象会根据主题对象的状态来更新自己的状态。
以下是观察者模式的示例代码:
javapublic interface Observer {
public void update(String message);
}
public interface Subject {
public void attach(Observer observer);
public void detach(Observer observer);
public void notifyObservers(String message);
}
public class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
public void attach(Observer observer) {
observers.add(observer);
}
public void detach(Observer observer) {
observers.remove(observer);
}
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
模板方法模式(Template Method Pattern)是一种行为型设计模式,它定义了一个算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模板方法模式通过一个抽象父类定义了一个算法的框架,并将一些步骤的实现延迟到子类中,使得子类可以通过重定义这些步骤来改变算法的具体实现。
以下是模板方法模式的示例代码:
javapublic abstract class TemplateMethod {
public final void doTemplateMethod() {
doStepOne();
doStepTwo();
doStepThree();
}
protected abstract void doStepOne();
protected abstract void doStepTwo();
protected abstract void doStepThree();
}
public class ConcreteTemplateMethod extends TemplateMethod {
protected void doStepOne() {
System.out.println("ConcreteTemplateMethod Step One");
}
protected void doStepTwo() {
System.out.println("ConcreteTemplateMethod Step Two");
}
protected void doStepThree() {
System.out.println("ConcreteTemplateMethod Step Three");
}
}
在这个示例中,TemplateMethod 是一个抽象父类,定义了一个算法的骨架,即 doTemplateMethod() 方法。该方法中包含了三个抽象方法 doStepOne()、doStepTwo() 和 doStepThree(),子类需要重定义这些方法以实现特定的功能。
ConcreteTemplateMethod 是一个具体的子类,它继承了 TemplateMethod 并重定义了三个抽象方法,从而实现了自定义的算法步骤。通过调用 doTemplateMethod() 方法,可以执行整个算法的流程。
策略模式(Strategy Pattern)是一种行为型设计模式,它定义一系列的算法,将每个算法封装起来,并使它们可以相互替换。
策略模式允许算法独立于使用它的客户端而变化,使得客户端可以根据需要来选择合适的算法。
以下是策略模式的示例代码:
javapublic interface Strategy {
public int doOperation(int num);
}
public class OperationAdd implements Strategy {
public int doOperation(int num) {
return num + 10;
}
}
public class OperationSubtract implements Strategy {
public int doOperation(int num) {
return num - 10;
}
}
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int num) {
return strategy.doOperation(num);
}
}
在这个示例中,Strategy 是一个接口,定义了一个 doOperation() 方法,该方法对一个整数进行特定的操作。
OperationAdd 和 OperationSubtract 是具体的策略类,它们实现了 Strategy 接口,并实现了自己的算法。
Context 是一个客户端类,它根据需要来选择合适的策略,并通过调用 executeStrategy() 方法来执行所选的策略。通过使用 Context 类,客户端可以动态地切换不同的策略。
命令模式(Command Pattern)是一种行为型设计模式,它定义了一个请求的封装,包括请求的名称和参数,以及执行请求的方法。
命令模式允许客户端将请求封装成一个对象,并通过调用该对象的相应方法来执行请求。
以下是命令模式的示例代码:
javapublic interface Command {
public void execute();
}
public class LightOnCommand implements Command {
public void execute() {
System.out.println("Light is turned on");
}
}
public class LightOffCommand implements Command {
public void execute() {
System.out.println("Light is turned off");
}
}
public class Receiver {
public void setCommand(Command command) {
this.command = command;
}
public void executeCommand() {
command.execute();
}
private Command command;
}
在这个示例中,Command 是一个接口,定义了一个 execute() 方法,用于执行请求。
LightOnCommand 和 LightOffCommand 是具体的命令类,它们实现了 Command 接口,并实现了自己的算法。
Receiver 是一个接收者类,它持有一个命令对象,并通过调用 executeCommand() 方法来执行该命令。使用 Receiver 类,客户端可以将请求的执行与具体的实现分离开来。
职责链模式(Chain of Responsibility Pattern)是一种请求处理的软件设计模式,它将多个对象连成一条链,并沿着这条链传递请求,直到有一个对象能够处理该请求为止。
职责链模式允许客户端将请求发送到链上,而无需关心请求的处理细节以及请求的传递。
以下是职责链模式的示例代码:
javapublic class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public boolean handleRequest(Request request) {
if (this instanceof && this.handle the request) {
return true;
}
if (this.successor != null) {
return this.successor.handleRequest(request);
}
return false;
}
}
在这个示例中,Handler 是一个处理者类,定义了一个 handleRequest() 方法,用于处理请求。
Handler 类中的 successor 属性表示下一个处理者对象,每个处理者对象都可以将请求传递给它的下一个处理者对象,直到有一个处理者对象能够处理该请求。
客户端可以创建一个链,将多个处理者对象连接起来,然后将请求发送到链上,由第一个处理者对象开始处理请求,如果该处理者无法处理该请求,则将请求传递给下一个处理者对象,以此类推,直到有一个处理者能够处理该请求为止。
职责链模式通常用于处理某个请求的对象不止一个的情况,例如在一个软件系统中,可以由多个处理者对象来处理同一个请求,每个处理者对象只负责处理自己职责范围内的请求。
状态模式(State Pattern)是一种结构型设计模式,它允许对象在内部状态改变时改变它的行为。
状态模式将对象的当前状态封装在一个独立的类中,使得状态的变化不会对其他对象造成影响。
以下是状态模式的示例代码:
javapublic interface State {
public void request();
}
public class ConcreteStateA implements State {
public void request() {
System.out.println("State A: " + request());
}
}
public class ConcreteStateB implements State {
public void request() {
System.out.println("State B: " + request());
}
}
public class Context {
private State state;
public void setState(State state) {
this.state = state;
}
public void request() {
state.request();
}
}
在这个示例中,State 是一个接口,定义了一个 request() 方法,用于处理请求。
ConcreteStateA 和 ConcreteStateB 是具体的状态类,它们实现了 State 接口,并实现了自己的算法。
Context 是一个对象类,它持有一个状态对象,并通过调用 request() 方法来执行该状态下的请求。使用 Context 类,客户端可以在不同的状态下执行不同的请求。
访问者模式是一种行为型设计模式,它可以在不修改已有类的情况下,为已有的数据结构增加新的功能,同时支持客户端以统一的方式操作这个数据结构的各个元素。
访问者模式的结构包含一个数据结构和一个访问者对象。数据结构包含多个元素,每个元素都实现了相同的接受访问的方法。访问者对象包含了对于数据结构的某个操作的算法,这个算法可以访问数据结构的每个元素并执行相应的操作。
以下是一个简单的Java代码示例,展示访问者模式的实现:
java// 定义抽象元素类
abstract class Element {
public abstract void accept(Visitor visitor);
}
// 定义具体元素类
class ConcreteElement1 extends Element {
@Override
public void accept(Visitor visitor) {
visitor.visitConcreteElement1();
}
}
class ConcreteElement2 extends Element {
@Override
public void accept(Visitor visitor) {
visitor.visitConcreteElement2();
}
}
本文作者:Weee
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!