玩转设计模式:一文看懂创建型设计模式的差异与应用

单例模式

核心观点:保证一个类只有一个实例,并提供一个全局访问点。

在实际开发中,我们经常会遇到需要限制某个类只能有一个实例的情况,例如配置信息类、线程池类等。这种情况下,我们可以使用单例模式来实现。单例模式确保一个类只有一个实例,并提供一个全局的访问点,使得其他对象可以通过这个访问点来获取类的实例。

在实现单例模式时,可以采用懒汉式或饿汉式的方式。懒汉式是指在第一次访问实例时才进行实例化,而饿汉式则是在类加载时就创建实例。

下面是一个简单的单例模式的示例代码:

public class Singleton {
    
    
    private static Singleton instance;

    private Singleton() {
    
    
        // 私有构造方法,防止外部创建实例
    }

    public static Singleton getInstance() {
    
    
        if (instance == null) {
    
    
            // 第一次访问时才进行实例化
            instance = new Singleton();
        }
        return instance;
    }

    // 其他方法...
}

优点:

  • 保证了全局只有一个实例,节省了系统资源。
  • 提供了一个全局访问点,方便其他对象获取实例。
  • 在多线程环境下也可以保证只有一个实例。

与其他类似的模式对比:

  • 简单工厂模式和工厂模式也能够创建对象,但它们主要是用来解决对象的创建问题,而不是保证只有一个实例。
  • 抽象工厂模式可以创建一系列相关对象,但它和单例模式的目的不同,抽象工厂模式更关注的是一组对象的创建,而单例模式只需要一个实例。
  • 建造者模式也可以创建对象,但它更关注的是复杂对象的构建过程和表示,而不是保证只有一个实例。

总结:单例模式是一种常用的创建型模式,它保证了一个类只有一个实例,并提供了一个全局访问点,可以方便地获取实例。使用单例模式可以节省系统资源,但需要注意在多线程环境下的安全性。通过与其他类似模式进行对比,可以更好地理解单例模式的优点和适用场景。

工厂模式

核心观点:定义一个创建对象的接口,但由子类决定要实例化的类。

在面向对象编程中,我们经常会遇到需要创建多个具有一定共性的对象的情况,此时可以使用工厂模式来管理对象的创建。工厂模式定义了一个创建对象的接口,但具体要创建哪个类的对象由子类决定。

下面是一个简单的工厂模式的示例代码:

public interface Product {
    
    
    void show();
}

public class ProductA implements Product {
    
    
    @Override
    public void show() {
    
    
        System.out.println("This is product A.");
    }
}

public class ProductB implements Product {
    
    
    @Override
    public void show() {
    
    
        System.out.println("This is product B.");
    }
}

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

public class Client {
    
    
    public static void main(String[] args) {
    
    
        Factory factory = new FactoryA();
        Product product = factory.createProduct();
        product.show();
    }
}

优点:

  • 将对象的创建和使用分离,使用者只关心接口而不需要关心具体实现类。
  • 符合开闭原则,新增具体产品时,只需要编写对应的具体产品类和工厂类即可,不需要修改其他代码。

与其他类似的模式对比:

  • 简单工厂模式也能够创建对象,但它将对象的创建逻辑放在一个工厂类中,违反了开闭原则。
  • 单例模式保证了全局只有一个实例,不适合用来创建多个具有相同特征的对象。
  • 抽象工厂模式用于创建一系列相关对象,与工厂模式的区别在于抽象工厂模式更关注一组对象的创建。

总结:工厂模式是一种常用的创建型模式,它定义了一个创建对象的接口,但由子类决定要实例化的类。使用工厂模式可以将对象的创建和使用分离,符合开闭原则。与其他类似的模式相比,工厂模式更注重对象的创建过程,适用于需要创建多个具有一定共性的对象的情况。

抽象工厂模式

核心观点:提供一个创建一系列相关或相互依赖对象的接口。

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

下面是一个简单的抽象工厂模式的示例代码:

