在本文章开始之前先说明:
设计模式不是代码,是某类问题的通用解决放啊,本质是用来提高 软件的维护性、通用性、扩展性,并且降低软件的复杂度 。
进入正题:
已知创建者模式分为以下5种:
单例模式、抽象工厂模式、原型模式、建造者模式、工厂模式
单例模式
点击下面链接进入
设计模式——单例模式8种实现-CSDN博客
工厂模式
设计模式——三大工厂模式-CSDN博客
原型模式
介绍
原型模式是一种创建型设计模式,它允许创建对象的同时保持其内部状态的一份拷贝,从而避免了使用详细的构造函数和初始化过程。
个人理解:
就是通过克隆已有的对象,来创建新的对象,从而减少对象实例化过程。
原型模式中的浅拷贝和深拷贝
1、浅拷贝:
在对对象进行拷贝的时候,只会拷贝它的基本数据类型,引用数据类型只会对其引用
2、深拷贝
在对一个对象进行拷贝的时候,拷贝整个对象,不论基本数据类型和引用数据类型
代码示例
1、浅拷贝实例
如下实例,Sheep类通过集成Cloneable接口,实现直接浅拷贝功能(克隆)。
// 创建一个实现 Cloneable 接口的原型类
class Sheep implements Cloneable {private String name;public Sheep(String name) {this.name = name;}public String getName() {return name;}// 重写 clone 方法实现深拷贝@Overridepublic Sheep clone() {try {return (Sheep) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}
}public class PrototypePatternExample {public static void main(String[] args) {Sheep originalSheep = new Sheep("Dolly");// 使用原型对象的 clone 方法复制一个新对象Sheep clonedSheep = originalSheep.clone();System.out.println("Original sheep: " + originalSheep.getName());System.out.println("Cloned sheep: " + clonedSheep.getName());}
}
2、深拷贝实例
(下面只是一种实现深拷贝的方式,还有一种可以使用序列化实现深克隆)
下面使用对clone方法进行重写,实现深拷贝对象功能。
// 创建一个包含引用类型成员变量的原型类
class Person implements Cloneable {private String name;private Address address;public Person(String name, Address address) {this.name = name;this.address = address;}public String getName() {return name;}public Address getAddress() {return address;}@Overridepublic Person clone() {try {Person clonedPerson = (Person) super.clone();// 对引用类型成员变量进行深拷贝clonedPerson.address = this.address.clone();return clonedPerson;} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}
}// 创建包含引用类型成员变量的另一个类
class Address implements Cloneable {private String city;public Address(String city) {this.city = city;}public String getCity() {return city;}@Overridepublic Address clone() {try {return (Address) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}
}public class DeepCopyExample {public static void main(String[] args) {Address originalAddress = new Address("Beijing");Person originalPerson = new Person("Alice", originalAddress);// 使用原型对象的 clone 方法进行深拷贝Person clonedPerson = originalPerson.clone();// 修改原始对象的地址originalAddress.setCity("Shanghai");// 输出克隆对象的地址,验证是否进行了深拷贝System.out.println("Original person's address: " + originalPerson.getAddress().getCity());System.out.println("Cloned person's address: " + clonedPerson.getAddress().getCity());}
}
小结和补充
优点
1、减少对象的创建时间
2、隐藏对象的创建细节:使得对象的创建过程更加简洁和易于维护。
3、动态改变对象的状态:在运行时可以修改对象的属性或内部状态,而无需通过重新实例化新对象来实现,使得系统更加灵活。
缺点
1、需要为每一个类配置一个克隆方法,需要修改其源码,违反了ocp原则
2、需要实现 Cloneable 接口:在 Java 中,被克隆的类需要实现 Cloneable 接口,并重写 clone 方法,这在某些情况下会增加代码的复杂性。
3、深拷贝问题:如果对象内部包含了引用类型的成员变量,克隆时需要注意深拷贝,否则可能会导致对象之间的关联性问题
补充
在 Spring 框架中,原型模式通常被用于创建 bean 实例。Spring 容器中的 bean 实例可以分为两种类型:单例和原型。单例 bean 是在容器启动时创建的,并且在整个应用程序生命周期中都只存在一个实例。而原型 bean 则是在每次请求时都会创建一个新的实例。
<bean id="myPrototypeBean" class="com.example.MyPrototypeBean" scope="prototype"/>
建造者模式
介绍
1、建造者模式又称生成器模式,是一种对象构建模式,可以将复杂对象的构建过程抽象出来,使这个抽象过程的不同实现方法可以构造出不同属性的对象。
2、建造者模式是一步一步创建一个复杂对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部实现细节。
为什么会有建造者模式
(可以说建造者模式的目的)
1、为了更好构建复杂对象
2、分离构建过程和表示
3、提供更好的控制构建过程
4、支持构建不同表示的对象
5、提高代码复用性
建造者模式的4个角色
Product(产品角色):一个具体的产品对象
Builder(抽象建造者):创建一个Product对象的各个部件指定的接口/抽象类。
ConcreteBuilder(具体建造者):实现接口,构建和装配各个部件
Director(指挥官):构建一个使用Builder接口的对象,它主要是用于创建一个复杂的对象。它主要有两个作用,一是:隔离客户与对象的生产过程;二是:复杂控制产品对象的生产过程。
实例
下面是一个Car的产品角色,CarBuilder就是车的各个部件(接口类),通过ConcreteCarBuilder 继承CarBuilder接口实现具体部件从而的得到车。可以在测试类(Director)中构建实现这个车
抽象建造者
public interface CarBuilder {void buildBody();void buildEngine();void buildTires();Car getCar();
}
具体建造者
public class ConcreteCarBuilder implements CarBuilder {private Car car;public ConcreteCarBuilder() {this.car = new Car();}@Overridepublic void buildBody() {car.setBody("Sedan");}@Overridepublic void buildEngine() {car.setEngine("V6");}@Overridepublic void buildTires() {car.setTires("All-Season");}@Overridepublic Car getCar() {return car;}
}
产品
public class Car {private String body;private String engine;private String tires;public void setBody(String body) {this.body = body;}public void setEngine(String engine) {this.engine = engine;}public void setTires(String tires) {this.tires = tires;}public void showInfo() {System.out.println("Car: " + body + ", " + engine + ", " + tires);}
}
指挥者
public class CarBuilderExample {public static void main(String[] args) {CarBuilder carBuilder = new ConcreteCarBuilder();// 构建汽车对象carBuilder.buildBody();carBuilder.buildEngine();carBuilder.buildTires();// 获取构建完成的汽车对象Car car = carBuilder.getCar();// 展示汽车信息car.showInfo();}
}
建造者模式在JDK中使用
-
StringBuilder
1、Appendable接口定义了多个append方法(抽象方法),即Appendable为抽象建造者定义了抽象方法
2、AbstractStringBuilder 已经是建造者,只是不能实例化
3、StringBuilder 即充当了指挥者,也充当了具体的建造者。建造方法的实现是由AbstractStringBuilder 完成,而StringBuilder继承了AbstractStringBuilder。
Product(产品角色):StringBuilder
Builder(抽象建造者):Appendable接口
ConcreteBuilder(具体建造者):AbstractStringBuilder抽象类
Director(指挥官):StringBuilder
小结
优点
1、分离构建过程与表示: 建造者模式将复杂对象的构建过程与最终表示分离,使得可以更加灵活地构建不同结构的对象。 2、更好的控制构建过程: 通过建造者模式,可以逐步构建复杂对象,每一步都可以有不同的实现,从而更好地控制构建过程。 3、易于扩展: 由于建造者模式将构建过程和最终产品分离,因此很容易添加新的具体建造者来构建不同类型的产品,而不需要修改现有代码。 4、提高代码复用性: 可以在不同的场景下重复使用相同的构建逻辑,提高代码复用性。
2、缺点
1、增加了代码量: 引入建造者模式会增加代码量,因为需要定义抽象建造者、具体建造者等额外的类。 2、可能会导致对象过于复杂: 如果产品本身比较简单,引入建造者模式可能会显得过于繁琐,不值得。
最后的总结
个人的理解:
1、单例模式就是一个类只能有一个实例对象;
2、工厂模式就是通过条件,生成统一的类对象;
3、原型模式就是通过克隆复制对象来实现快速获取一个对象;
4、建造者模式就是对一个复杂类的一步步具体拆分实现
-
单例模式(Singleton Pattern):
- 单例模式确保一个类只有一个实例,并提供一个全局访问点。这对于需要共享资源的对象或控制对象的创建数量很有用。
-
工厂模式(Factory Pattern):
- 工厂模式通过使用工厂方法来创建对象,而无需指定将要创建的对象的具体类。这样可以根据特定条件或参数创建相应的对象实例。
-
原型模式(Prototype Pattern):
- 原型模式通过克隆(复制)现有对象来创建新对象。这种方式可以避免重复初始化成本高的对象,提高性能。
-
建造者模式(Builder Pattern):
- 建造者模式用于创建一个复杂对象,将其构建过程与表示分离,使得同样的构建过程可以创建不同的表示。通常在创建具有多个部分或配置选项的对象时使用。