Skip to content

Latest commit

 

History

History
508 lines (431 loc) · 12.2 KB

2024-09-02-设计模式.md

File metadata and controls

508 lines (431 loc) · 12.2 KB
layout title date categories tags comments mathjax copyrights draft
post
设计模式
2024-09-02 17:00:00 +0800
杂项
pattern
true
true
原创
true

设计模式是软件设计中常用的解决方案,旨在提高代码的可维护性、可扩展性和可重用性。它们提供了一种通用的语言,使开发人员能够更好地沟通和协作。

设计模式通常分为三大类:

  • 创建型模式:关注对象的创建过程,提供了创建对象的灵活性和可扩展性。
  • 结构型模式:关注对象之间的关系,帮助我们更好地组织和管理代码。
  • 行为型模式:关注对象之间的交互和职责分配,帮助我们更好地管理对象之间的协作。

创建型模式

创建型模式主要关注对象的创建过程,提供了创建对象的灵活性和可扩展性。常见的创建型模式包括:

工厂方法

工厂方法(Factory Method)在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型。

工厂方法主要包含以下几个角色:

  • 产品(Product):定义产品的接口。
  • 具体产品(ConcreteProduct):实现产品接口的具体类。
  • 创建者(Creator):定义一个工厂方法,用于创建产品对象。
  • 具体创建者(ConcreteCreator):实现工厂方法以返回具体产品的实例。
classDiagram
class Creator {
    +someOperation()
    +createProduct() Product
}
note for Creator "someOperation() {
  Product product = createProduct();
  product.doStuff();
}"
class ConcreteCreatorA {
    +createProduct() Product
}
note for ConcreteCreatorA "Product createProduct() {
  return new ConcreteProductA();
}"
class ConcreteCreatorB {
    +createProduct() Product
}
note for ConcreteCreatorB "Product createProduct() {
  return new ConcreteProductB();
}"
class Product {
    <<interface>>
    +doStuff()
}
class ConcreteProductA {
    +doStuff()
}
class ConcreteProductB {
    +doStuff()
}
ConcreteCreatorA --|> Creator
ConcreteCreatorB --|> Creator
ConcreteProductA ..|> Product
ConcreteProductB ..|> Product
Creator ..> Product
Loading

例如:

  • 产品:按钮
  • 具体产品:Windows 按钮、Linux 按钮
  • 创建者:会话框
  • 具体创建者:Windows 会话框、Linux 会话框
// 产品

public interface Product {
    void doStuff();
}

public class ConcreteProductA implements Product {
    @Override
    public void doStuff() {
        // 实现 A 的操作
    }
}

public class ConcreteProductB implements Product {
    @Override
    public void doStuff() {
        // 实现 B 的操作
    }
}

// 工厂

public abstract class Factory {
    public abstract Product createProduct();
    public void someOperation() {
        Product product = createProduct();
        product.doStuff();
    }
}

public class ConcreteFactoryA extends Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
}
public class ConcreteFactoryB extends Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProductB();
    }
}

// 测试

public class Test {
    public static void main(String[] args) {
        Factory factoryA = new ConcreteFactoryA();
        factoryA.someOperation();

        Factory factoryB = new ConcreteFactoryB();
        factoryB.someOperation();
    }
}

抽象工厂

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

抽象工厂主要包含以下几个角色:

  • 抽象产品(AbstractProduct):构成系列产品的一组不同但相关的产品声明接口。
  • 具体产品(ConcreteProduct):实现抽象产品接口的具体类。
  • 抽象工厂(AbstractFactory):声明创建抽象产品的接口。
  • 具体工厂(ConcreteFactory):实现抽象工厂的接口以创建具体产品。
