一、设计模式分类

设计模式是软件设计中常见问题的典型解决方案,它们可以提高代码的可重用性、可扩展性和可维护性。设计模式大体上分为三类:

1. 创建型模式:关注对象创建机制,包括工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

2. 结构型模式:关注类和对象的组合方式,包括适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

3. 行为型模式:关注对象间的通信和职责分配,包括策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

二、设计模式详解

A. 创建型模式

创建型模式主要解决对象创建的问题,将对象的创建与使用分离,使系统更加灵活。

1. 工厂模式

工厂模式分为两种:简单工厂模式和工厂方法模式。

1.1 简单工厂模式

简单工厂模式通过一个工厂类来创建不同类型的对象。当需要新增产品时,必须修改工厂类的代码。

public class SimpleFactory {

    public Product createProduct(String type) {

        if ("A".equals(type)) {

            return new ProductA();

        } else if ("B".equals(type)) {

            return new ProductB();

        }

        return null;

    }

}

缺点:必须修改原代码,增加维护困难。

1.2 工厂方法模式

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类的实例化推迟到子类。

public interface Factory {

    Product createProduct();

}

public class FactoryA implements Factory {

    @Override

    public Product createProduct() {

        return new ProductA();

    }

}

public class FactoryB implements Factory {

    @Override

    public Product createProduct() {

        return new ProductB();

    }

}

缺点:必须实现父类方法,注重如何实现业务。

2. 抽象工厂模式

抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

public interface AbstractFactory {

    ProductA createProductA();

    ProductB createProductB();

}

public class ConcreteFactory1 implements AbstractFactory {

    @Override

    public ProductA createProductA() {

        return new ProductA1();

    }

    

    @Override

    public ProductB createProductB() {

        return new ProductB1();

    }

}

优点:可以快速定义参数方法,更好支持拓展方法。

3. 单例模式

确保一个类最多只有一个实例,并提供一个全局访问点。

3.1 预加载
public class Singleton {

    private static Singleton instance = new Singleton();

    

    private Singleton() {}

    

    public static Singleton getInstance() {

        return instance;

    }

}

缺点:没有使用该对象时,会造成内存的浪费。

