设计模式——创建型模式

常见的设计模式包括:

  • 创建型模式:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。
  • 结构型模式:适配器模式、桥接模式、装饰器模式、组合模式、外观模式、享元模式、代理模式。
  • 行为型模式:责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式。

1.创建型模式

  • 创建型模式是设计模式的一种类型,关注对象的创建和实例化过程。这些模式可以帮助我们在创建对象时更加灵活和可控,并且可以提高代码的可维护性和可扩展性。
  • 常见的创建型模式:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式

1.1 单例模式

单例模式(Singleton Pattern)是一种创建型模式,它保证一个类只有一个实例,并提供了一个全局访问点,使得该实例可以被全局访问。
以下是一个简单的单例模式的示例代码:

public class Singleton {
    // 私有静态成员变量,用于保存唯一实例
    private static Singleton instance;

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

    // 公有静态方法,用于获取唯一实例,静态方法不需要创建对象就能调用,如
    // Singleton instance = Singleton.getInstance();
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    // 其他方法
    public void doSomething() {
        System.out.println("Singleton do something.");
    }
}

在上面的示例代码中,Singleton 类只有一个私有静态成员变量 instance,用于保存唯一实例。私有构造函数 Singleton() 用于防止外部创建实例。公有静态方法 getInstance() 用于获取唯一实例,并且使用了双重检查锁定机制来保证线程安全。doSomething() 方法是 Singleton 类的其他方法,用于演示单例模式的使用。
通过单例模式,我们可以保证 Singleton 类只有一个实例,并且可以通过 getInstance() 方法来获取该实例。这样就可以避免在系统中创建多个相同的对象,从而节省系统资源,并且保证系统的一致性和可靠性。
单例模式常用于需要在系统中创建唯一实例的场景,比如数据库连接池、日志记录器、配置信息管理器等。
例题:
image.png

1.2 工厂方法模式

工厂方法模式(Factory Method Pattern)是一种创建型模式,它定义了一个用于创建对象的接口,让子类(即具体的工厂类)决定实例化哪一个类。与简单工厂模式不同的是,工厂方法模式将具体产品的创建延迟到了具体的工厂类中,从而更加符合开闭原则
image.png

简单工厂模式

image.png
没有工厂接口,直接由客户端的参数决定工厂创造什么产品。如果要新增产品的话,需要修改工厂类的方法,不符合开闭原则。

开闭原则

开闭原则(Open-Closed Principle,OCP)是面向对象设计中的一个重要原则,它指出一个软件实体(类、模块、函数等)应该对扩展开放(Open for extension),对修改关闭(Closed for modification)。换言之,当需要修改一个软件实体的行为时,不应该直接修改它的源代码,而应该通过扩展它的行为来实现。
开闭原则的核心思想是通过抽象来达到扩展的目的,从而避免对原有代码的修改。具体来说,可以通过以下方式来实现开闭原则:

  1. 抽象化:通过接口、抽象类等方式将软件实体的行为进行抽象,从而使其更加灵活和可扩展。
  2. 封装变化:将可能发生变化的部分封装起来,从而使其对其他部分不可见,从而降低了系统的耦合度。
  3. 继承和多态:利用继承和多态等机制来实现开闭原则,通过子类继承父类或实现接口来扩展系统的功能,从而避免直接修改原有代码。

工厂方法模式示例

以下是一个简单的工厂方法模式的示例代码,假设我们要创建一个图形,包括圆形和矩形,每种图形都有对应的工厂类:

public interface Shape {
    void draw();
}
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Draw a circle.");
    }
}

public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Draw a rectangle.");
    }
}
1.创建工厂类
// 创建对象的接口
public interface ShapeFactory {
    Shape createShape();
}

public class CircleFactory implements ShapeFactory {
    @Override
    public Shape createShape() {
        return new Circle();
    }
}

public class RectangleFactory implements ShapeFactory {
    @Override
    public Shape createShape() {
        return new Rectangle();
    }
}

在上面的示例代码中,Shape 接口定义了图形的基本操作,包括 draw() 方法。Circle 类和 Rectangle 类分别实现了 Shape 接口,并实现了 draw() 方法,用于绘制圆形和矩形。ShapeFactory 接口定义了工厂的基本操作,包括 createShape() 方法。CircleFactory 类和 RectangleFactory 类分别实现了 ShapeFactory 接口,并实现了 createShape() 方法,用于创建圆形和矩形对象。
用户可以通过工厂类来创建图形对象,具体的步骤如下:

  1. 创建一个具体的工厂类对象,例如 CircleFactory 或 RectangleFactory。
  2. 调用工厂类的 createShape() 方法,工厂类会返回对应的图形对象,例如圆形对象或矩形对象。

