创建型模式是软件工程中常用的设计模式之一,主要关注对象的创建过程。创建型模式隐藏了对象创建的细节,而不是直接使用new操作符创建对象。这样做的好处包括:
以下是几种常见的创建型设计模式:
单例模式(Singleton)
工厂方法模式(Factory Method)
抽象工厂模式(Abstract Factory)
建造者模式(Builder)
原型模式(Prototype)
单例设计模式(Singleton Pattern)是一种常用的软件设计模式,其核心思想是确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。这种模式在很多场景下都非常有用,比如配置管理器、线程池、缓存等。
单例模式有几个关键特点:
1. 私有的构造函数:确保不能通过new关键字在类的外部创建实例。
2. 私有的静态变量:用于存储类的唯一实例。
3. 公有的静态方法:提供一个全局访问点来获取实例,如果实例不存在,则创建它。
以下是几种实现单例模式的方法:
public class Singleton {
// 私有的静态变量,存储类的唯一实例
private static Singleton instance;
// 私有的构造函数,防止外部通过new创建实例
private Singleton() {}
// 公有的静态方法,提供全局访问点
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
public class Singleton {
// 私有的静态变量,存储类的唯一实例,并在类加载时就创建实例
private static final Singleton instance = new Singleton();
// 私有的构造函数
private Singleton() {}
// 公有的静态方法
public static Singleton getInstance() {
return instance;
}
}
public class Singleton {
// 私有的静态变量
private static volatile Singleton instance;
// 私有的构造函数
private Singleton() {}
// 公有的静态方法
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
public class Singleton {
// 私有的构造函数
private Singleton() {}
// 静态内部类,静态内部类的加载时机是在外部类被加载时,并且静态内部类可以持有外部类的引用
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
// 公有的静态方法
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
public enum Singleton {
INSTANCE;
// 可以在这里添加其他方法
}
使用枚举方式实现单例是最简单的,也是最推荐的方式,因为它不仅代码简洁,而且自动支持序列化机制,防止多次实例化。
选择哪种实现方式取决于你的具体需求,比如是否需要考虑线程安全、是否需要延迟实例化等。
工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它定义了一个创建对象的接口,但让子类决定要实例化的类。工厂方法模式让类的实例化推迟到子类中进行。
工厂方法模式的主要优点包括:
1. 代码的模块化:将对象的创建和使用分离,使得代码更加模块化。
2. 扩展性:当需要引入新的类时,只需添加一个子类即可,无需修改现有的代码。
3. 解耦:客户端不需要知道具体的产品类,只需要知道产品接口。
工厂方法模式的主要角色包括:
1. 抽象产品(Product):定义了产品的接口。
2. 具体产品(Concrete Product):实现了抽象产品接口的具体类。
3. 抽象工厂(Creator):声明了工厂方法,返回一个产品类型的对象。
4. 具体工厂(Concrete Creator):实现了工厂方法,生成一个具体产品对象。
以下是工厂方法模式的简单实现:
抽象产品(Product
public interface Product {
void use();
}
具体产品(Concrete Product)
public class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println("Using ConcreteProductA");
}
}
public class ConcreteProductB implements Product {
@Override
public void use() {
System.out.println("Using ConcreteProductB");
}
}
抽象工厂(Creator)
public abstract class Creator {
// 工厂方法,返回一个产品类型的对象
public abstract Product factoryMethod();
}
具体工厂(Concrete Creator)
public class ConcreteCreatorA extends Creator {
@Override
public Product factoryMethod() {
return new ConcreteProductA();
}
}
public class ConcreteCreatorB extends Creator {
@Override
public Product factoryMethod() {
return new ConcreteProductB();
}
}
客户端代码
public class Client {
public static void main(String[] args) {
// 客户端代码
Creator creatorA = new ConcreteCreatorA();
Product productA = creatorA.factoryMethod();
productA.use();
Creator creatorB = new ConcreteCreatorB();
Product productB = creatorB.factoryMethod();
productB.use();
}
}
在这个例子中,`Creator` 是抽象工厂,它定义了一个工厂方法 `factoryMethod`,该方法返回一个 `Product` 类型的对象。`ConcreteCreatorA` 和 `ConcreteCreatorB` 是具体工厂,它们实现了 `factoryMethod` 方法,分别生成 `ConcreteProductA` 和 `ConcreteProductB`。客户端代码通过具体工厂来创建具体产品。
工厂方法模式非常适合于系统需要生成复杂对象的情况,并且系统希望将对象创建和使用分离,以提高系统的灵活性和可扩展性。
“抽象工厂模式”(Abstract Factory Pattern),是一种创建型设计模式,用于创建一系列相关或相互依赖的对象,而无需指定它们具体的类。抽象工厂模式提供了一种方式,让代码可以在不知道具体类的情况下工作,从而增强了代码的灵活性和可扩展性。
抽象工厂模式的主要优点包括:
1. 隔离具体类的生成:客户端不需要知道具体的类,只需要知道接口。
2. 增强模块化:将对象创建和使用分离,使得代码更加模块化。
3. 提高扩展性:当需要引入新的产品族时,只需添加一个新的具体工厂,无需修改现有代码。
抽象工厂模式的主要角色包括:
1. 抽象产品(Abstract Product):定义了产品的接口。
2. 具体产品(Concrete Product):实现了抽象产品接口的具体类。
3. 抽象工厂(Abstract Factory):定义了创建一系列抽象产品的方法。
4. 具体工厂(Concrete Factory):实现了抽象工厂的方法,生成一系列具体产品。
以下是抽象工厂模式的简单实现:
抽象产品(Abstract Product)
public interface AbstractProductA {
void use();
}
public interface AbstractProductB {
void use();
}
具体产品(Concrete Product)
public class ConcreteProductA1 implements AbstractProductA {
@Override
public void use() {
System.out.println("Using ConcreteProductA1");
}
}
public class ConcreteProductB1 implements AbstractProductB {
@Override
public void use() {
System.out.println("Using ConcreteProductB1");
}
}
public class ConcreteProductA2 implements AbstractProductA {
@Override
public void use() {
System.out.println("Using ConcreteProductA2");
}
}
public class ConcreteProductB2 implements AbstractProductB {
@Override
public void use() {
System.out.println("Using ConcreteProductB2");
}
}
抽象工厂(Abstract Factory)
public interface AbstractFactory {
AbstractProductA createProductA();
AbstractProductB createProductB();
}
具体工厂(Concrete Factory)
public class ConcreteFactory1 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ConcreteProductA1();
}
@Override
public AbstractProductB createProductB() {
return new ConcreteProductB1();
}
}
public class ConcreteFactory2 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ConcreteProductA2();
}
@Override
public AbstractProductB createProductB() {
return new ConcreteProductB2();
}
}
客户端代码
public class Client {
public static void main(String[] args) {
// 客户端代码
AbstractFactory factory1 = new ConcreteFactory1();
AbstractProductA productA1 = factory1.createProductA();
AbstractProductB productB1 = factory1.createProductB();
productA1.use();
productB1.use();
AbstractFactory factory2 = new ConcreteFactory2();
AbstractProductA productA2 = factory2.createProductA();
AbstractProductB productB2 = factory2.createProductB();
productA2.use();
productB2.use();
}
}
在这个例子中,`AbstractFactory` 是抽象工厂,它定义了创建一系列抽象产品的方法。`ConcreteFactory1` 和 `ConcreteFactory2` 是具体工厂,它们实现了抽象工厂的方法,生成一系列具体产品。客户端代码通过具体工厂来创建具体产品。
抽象工厂模式非常适合于系统需要生成一系列相关或相互依赖的对象的情况,并且系统希望将对象创建和使用分离,以提高系统的灵活性和可扩展性。
原型模式(Prototype Pattern)是一种创建型设计模式,它使得一个对象可以复制自身,从而创建一个与自己属性一致的新对象。这种模式特别适用于对象的创建成本较高,或者创建过程复杂、需要大量资源的情况。原型模式允许通过复制现有的对象来生成新对象,而不是通过新建对象的方式。
原型模式的主要优点包括:
1. 简化对象创建过程:避免了创建复杂对象的开销。
2. 提高性能:通过复制现有对象来创建新对象,可以节省时间。
3. **扩展性:可以轻松地增加新的原型类型,而无需修改现有代码。
原型模式的主要角色包括:
1. 原型接口(Prototype):声明一个克隆自身的接口。
2. 具体原型类(Concrete Prototype):实现原型接口,并实现克隆操作。
3. 客户端(Client):创建或复制原型对象。
以下是原型模式的简单实现:
原型接口(Prototype)
public interface Prototype {
Prototype clone();
}
具体原型类(Concrete Prototype)
public class ConcretePrototype implements Prototype {
private String field;
public ConcretePrototype(String field) {
this.field = field;
}
// 克隆自身
@Override
public Prototype clone() {
try {
return (ConcretePrototype) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
// Getter 和 Setter
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
}
客户端代码
public class Client {
public static void main(String[] args) {
// 创建一个原型对象
ConcretePrototype prototype = new ConcretePrototype("Original");
// 克隆原型对象
Prototype clonedPrototype = prototype.clone();
// 打印克隆后的对象信息
System.out.println("Original: " + prototype.getField());
System.out.println("Cloned: " + clonedPrototype.getField());
}
}
在这个例子中,`Prototype` 是原型接口,它声明了一个克隆自身的方法 `clone()`。`ConcretePrototype` 是具体原型类,它实现了原型接口,并实现了克隆操作。客户端代码创建了一个原型对象,然后通过调用 `clone()` 方法来复制这个对象。
原型模式非常适合于以下情况:
需要注意的是,原型模式要求对象能被复制,这意味着对象的状态必须是可复制的。此外,如果对象包含不可复制的资源(如文件句柄、数据库连接等),则不适合使用原型模式。在这种情况下,可能需要考虑使用其他模式,如工厂方法模式或抽象工厂模式。
建造者模式(Builder Pattern)是一种创建型设计模式,它提供了一种创建复杂对象的最佳方式。在建造者模式中,通过指定复杂对象的类型和内容,可以逐步构造一个复杂对象。这种模式隐藏了复杂对象的创建细节,使得对象的创建和表示分离。
建造者模式的主要优点包括:
1. 封装性:将复杂对象的创建和表示分离,使得创建过程独立于表示。
2. 灵活性:可以独立地改变复杂对象的创建过程,而不影响其他代码。
3. 可扩展性:可以轻松地扩展复杂对象的创建过程,以支持新的功能。
建造者模式的主要角色包括:
1. 产品(Product):需要被创建的复杂对象。
2. 抽象建造者(Builder):定义创建复杂对象的接口。
3. **具体建造者(Concrete Builder):实现抽象建造者接口,并提供方法来创建复杂对象的各个部分。
4. 导演者(Director):管理复杂对象的创建过程,通常包含一个建造者对象,并使用它来创建复杂对象。
5. 客户端(Client):创建具体建造者对象,并指导导演者如何使用建造者对象来创建复杂对象。
以下是建造者模式的简单实现:
产品(Product)
public class Product {
private String partA;
private String partB;
private String partC;
// 构造函数、getter 和 setter 省略
}
抽象建造者(Builder)
public interface Builder {
void buildPartA();
void buildPartB();
void buildPartC();
Product getResult();
}
具体建造者(Concrete Builder)
public class ConcreteBuilder implements Builder {
private Product product;
public ConcreteBuilder() {
product = new Product();
}
@Override
public void buildPartA() {
product.setPartA("PartA");
}
@Override
public void buildPartB() {
product.setPartB("PartB");
}
@Override
public void buildPartC() {
product.setPartC("PartC");
}
@Override
public Product getResult() {
return product;
}
}
导演者(Director)
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public void construct() {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
}
public Product getProduct() {
return builder.getResult();
}
}
客户端代码
public class Client {
public static void main(String[] args) {
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
director.construct();
Product product = director.getProduct();
// 使用 product
}
}
在这个例子中,`Product` 是需要被创建的复杂对象,`Builder` 是抽象建造者,定义了创建复杂对象的接口。`ConcreteBuilder` 是具体建造者,实现了抽象建造者接口,并提供了方法来创建复杂对象的各个部分。`Director` 是导演者,管理复杂对象的创建过程。客户端代码创建了一个具体建造者对象,并指导导演者如何使用建造者对象来创建复杂对象。
建造者模式非常适合于以下情况:
- 当创建复杂对象的算法应该独立于创建过程时。
- 当需要创建复杂对象的多种表示时。
- 当创建复杂对象的过程需要被封装或隐藏时。