3.2 懒加载
`

线程安全问题:普通懒加载无法保证线程安全。

3.3 线程安全的懒加载
public class Singleton {

    private static volatile Singleton instance = null;

    

    private Singleton() {}

    

    public static Singleton getInstance() {

        if (instance == null) {

            synchronized (Singleton.class) {

                if (instance == null) {

                    instance = new Singleton();

                }

            }

        }

        return instance;

    }

}

使用双重检查锁定和volatile关键字确保线程安全。

4. 建造者模式

封装一个复杂对象构造过程,并允许按步骤构造。

public class Computer {

    private String cpu;

    private String ram;

    // 其他组件...

    

    // 构造方法和getter/setter

}

public interface ComputerBuilder {

    void buildCpu();

    void buildRam();

    Computer getComputer();

}

public class Director {

    private ComputerBuilder builder;

    

    public Director(ComputerBuilder builder) {

        this.builder = builder;

    }

    

    public Computer construct() {

        builder.buildCpu();

        builder.buildRam();

        return builder.getComputer();

    }

}

优点:可以控制对象的创建过程,将构造与表示分离。

缺点:会增加类的数量,管理复杂度提高。

5. 原型模式

通过复制现有的实例创建新的实例,无需知道类的具体信息。

public class Prototype implements Cloneable {

    private String property;

    

    @Override

    public Prototype clone() {

        try {

            return (Prototype) super.clone();

        } catch (CloneNotSupportedException e) {

            return null;

        }

    }

}
5.1 深拷贝与浅拷贝
  • 浅拷贝:基本类型重新创建,引用类型指向原对象

  • 深拷贝:所有类型都重新创建

应用场景:需要创建大量相似对象时,使用原型模式可以提高性能。

B. 结构型模式

结构型模式关注类和对象的组合方式,形成更大的结构。

6. 适配器模式

将某个类的接口转换成客户端期望的另一个接口表示。

6.1 类适配器

通过继承实现适配:

public class Adaptee {

    public void specificRequest() {

        System.out.println("特殊请求");

    }

}

public interface Target {

    void request();

}

public class Adapter extends Adaptee implements Target {

    @Override

    public void request() {

        specificRequest();

    }

}

6.2 对象适配器

通过组合实现适配:

public class Adapter implements Target {

    private Adaptee adaptee;

    

    public Adapter(Adaptee adaptee) {

        this.adaptee = adaptee;

    }

    

    @Override

    public void request() {

        adaptee.specificRequest();

    }

}

6.3 接口适配器

为接口提供默认实现:

public interface Target {

    void request1();

    void request2();

    void request3();

}

public abstract class Adapter implements Target {

    public void request1() {}

    public void request2() {}

    public void request3() {}

}

7. 装饰器模式

动态地给一个对象添加一些额外的职责。

public interface Component {

    void operation();

}

public class ConcreteComponent implements Component {

    @Override

    public void operation() {

        System.out.println("基本操作");

    }

}

public abstract class Decorator implements Component {

    protected Component component;

    

    public Decorator(Component component) {

        this.component = component;

    }

    

    @Override

    public void operation() {

        component.operation();

    }

}

public class ConcreteDecoratorA extends Decorator {

    public ConcreteDecoratorA(Component component) {

        super(component);

    }

    

    @Override

    public void operation() {

        super.operation();

        addedBehavior();

    }

    

    private void addedBehavior() {

        System.out.println("添加的行为A");

    }

}

8. 代理模式

为其他对象提供一种代理以控制对这个对象的访问。

public interface Subject {

    void request();

}

public class RealSubject implements Subject {

    @Override

    public void request() {

        System.out.println("真实请求");

    }

}

public class Proxy implements Subject {

    private RealSubject realSubject;

    

    @Override

    public void request() {

        if (realSubject == null) {

            realSubject = new RealSubject();

        }

        preRequest();

        realSubject.request();

        postRequest();

    }

    

    private void preRequest() {

        System.out.println("预处理");

    }

    

    private void postRequest() {

        System.out.println("后处理");

    }

}

9. 外观模式

为子系统中的一组接口提供一个一致的界面。

public class SubSystemA {

    public void operationA() {

        System.out.println("子系统A操作");

    }

}

public class SubSystemB {

    public void operationB() {

        System.out.println("子系统B操作");

    }

}

public class Facade {

    private SubSystemA a;

    private SubSystemB b;

    

    public Facade() {

        a = new SubSystemA();

        b = new SubSystemB();

    }

    

    public void operation() {

        a.operationA();

        b.operationB();

    }

}

10. 桥接模式

将抽象部分与它的实现部分分离,使它们都可以独立地变化。

public interface Implementor {

    void operationImpl();

}

public class ConcreteImplementorA implements Implementor {

    @Override

    public void operationImpl() {

        System.out.println("具体实现A");

    }

}

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();

    }

}

11. 组合模式

将对象组合成树形结构以表示"部分-整体"的层次结构。

public abstract class Component {

    protected String name;

    

    public Component(String name) {

        this.name = name;

    }

    

    public abstract void add(Component c);

    public abstract void remove(Component c);

    public abstract void display(int depth);

}

public class Leaf extends Component {

    public Leaf(String name) {

        super(name);

    }

    

    @Override

    public void add(Component c) {

        throw new UnsupportedOperationException();

    }

    

    @Override

    public void remove(Component c) {

        throw new UnsupportedOperationException();

    }

    

    @Override

    public void display(int depth) {

        System.out.println("-".repeat(depth) + name);

    }

}

public class Composite extends Component {

    private List<Component> children = new ArrayList<>();

    

    public Composite(String name) {

        super(name);

    }

    

    @Override

    public void add(Component c) {

        children.add(c);

    }

    

    @Override

    public void remove(Component c) {

        children.remove(c);

    }

    

    @Override

    public void display(int depth) {

        System.out.println("-".repeat(depth) + name);

        for (Component c : children) {

            c.display(depth + 2);

        }

    }

}

12. 享元模式

运用共享技术有效地支持大量细粒度的对象。

public interface Flyweight {
    void operation(String extrinsicState);
}

public class ConcreteFlyweight implements Flyweight {
    private String intrinsicState;
    
    public ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }
    
    @Override
    public void operation(String extrinsicState) {
        System.out.println("内部状态: " + intrinsicState);
        System.out.println("外部状态: " + 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);
    }
}

三、总结

设计模式是软件开发中经过验证的解决方案,它们可以帮助我们解决常见的设计问题。本文详细介绍了创建型和结构型设计模式:

  • 创建型模式:关注对象的创建过程,包括工厂模式、抽象工厂、单例模式、建造者模式和原型模式。

  • 结构型模式:关注类和对象的组合方式,包括适配器、装饰器、代理、外观、桥接、组合和享元模式。