下面是一个简单的调用示例代码:

public class Client {
    public static void main(String[] args) {
        ShapeFactory circleFactory = new CircleFactory();
        Shape shape1 = circleFactory.createShape();
        shape1.draw();

        ShapeFactory rectangleFactory = new RectangleFactory();
        Shape shape2 = rectangleFactory.createShape();
        shape2.draw();
    }
}

在上面的示例代码中,首先创建了具体的工厂类对象 CircleFactory 和 RectangleFactory。然后分别调用工厂类的 createShape() 方法,这样工厂类就知道了应该创建哪种图形。最后通过返回的图形对象的 draw() 方法来绘制图形。
通过工厂方法模式,客户端可以通过工厂类来创建对象,而不需要直接与具体的实现类耦合,从而提高了系统的灵活性和可维护性。同时,工厂方法模式还可以将对象的创建过程封装起来,从而提高了系统的安全性和可重用性。

1.3 抽象工厂模式

工厂方法模式中,工厂创建的产品都属于同一个大类(抽象类),而抽象工厂模式可以让工厂生产多个大类的产品。但是如果要添加产品类别的话,又会涉及到修改抽象工厂和工厂实现类中方法的代码,也会不符合开闭原则。
image.png

抽象工厂模式示例

以下是一个简单的抽象工厂模式的示例代码,假设我们要创建一个图形,包括圆形和矩形,每种图形都有对应的颜色,包括红色和蓝色,每种颜色都有对应的工厂类:

public interface Shape {
    void draw();
}

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Draw a circle.");
    }
}

public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Draw a rectangle.");
    }
}

public interface Color {
    void fill();
}

public class Red implements Color {
    @Override
    public void fill() {
        System.out.println("Fill with red color.");
    }
}

public class Blue implements Color {
    @Override
    public void fill() {
        System.out.println("Fill with blue color.");
    }
}

public interface AbstractFactory {
    Shape createShape();
    Color createColor();
}

public class RedCircleFactory implements AbstractFactory {
    @Override
    public Shape createShape() {
        return new Circle();
    }

    @Override
    public Color createColor() {
        return new Red();
    }
}

public class BlueRectangleFactory implements AbstractFactory {
    @Override
    public Shape createShape() {
        return new Rectangle();
    }

    @Override
    public Color createColor() {
        return new Blue();
    }
}

在上面的示例代码中,Shape 接口定义了图形的基本操作,包括 draw() 方法。Circle 类和 Rectangle 类分别实现了 Shape 接口,并实现了 draw() 方法,用于绘制圆形和矩形。Color 接口定义了颜色的基本操作,包括 fill() 方法。Red 类和 Blue 类分别实现了 Color 接口,并实现了 fill() 方法,用于填充红色和蓝色。AbstractFactory 接口定义了工厂的基本操作,包括 createShape() 方法和 createColor() 方法。RedCircleFactory 类和 BlueRectangleFactory 类分别实现了 AbstractFactory 接口,并实现了 createShape() 方法和 createColor() 方法,用于创建红色圆形对象和蓝色矩形对象。
用户可以通过工厂类来创建图形和颜色对象,具体的步骤如下:

  1. 创建一个具体的工厂类对象,例如 RedCircleFactory 或 BlueRectangleFactory。
  2. 调用工厂类的 createShape() 方法和 createColor() 方法,工厂类会返回对应的图形对象和颜色对象,例如红色圆形对象或蓝色矩形对象。

下面是一个简单的调用示例代码:

public class Client {
    public static void main(String[] args) {
        AbstractFactory factory1 = new RedCircleFactory();
        Shape shape1 = factory1.createShape();
        Color color1 = factory1.createColor();
        shape1.draw();
        color1.fill();

        AbstractFactory factory2 = new BlueRectangleFactory();
        Shape shape2 = factory2.createShape();
        Color color2 = factory2.createColor();
        shape2.draw();
        color2.fill();
    }
}