classDiagram
class AbstractFactory {
    <<interface>>
    +createProductA() ProductA
    +createProductB() ProductB
}
class ConcreteFactory1 {
    +createProductA() ProductA
    +createProductB() ProductB
}
note for ConcreteFactory1 "ProductA createProductA() {
&emsp;&emsp;return new ConcreteProductA1();
}"
note for ConcreteFactory1 "ProductB createProductB() {
&emsp;&emsp;return new ConcreteProductB1();
}"
class ConcreteFactory2 {
    +createProductA() ProductA
    +createProductB() ProductB
}
note for ConcreteFactory2 "ProductA createProductA() {
&emsp;&emsp;return new ConcreteProductA2();
}"
note for ConcreteFactory2 "ProductB createProductB() {
&emsp;&emsp;return new ConcreteProductB2();
}"
ConcreteFactory1 ..|> AbstractFactory
ConcreteFactory2 ..|> AbstractFactory
ConcreteProductA1 --|> AbstractProductA
ConcreteProductA2 --|> AbstractProductA
ConcreteProductB1 --|> AbstractProductB
ConcreteProductB2 --|> AbstractProductB
ConcreteFactory1 ..> ConcreteProductA1
ConcreteFactory1 ..> ConcreteProductB1
ConcreteFactory2 ..> ConcreteProductA2
ConcreteFactory2 ..> ConcreteProductB2
Loading

例如:

  • 产品:按钮、文本框
  • 具体产品:Windows 按钮、Linux 按钮、Windows 文本框、Linux 文本框
  • 抽象工厂:GUI 工厂
  • 具体工厂:Windows 工厂、Linux 工厂
// 产品

public interface ProductA {
    void someOperationA();
}

public interface ProductB {
    void someOperationB();
}

public class ConcreteProductA1 implements ProductA {
    @Override
    public void someOperationA() {
        // 实现 A1 的操作
    }
}

public class ConcreteProductA2 implements ProductA {
    @Override
    public void someOperationA() {
        // 实现 A2 的操作
    }
}

public class ConcreteProductB1 implements ProductB {
    @Override
    public void someOperationB() {
        // 实现 B1 的操作
    }
}

public class ConcreteProductB2 implements ProductB {
    @Override
    public void someOperationB() {
        // 实现 B2 的操作
    }
}

// 工厂

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

public class ConcreteFactory2 implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ConcreteProductA2();
    }
    @Override
    public ProductB createProductB() {
        return new ConcreteProductB2();
    }
}

// 测试

public class Test {
    public static void main(String[] args) {
        AbstractFactory factory1 = new ConcreteFactory1();
        ProductA productA1 = factory1.createProductA();
        ProductB productB1 = factory1.createProductB();

        AbstractFactory factory2 = new ConcreteFactory2();
        ProductA productA2 = factory2.createProductA();
        ProductB productB2 = factory2.createProductB();
    }
}

单例模式

单例模式(Singleton Pattern)确保一个类只有一个实例,并提供一个全局访问点。

classDiagram
class Singleton {
    -instance Singleton
    -Singleton()
    +getInstance() Singleton
}
note for Singleton "Singleton getInstance() {
&emsp;&emsp;if (instance == null) {
&emsp;&emsp;&emsp;&emsp;instance = new Singleton();
&emsp;&emsp;}
&emsp;&emsp;return instance;
}"
Loading

例如:

与数据库连接池相关的类通常使用单例模式。

// 单例

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

// 测试

public class Test {
    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance();
    }
}

原型模式

原型模式(Prototype Pattern)通过复制现有对象来创建新对象,而不是通过实例化类。

原型模式主要包含以下几个角色:

  • 原型(Prototype):声明一个克隆自身的接口。
  • 具体原型(ConcretePrototype):实现克隆操作。
classDiagram
class Prototype {
    <<interface>>
    +clone() Prototype
}
class ConcretePrototype {
    -field1
    +ConcretePrototype(prototype: Prototype)
    +clone() Prototype
}
note for ConcretePrototype "ConcretePrototype(prototype: Prototype) {
&emsp;&emsp;this.field1 = prototype.field1;
}"
note for ConcretePrototype "clone() {
&emsp;&emsp;return new ConcretePrototype(this);
}"
class SubclassPrototype {
    -field2
    +SubclassPrototype(prototype: Prototype)
    +clone() Prototype
}
note for SubclassPrototype "SubclassPrototype(prototype: Prototype) {
&emsp;&emsp;super(prototype);
&emsp;&emsp;this.field2 = prototype.field2;
}"
note for SubclassPrototype "clone() {
&emsp;&emsp;return new SubclassPrototype();
}"
SubclassPrototype --|> ConcretePrototype
ConcretePrototype ..|> Prototype
Loading

