创建型模式包括单例、工厂方法、抽象工厂、建造者和原型,分别用于全局唯一实例、对象创建解耦、产品族构建、分步生成复杂对象和克隆原型,提升代码复用性和维护性。
1. 单例模式(Singleton)
定义
确保一个类只有一个实例,并提供全局访问点。
结构
- 私有构造函数(防止外部实例化)
- 静态成员变量保存唯一实例
- 静态方法提供全局访问入口
Java 实现
// 枚举实现(线程安全,防止反射攻击)
public enum Singleton {
INSTANCE;
public void doSomething() {
System.out.println("Singleton instance is working.");
}
}
// 静态内部类实现(延迟加载,线程安全)
public class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
适用场景
- 全局配置管理(如数据库连接池)
- 日志记录器、工具类等需要唯一实例的场景
优缺点
- 优点:节省内存、严格控全局访问点。
- 缺点:可能引入全局状态,测试困难,违反单一职责原则。
2. 工厂方法模式(Factory Method)
定义
定义一个创建对象的接口,但由子类决定实例化哪个类。
结构
- 抽象工厂接口:声明创建对象的方法
- 具体工厂类:实现接口,创建具体对象
- 抽象产品接口:定义产品规范
- 具体产品类:实现产品接口
Java 实现
// 抽象产品
interface Transport {
void deliver();
}
// 具体产品
class Truck implements Transport {
@Override
public void deliver() {
System.out.println("Delivering by land.");
}
}
class Ship implements Transport {
@Override
public void deliver() {
System.out.println("Delivering by sea.");
}
}
// 抽象工厂
interface Logistics {
Transport createTransport();
}
// 具体工厂
class RoadLogistics implements Logistics {
@Override
public Transport createTransport() {
return new Truck();
}
}
class SeaLogistics implements Logistics {
@Override
public Transport createTransport() {
return new Ship();
}
}
// 客户端调用
public class Client {
public static void main(String[] args) {
Logistics logistics = new RoadLogistics();
Transport transport = logistics.createTransport();
transport.deliver(); // 输出: Delivering by land.
}
}
适用场景
- 跨平台UI组件创建(如不同操作系统下的按钮)
- 需要解耦对象创建逻辑的场景
优缺点
- 优点:符合开闭原则,扩展性强。
- 缺点:每新增一个产品需要新增工厂类,类数量增加。
3. 抽象工厂模式(Abstract Factory)
定义
创建一组相关或依赖对象的族,而无需指定具体类。
结构
- 抽象工厂接口:定义创建一族产品的方法
- 具体工厂类:实现接口,创建同一族的不同产品
- 抽象产品接口:定义产品族中每个产品的规范
- 具体产品类:实现同一族的不同产品
Java 实现
// 抽象产品族:家具
interface Chair {
void sitOn();
}
interface Sofa {
void lieOn();
}
// 具体产品:现代风格
class ModernChair implements Chair {
@Override
public void sitOn() {
System.out.println("Sitting on a modern chair.");
}
}
class ModernSofa implements Sofa {
@Override
public void lieOn() {
System.out.println("Lying on a modern sofa.");
}
}
// 具体产品:复古风格
class VintageChair implements Chair {
@Override
public void sitOn() {
System.out.println("Sitting on a vintage chair.");
}
}
class VintageSofa implements Sofa {
@Override
public void lieOn() {
System.out.println("Lying on a vintage sofa.");
}
}
// 抽象工厂
interface FurnitureFactory {
Chair createChair();
Sofa createSofa();
}
// 具体工厂
class ModernFurnitureFactory implements FurnitureFactory {
@Override
public Chair createChair() {
return new ModernChair();
}
@Override
public Sofa createSofa() {
return new ModernSofa();
}
}
class VintageFurnitureFactory implements FurnitureFactory {
@Override
public Chair createChair() {
return new VintageChair();
}
@Override
public Sofa createSofa() {
return new VintageSofa();
}
}
// 客户端调用
public class Client {
public static void main(String[] args) {
FurnitureFactory factory = new ModernFurnitureFactory();
Chair chair = factory.createChair();
Sofa sofa = factory.createSofa();
chair.sitOn(); // 输出: Sitting on a modern chair.
sofa.lieOn(); // 输出: Lying on a modern sofa.
}
}
适用场景
- 需要创建一组风格统一的对象(如UI主题、跨平台组件)
- 系统需要独立于产品的创建和组合
优缺点
- 优点:保证产品族的兼容性,符合开闭原则。
- 缺点:新增产品族容易,但新增产品类型困难(需修改所有工厂)。
4. 建造者模式(Builder)
定义
分步骤构建复杂对象,分离构造过程与表示。
结构
- 建造者接口:定义构建步骤
- 具体建造者:实现接口,构建具体对象
- 指挥者(Director) :控制构建流程
- 产品类:最终构建的复杂对象
Java 实现
// 复杂对象:汽车
class Car {
private String engine;
private int seats;
private boolean hasGPS;
public void setEngine(String engine) { this.engine = engine; }
public void setSeats(int seats) { this.seats = seats; }
public void setHasGPS(boolean hasGPS) { this.hasGPS = hasGPS; }
}
// 抽象建造者
interface CarBuilder {
void reset();
void buildEngine();
void buildSeats();
void buildGPS();
Car getResult();
}
// 具体建造者:跑车
class SportsCarBuilder implements CarBuilder {
private Car car;
public SportsCarBuilder() { this.reset(); }
@Override
public void reset() { car = new Car(); }
@Override
public void buildEngine() { car.setEngine("V8"); }
@Override
public void buildSeats() { car.setSeats(2); }
@Override
public void buildGPS() { car.setHasGPS(true); }
@Override
public Car getResult() { return car; }
}
// 指挥者
class Director {
public void constructSportsCar(CarBuilder builder) {
builder.reset();
builder.buildEngine();
builder.buildSeats();
builder.buildGPS();
}
}
// 客户端调用
public class Client {
public static void main(String[] args) {
Director director = new Director();
CarBuilder builder = new SportsCarBuilder();
director.constructSportsCar(builder);
Car car = builder.getResult();
}
}
适用场景
- 构造复杂对象(如SQL查询语句、XML文档生成)
- 需要不同配置的对象变体(如汽车的高配/低配)
优缺点
- 优点:封装构造细节,支持分步构造。
- 缺点:代码量增加,产品需高度相似。
5. 原型模式(Prototype)
定义
通过复制现有对象(原型)来创建新对象。
结构
- 原型接口:声明克隆方法(如
Cloneable) - 具体原型类:实现克隆方法(深拷贝/浅拷贝)
Java 实现
// 原型接口(Java 中 Cloneable 是标记接口)
class Shape implements Cloneable {
private String type;
public Shape(String type) { this.type = type; }
@Override
public Shape clone() {
try {
return (Shape) super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
public String getType() { return type; }
}
// 客户端调用
public class Client {
public static void main(String[] args) {
Shape circle = new Shape("Circle");
Shape clonedCircle = circle.clone();
System.out.println(clonedCircle.getType()); // 输出: Circle
}
}
适用场景
- 需要高性能创建相似对象(如游戏中的大量敌人克隆)
- 避免构造复杂对象的初始化逻辑
优缺点
- 优点:避免重复初始化,提升性能。
- 缺点:深拷贝实现复杂,可能破坏封装性(需访问私有字段)。
总结
- 单例:全局唯一实例。
- 工厂方法:子类决定对象类型。
- 抽象工厂:创建一族对象。
- 建造者:分步构造复杂对象。
- 原型:克隆已有对象。
最佳实践:
- 优先选择静态工厂方法(如
LocalDate.now())代替new。 - 使用枚举实现单例以避免反射攻击。
- 建造者模式适合构造参数多且可选的对象(如
StringBuilder)。 - 原型模式需谨慎处理深拷贝问题(推荐使用序列化或工具库如
Apache Commons)。