1、创建型模式
创建型模式的作用就是为了产生实例对象。
1.1、单例模式
定义:一个类只有一个实例,且这个类能自行创建这个实例。
特点:1、单例类只有一个对象
2、单例类必须自己创建自己的对象
3、单例类需要给其他类提供访问这个对象的节点
应用:Windows 的回收站、操作系统中的文件系统、多线程中的线程池、显卡的驱动程序对象、打印机的后台处理服务、应用程序的日志对象、数据库的连接池、网站的计数器、Web 应用的配置对象、应用程序中的对话框、系统中的缓存等。
优点:内存中只有一个实例;避免对资源的多重占用;设置全局访问节点,可以优化资源的访问。
缺点:不能继承,扩展困难;并发测试中,不利于代码调试。
单例类的结构

单例类的实现
(1)懒汉式实现
public class LazySingleton {
private static volatile LazySingleton instance = null; //保证 instance 在所有线程中同步
private LazySingleton() {
} //private 避免类在外部被实例化
public static synchronized LazySingleton getInstance() {
//getInstance 方法前加同步
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
懒汉式实现在实例化时没有生成单例,只有在调用getInstance()时才生成单例。懒汉式需要保证多线程安全性(通过volatile和synchronized),但带来而外的开销。
(2)饿汉式单例
public class HungrySingleton {
private static final HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return instance;
}
}
饿汉式单例在实例化时就生成单例,是线程安全的。
参考文献
(1)菜鸟教程-单例模式
(2)C语言中文网-单例模式
1.2、工厂模式
定义:在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
示例:

1.3、抽象工厂模式
定义:抽象工厂模式(Abstract Factory Pattern)是围绕一个抽象工厂创建其他工厂,该抽象工厂又称为其他工厂的工厂。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
示例:

1.4、建造者模式
定义:建造者模式(Builder Pattern)使用多个简单的对象一步一步(链式)构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
优点: 1、建造者独立,易扩展。 2、便于控制细节风险。
缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。
示例:
class User {
// 下面是“一堆”的属性
private String name;
private String password;
private String nickName;
private int age;
// 构造方法私有化,不然客户端就会直接调用构造方法了
private User(String name, String password, String nickName, int age) {
this.name = name;
this.password = password;
this.nickName = nickName;
this.age = age;
}
// 静态方法,用于生成一个 Builder,这个不一定要有,不过写这个方法是一个很好的习惯,
// 有些代码要求别人写 new User.UserBuilder().a()...build() 看上去就没那么好
public static UserBuilder builder() {
return new UserBuilder();
}
public static class UserBuilder {
// 下面是和 User 一模一样的一堆属性
private String name;
private String password;
private String nickName;
private int age;
private UserBuilder() {
}
// 链式调用设置各个属性值,返回 this,即 UserBuilder
public UserBuilder name(String name) {
this.name = name;
return this;
}
public UserBuilder password(String password) {
this.password = password;
return this;
}
public UserBuilder nickName(String nickName) {
this.nickName = nickName;
return this;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
// build() 方法负责将 UserBuilder 中设置好的属性“复制”到 User 中。
// 当然,可以在 “复制” 之前做点检验
public User build() {
if (name == null || password == null) {
throw new RuntimeException("用户名和密码必填");
}
if (age <= 0 || age >= 150) {
throw new RuntimeException("年龄不合法");
}
// 还可以做赋予”默认值“的功能
if (nickName == null) {
nickName = name;
}
return new User(name, password, nickName, age);
}
}
}
则可以通过下面的代码进行调用:
User d = User.builder()
.name("foo")
.password("pAss12345")
.age(25)
.build();
Tips:可以通过LomBok的注解:@Builder将类设置为建造者模式
@Builder class User { private String name; private String password; private String nickName; private int age; }
1.5、原型模式
定义:原型模式(Prototype Pattern)是用于创建重复的对象,首先需要一个原型实例,基于这个原型实例产生新的实例,也就是“克隆”。
优点: 1、性能提高。 2、逃避构造函数的约束。
缺点: 1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。 2、必须实现 Cloneable 接口。
Tips:Object 类中有一个 clone() 方法,它用于生成一个新的对象,当然,如果我们要调用这个方法,java 要求我们的类必须先实现 Cloneable 接口,此接口没有定义任何方法,但是不这么做的话,在 clone() 的时候,会抛出 CloneNotSupportedException 异常。同时,java 的克隆是浅克隆,碰到对象引用的时候,克隆出来的对象和原对象中的引用将指向同一个对象。通常实现深克隆的方法是将对象进行序列化,然后再进行反序列化。
本文详细介绍了创建型设计模式,包括单例模式、工厂模式、抽象工厂模式、建造者模式和原型模式。单例模式确保类只有一个实例,适用于全局访问点和资源管理。工厂模式提供了一个创建对象的接口,简化了对象创建过程。抽象工厂模式用于创建一系列相关或相互依赖的对象。建造者模式通过步骤构建复杂对象,提供了更大的灵活性。原型模式通过克隆已有对象创建新对象,适用于性能优化和逃避构造函数约束。每种模式都分析了其优缺点和应用场景。

被折叠的 条评论
为什么被折叠?