例如:

  • 原型:图形
  • 具体原型:圆形、矩形
  • 子类原型:椭圆形、正方形
// 原型

public interface Prototype {
    Prototype clone();
}

// 具体原型

public class ConcretePrototype implements Prototype {
    private String field1;

    public ConcretePrototype(ConcretePrototype prototype) {
        this.field1 = prototype.field1;
    }

    @Override
    public Prototype clone() {
        return new ConcretePrototype(this);
    }
}

public class SubclassPrototype extends ConcretePrototype {
    private String field2;

    public SubclassPrototype(SubclassPrototype prototype) {
        super(prototype);
        this.field2 = prototype.field2;
    }

    @Override
    public Prototype clone() {
        return new SubclassPrototype(this);
    }
}

// 测试

public class Test {
    public static void main(String[] args) {
        ConcretePrototype prototype = new ConcretePrototype();
        ConcretePrototype clone = (ConcretePrototype) prototype.clone();
    }
}

生成器模式

生成器模式(Builder Pattern)将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

生成器模式主要包含以下几个角色:

  • 生成器(Builder):定义创建一个产品对象的抽象接口。
  • 具体生成器(ConcreteBuilder):实现 Builder 接口以构建和装配该产品的各个部件。
  • 产品(Product):表示被构建的复杂对象。
  • 主管(Director):构建一个使用 Builder 接口的对象。
classDiagram
class Builder {
    <<interface>>
    +reset()
    +buildStepA()
    +buildStepB()
    +buildStepC()
}
class ConcreteBuilder1 {
    -result Product1
    +reset()
    +buildStepA()
    +buildStepB()
    +buildStepC()
    +getResult() Product1
}
note for ConcreteBuilder1 "reset() {
&emsp;&emsp;result = new Product1();
}"
note for ConcreteBuilder1 "buildStepA() {
&emsp;&emsp;result.setFeatureA();
}"
note for ConcreteBuilder1 "buildStepB() {
&emsp;&emsp;result.setFeatureB();
}"
note for ConcreteBuilder1 "buildStepC() {
&emsp;&emsp;result.setFeatureC();
}"
note for ConcreteBuilder1 "getResult() {
&emsp;&emsp;return this.result;
}"
class ConcreteBuilder2 {
    -result Product2
    +reset()
    +buildStepA()
    +buildStepB()
    +buildStepC()
    +getResult() Product2
}
note for ConcreteBuilder2 "reset() {
&emsp;&emsp;result = new Product2();
}"
note for ConcreteBuilder2 "buildStepA() {
&emsp;&emsp;result.setFeatureA();
}"
note for ConcreteBuilder2 "buildStepB() {
&emsp;&emsp;result.setFeatureB();
}"
note for ConcreteBuilder2 "buildStepC() {
&emsp;&emsp;result.setFeatureC();
}"
note for ConcreteBuilder2 "getResult() {
&emsp;&emsp;return this.result;
}"
class Director {
    -builder Builder
    +Director(Builder builder)
    +changeBuilder(Builder builder)
    +make(type: String) Product
}
note for Director "make(type: String) {
&emsp;&emsp;builder.reset();
&emsp;&emsp;if (type == 'type1') {
&emsp;&emsp;&emsp;&emsp;builder.buildStepA();
&emsp;&emsp;&emsp;&emsp;builder.buildStepB();
&emsp;&emsp;} else {
&emsp;&emsp;&emsp;&emsp;builder.buildStepA();
&emsp;&emsp;&emsp;&emsp;builder.buildStepC();
&emsp;&emsp;}
}"
ConcreteBuilder1 ..|> Builder
ConcreteBuilder2 ..|> Builder
ConcreteBuilder1 --> Product1
ConcreteBuilder2 --> Product2
Director --> Builder
Loading