public interface ProductA {
    
    
    void show();
}

public class ConcreteProductA1 implements ProductA {
    
    
    @Override
    public void show() {
    
    
        System.out.println("This is concrete product A1.");
    }
}

public class ConcreteProductA2 implements ProductA {
    
    
    @Override
    public void show() {
    
    
        System.out.println("This is concrete product A2.");
    }
}

public interface ProductB {
    
    
    void show();
}

public class ConcreteProductB1 implements ProductB {
    
    
    @Override
    public void show() {
    
    
        System.out.println("This is concrete product B1.");
    }
}

public class ConcreteProductB2 implements ProductB {
    
    
    @Override
    public void show() {
    
    
        System.out.println("This is concrete product 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 Client {
    
    
    public static void main(String[] args) {
    
    
        AbstractFactory factory1 = new ConcreteFactory1();
        ProductA productA1 = factory1.createProductA();
        ProductB productB1 = factory1.createProductB();
        productA1.show();
        productB1.show();

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

优点:

  • 将一组相关或相互依赖的对象集中在一起创建,在设计上符合单一职责原则。
  • 客户端代码与具体工厂类解耦,更容易扩展新的产品系列。

与其他类似的模式对比:

  • 工厂模式也可以创建对象,但它的重点是某个类的对象创建过程,而抽象工厂模式更关注一组相关或相互依赖对象的创建。
  • 单例模式保证了全局只有一个实例,不适合用来创建一系列对象。

总结:抽象工厂模式是一种常用的创建型模式,它提供了一个创建一系列相关或相互依赖对象的接口,无需指定具体的类。抽象工厂模式将一组相关或相互依赖的对象集中在一起创建,实现了客户端与具体工厂类的解耦。与其他类似模式相比,抽象工厂模式更关注一组对象的创建。

建造者模式

核心观点:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式是一种创建型模式,它将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

下面是一个简单的建造者模式的示例代码:

public class Product {
    
    
    private String partA;
    private String partB;

    public void setPartA(String partA) {
    
    
        this.partA = partA;
    }

    public void setPartB(String partB) {
    
    
        this.partB = partB;
    }

    public void show() {
    
    
        System.out.println("Part A: " + partA);
        System.out.println("Part B: " + partB);
    }
}

public abstract class Builder {
    
    
    public abstract void buildPartA();
    public abstract void buildPartB();
    public abstract Product getResult();
}

public class ConcreteBuilder1 extends Builder {
    
    
    private Product product = new Product();

    @Override
    public void buildPartA() {
    
    
        product.setPartA("Part A from ConcreteBuilder1");
    }

    @Override
    public void buildPartB() {
    
    
        product.setPartB("Part B from ConcreteBuilder1");
    }

    @Override
    public Product getResult() {
    
    
        return product;
    }
}

public class ConcreteBuilder2 extends Builder {
    
    
    private Product product = new Product();

    @Override
    public void buildPartA() {
    
    
        product.setPartA("Part A from ConcreteBuilder2");
    }

    @Override
    public void buildPartB() {
    
    
        product.setPartB("Part B from ConcreteBuilder2");
    }

    @Override
    public Product getResult() {
    
    
        return product;
    }
}

public class Director {
    
    
    public void construct(Builder builder) {
    
    
        builder.buildPartA();
        builder.buildPartB();
    }
}

public class Client {
    
    
    public static void main(String[] args) {
    
    
        Director director = new Director();
        Builder builder1 = new ConcreteBuilder1();
        director.construct(builder1);
        Product product1 = builder1.getResult();
        product1.show();

        Builder builder2 = new ConcreteBuilder2();
        director.construct(builder2);
        Product product2 = builder2.getResult();
        product2.show();
    }
}

优点:

  • 将一个复杂对象的构建与它的表示分离,使得构建过程灵活多变,可以对同一个构建过程创建不同的表示。
  • 客户端不需要知道具体的构建过程,只需要指定具体的建造者对象即可,简化了客户端的使用。

与其他类似的模式对比:

  • 工厂模式也用于创建对象,但它更关注对象的创建过程,而建造者模式更注重对象的构建过程和表示。
  • 抽象工厂模式也可以创建一系列相关对象,它将一组相关对象集中在一起创建,而建造者模式将一个复杂对象的构建与它的表示分离。

总结:建造者模式是一种常用的创建型模式,它将一个复杂对象的构建与它的表示分离,使得构建过程灵活多变,可以对同一个构建过程创建不同的表示。使用建造者模式可以较好地解决构建复杂对象的问题,同时使得客户端代码更加简洁,易于维护。与其他类似模式相比,建造者模式更关注对象的构建过程和表示。

原型模式

概述
原型模式是一种创建型模式,它通过复制现有对象来创建新对象,避免了重复的初始化过程。核心思想是通过克隆方法来复制现有的对象,以创建新的对象。原型模式适用于需要创建大量相似对象,但是对象的创建过程比较耗时或昂贵的情况。

代码示例
下面是一个使用原型模式的代码示例:

// 原型接口
interface Prototype {
    
    
    Prototype clone();  // 克隆方法
}

// 具体原型类
class ConcretePrototype implements Prototype {
    
    
    private String name;

    public ConcretePrototype(String name) {
    
    
        this.name = name;
    }

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

    public void setName(String name) {
    
    
        this.name = name;
    }

    public String getName() {
    
    
        return this.name;
    }
}

// 客户端代码
public class Client {
    
    
    public static void main(String[] args) {
    
    
        ConcretePrototype prototype = new ConcretePrototype("原型对象");
        ConcretePrototype clone = (ConcretePrototype) prototype.clone();
        clone.setName("克隆对象");

        System.out.println(prototype.getName());  // 输出:原型对象
        System.out.println(clone.getName());      // 输出:克隆对象
    }
}

在上面的示例中,我们定义了一个原型接口 Prototype,包含了一个克隆方法 clone()。具体的原型类 ConcretePrototype 实现了原型接口,并实现了克隆方法,在克隆方法中创建了新的对象并返回。客户端代码中使用原型模式创建了一个原型对象,并通过克隆方法获得了一个克隆对象。

优缺点分析
原型模式的优点如下:

  • 节省对象的初始化时间和资源。由于原型模式是通过克隆已有对象来创建新对象,避免了重复的初始化过程,提高了对象的创建效率。
  • 简化对象的创建过程。通过原型模式,我们可以直接复制已有对象的状态,而不需要手动设置每个属性的值,简化了对象的创建过程。

原型模式的缺点如下:

  • 对象的克隆可能会受限。有些对象的克隆是受限制的,例如不能克隆单例对象、不能克隆不可序列化的对象等。
  • 对象的克隆可能会导致深拷贝问题。如果对象的属性中包含了引用类型的成员变量,克隆时可能会导致深拷贝问题,需要注意处理。

与其他模式的比较

  • 原型模式与工厂模式:原型模式和工厂模式都是创建型模式,但它们的目的不同。原型模式关注的是如何通过复制已有对象来创建新对象,而工厂模式关注的是如何通过工厂方法或工厂类来创建对象。
  • 原型模式与单例模式:原型模式和单例模式都是创建型模式,但它们的目的截然不同。原型模式旨在创建新对象,每个对象都有一个独立的状态;而单例模式旨在创建唯一的对象,所有对象共享同一个状态。

综上所述,原型模式是一种通过复制现有对象来创建新对象的创建型模式,适用于需要创建大量相似对象的情况。它可以提高对象的创建效率,简化对象的创建过程。但是需要注意对象克隆的限制和深拷贝问题。

总体而言,原型模式是一种简单而实用的设计模式,能够有效地提升代码的重复利用和创建效率,适用于各种不同的应用场景。

猜你喜欢

转载自blog.csdn.net/jingyoushui/article/details/132953522