设计模式 - 创建型设计模式

什么是设计模式

在日常生活中每个人都会遇到各种各样的问题, 经过归类和分析后发现, 很多问题都可以使用相同的方式方法来解决, 将这些方式方法整理就产生了设计模式. 简单说, 设计模式是解决通用问题的模板.  每个领域都有自己的设计模式, 在计算机领域设计模式主要分三大类: 

  • 创建型设计模式 - 提供创建对象的机制, 增加已有代码的灵活性和可复用性。
  • 结构型设计模式 - 如何将对象和类组装成较大的结构, 并同时保持结构的灵活和高效。
  • 行为设计模式 - 对象间的高效沟通和职责委派。

本文在主要体现创建型设计模式.

工厂方法模式

模式意图

在父类提供创建对象的方法, 允许子类决定实例化对象类型. 

模式结构

使用实例

class Pet {

    say();
}


class Dog extends Pet {


    say() {
       print("A Dog say")
    }
}

class Cat extends Pet {

    say() {

        print("A Cat say")
    }

}


class PetSaied {


    main() {

       String petType = "Dog";

       Pet pet = createPet(petType);
       Optional.isNullable(pet).say();


       String petType = "Cat";

       Pet pet = createPet(petType);
       Optional.isNullable(pet).say();

    }

    createPet(String petType) {

        Pet pet = null;
        switch(petType) {
            case "Dog":
                pet = new Dog();
                break;
            case "Cat":
                pet = new Cat();
                break;
        }

        return pet;
    }
}

适合应用场景

  • 当你在编写代码的过程中, 如果无法预知对象确切类别及其依赖关系时, 可使用工厂方法。
  • 如果你希望用户能扩展你软件库或框架的内部组件, 可使用工厂方法。
  • 如果你希望复用现有对象来节省系统资源, 而不是每次都重新创建对象, 可使用工厂方法。

Java中的使用

核心 Java 程序库中有该模式的应用:

抽象工厂模式

模式意图

抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。

模式结构

使用实例

适合应用场景

  • 如果代码需要与多个不同系列的相关产品交互, 但是由于无法提前获取相关信息, 或者出于对未来扩展性的考虑, 你不希望代码基于产品的具体类进行构建, 在这种情况下, 你可以使用抽象工厂。
  • 如果你有一个基于一组抽象方法的类, 且其主要功能因此变得不明确, 那么在这种情况下可以考虑使用抽象工厂模式。

Java中的使用

以下是来自核心 Java 程序库的一些示例:

生成器模式

模式意图

能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象。

模式结构

使用实例

适合应用场景

  • 使用生成器模式可避免 “重叠构造函数 (telescoping constructor)” 的出现。
  • 当你希望使用代码创建不同形式的产品 (例如石头或木头房屋) 时, 可使用生成器模式。
  • 使用生成器构造组合树或其他复杂对象

Java中的使用

生成器在 Java 核心程序库中得到了广泛的应用:

原型模式

模式意图

能够复制已有对象, 而又无需使代码依赖它们所属的类。

模式结构

使用实例

适合应用场景

  • 如果你需要复制一些对象, 同时又希望代码独立于这些对象所属的具体类, 可以使用原型模式。
  • 如果子类的区别仅在于其对象的初始化方式, 那么你可以使用该模式来减少子类的数量。 别人创建这些子类的目的可能是为了创建特定类型的对象。

Java中的使用

Java 的 Cloneable  (可克隆) 接口就是立即可用的原型模式。任何类都可通过实现该接口来实现可被克隆的性质。

java.lang.Object#clone() (类必须实现 java.lang.Cloneable 接口)

识别方法: 原型可以简单地通过 clone或 copy等方法来识别。

单例模式

模式意图

保证一个类只有一个实例, 并提供一个访问该实例的全局节点。

模式结构

使用实例

// 数据库类会对`getInstance(获取实例)`方法进行定义以让客户端在程序各处
// 都能访问相同的数据库连接实例。
class Database is
    // 保存单例实例的成员变量必须被声明为静态类型。
    private static field instance: Database

    // 单例的构造函数必须永远是私有类型,以防止使用`new`运算符直接调用构
    // 造方法。
    private constructor Database() is
        // 部分初始化代码(例如到数据库服务器的实际连接)。
        // ……

    // 用于控制对单例实例的访问权限的静态方法。
    public static method getInstance() is
        if (Database.instance == null) then
            acquireThreadLock() and then
                // 确保在该线程等待解锁时,其他线程没有初始化该实例。
                if (Database.instance == null) then
                    Database.instance = new Database()
        return Database.instance

    // 最后,任何单例都必须定义一些可在其实例上执行的业务逻辑。
    public method query(sql) is
        // 比如应用的所有数据库查询请求都需要通过该方法进行。因此,你可以
        // 在这里添加限流或缓冲逻辑。
        // ……

class Application is
    method main() is
        Database foo = Database.getInstance()
        foo.query("SELECT ……")
        // ……
        Database bar = Database.getInstance()
        bar.query("SELECT ……")
        // 变量 `bar` 和 `foo` 中将包含同一个对象。

适合应用场景

  • 如果程序中的某个类对于所有客户端只有一个可用的实例, 可以使用单例模式。
  • 如果你需要更加严格地控制全局变量, 可以使用单例模式。

Java中的使用

尽管如此, Java 核心程序库中仍有相当多的单例示例:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值