在上面的示例代码中,首先创建了具体的工厂类对象 RedCircleFactory 和 BlueRectangleFactory。然后分别调用工厂类的 createShape() 方法和 createColor() 方法,这样工厂类就知道了应该创建哪种图形和颜色。最后通过返回的图形对象的 draw() 方法和颜色对象的 fill() 方法来绘制图形和填充颜色。
通过抽象工厂模式,客户端可以通过工厂类来创建一组相关的对象,而不需要直接与具体的实现类耦合,从而提高了系统的灵活性和可维护性。同时,抽象工厂模式还可以将一组相关的产品组合起来,从而提供更高层次的抽象,使客户端不需要关心产品的具体实现。

1.4 建造者模式

建造者模式(Builder Pattern)是一种创建型模式,它可以将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。建造者模式通常包含一个抽象建造者、具体建造者、指挥者和产品等组成部分。
下面是一个简单的建造者模式的示例代码,假设我们要创建一个电脑,它包含 CPU、内存、硬盘等组件:

1.定义要建造的产品

电脑类:

public class Computer {
    private String cpu;
    private String memory;
    private String hardDisk;

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }

    public void setMemory(String memory) {
        this.memory = memory;
    }

    public void setHardDisk(String hardDisk) {
        this.hardDisk = hardDisk;
    }

    public String getDescription() {
        return "This is a computer with " + cpu + " CPU, " + memory + " memory and " + hardDisk + " hard disk.";
    }
}

2.定义建造者

电脑建造者接口:

public interface ComputerBuilder {
    void buildCpu();
    void buildMemory();
    void buildHardDisk();
    Computer getResult();
}

电脑建造者实现:

public class OfficeComputerBuilder implements ComputerBuilder {
    private Computer computer = new Computer();

    @Override
    public void buildCpu() {
        computer.setCpu("Intel Core i5");
    }

    @Override
    public void buildMemory() {
        computer.setMemory("8GB");
    }

    @Override
    public void buildHardDisk() {
        computer.setHardDisk("1TB");
    }

    @Override
    public Computer getResult() {
        return computer;
    }
}

3.定义指挥者

指挥者类的实现:

public class Director {
    public void construct(ComputerBuilder builder) {
        builder.buildCpu();
        builder.buildMemory();
        builder.buildHardDisk();
    }
}

4.客户端创建产品

在上面的示例代码中,Computer 类是要创建的产品,它包含 CPU、内存、硬盘等组件,同时提供了 getDescription() 方法用于获取产品的描述信息。ComputerBuilder 接口定义了创建产品的抽象方法,包括 buildCpu()、buildMemory() 和 buildHardDisk() 方法,以及 getResult() 方法用于获取创建好的产品。OfficeComputerBuilder 类是具体的建造者,它实现了 ComputerBuilder 接口中定义的抽象方法,用于创建办公电脑产品。Director 类是指挥者,它负责调用建造者的方法来创建产品。具体调用的过程如下所示:

public class Client {
    public static void main(String[] args) {
        ComputerBuilder builder = new OfficeComputerBuilder();
        Director director = new Director();
        director.construct(builder);
        Computer computer = builder.getResult();
        System.out.println(computer.getDescription());
    }
}

首先创建了一个具体的建造者对象 OfficeComputerBuilder 和一个指挥者对象 Director。然后调用指挥者的 construct() 方法,并将具体的建造者对象作为参数传入,这样指挥者就知道了如何创建产品。最后通过具体的建造者对象的 getResult() 方法获取创建好的产品,并输出其描述信息。
使用建造者模式可以将复杂对象的构建过程封装起来,使得客户端只需要关心要创建的产品的类型和建造者的类型,而不需要关心产品的具体构建过程。同时,建造者模式可以避免在客户端中直接创建复杂对象,从而提高系统的灵活性和可维护性。

1.5 原型模式

原型模式(Prototype Pattern)是一种创建型模式,它允许通过复制现有对象来创建新对象,而不是通过实例化类来创建对象。原型模式适用于创建对象的过程比较复杂,或者需要创建多个相似但不完全相同的对象的情况。
image.png
即定义一个抽象类里面有clone方法,支持克隆的原型对象需要实现这个方法

原型模式示例

以下是一个简单的原型模式的示例代码,假设我们要创建一个图形,包括圆形和矩形,每种图形都有对应的颜色:

1.定义原型接口

image.png

2.创建实现clone方法的类

image.png

3.调用clone方法克隆对象

image.png
通过原型模式,客户端可以通过复制现有对象来创建新对象,而不需要通过实例化类来创建对象,从而提高了系统的灵活性和可维护性。同时,原型模式还可以避免了不必要的复杂对象构造过程,从而提高了系统的性能。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值