创建型设计模式是处理对象创建的设计模式,主要特点是"将对象的创建与业务代码分离"。一共有五种:工厂方法模式、单例模式、原型模式、抽象工厂模式及建造者模式。
1 单例模式
需求:
- 在整个系统中只需要一个实例。
- 管理共享资源,例如数据库连接、配置文件读取等,可以减少资源消耗,提高性能。
1.1 单例模式介绍
确保某个类只有一个实例,自行实例化并且向整个系统提供这个实例。
图 单例模式UML
|------|------------------------------------------------------------------|
| 饿汉模式 | 在程序启动时就进行对象的实例化,单例对象会在类被加载时创建。实现简单、线程安全。但是无法进行懒加载,会带来一定的系统开销。 |
| 懒汉模式 | 类加载时不会创建单例对象,而是等到真正需要的时候才创建。懒汉模式第一次调用时才初始化,避免了内存浪费,但是需要注意线程安全问题。 |
| 枚举 | 实现单例的最佳方法,自动支持序列化机制、防止多次实例化并且线程安全。 |
图 实现单例模式的方式
public class HungryModel {
private HungryModel() {}
private final static HungryModel instance = new HungryModel();
public static HungryModel getInstance() {
return instance;
}
}
public class DoubleCheckLocking {
private DoubleCheckLocking() {}
private static DoubleCheckLocking instance = null;
public static DoubleCheckLocking getInstance() {
if (instance == null) {
synchronized (DoubleCheckLocking.class) {
if (instance == null) instance = new DoubleCheckLocking();
}
}
return instance;
}
}
public class IoDHSingleton {
private IoDHSingleton() {}
private static class Holder {
static final IoDHSingleton instance = new IoDHSingleton();
}
public static IoDHSingleton getInstance() {
return Holder.instance;
}
}
1.1.1 优缺点
**优点:**确保一个类在系统中只有一个实例,节约系统资源,提高性能。
**缺点:**不符合单一职责原则。
2 原型模式
需求:
- 需要频繁创建属性近似的对象。
- 需要保持对象在某个时刻的状态。
2.1 原型模式介绍
通过一个已存在的对象克隆出多个一摸一样的对象。
图 原型模式UML
public class Address implements Cloneable{
public Address() {}
@Override
public Address clone() throws CloneNotSupportedException {
return (Address)super.clone();
}
@Override
public String toString() {
return "Address(" + Integer.toHexString(hashCode()) + ")";
}
}
public class User implements Cloneable{
private List<Address> addressList;
public void setAddressList(List<Address> addressList) {
this.addressList = addressList;
}
@Override
public User clone() throws CloneNotSupportedException {
User clone = (User)super.clone();
if (addressList != null) {
List<Address> newList = new ArrayList<>();
for (Address address : addressList) {
newList.add(address.clone());
}
clone.setAddressList(newList);
}
return clone;
}
public static void main(String[] args) throws CloneNotSupportedException {
User user = new User();
List<Address> addresses = new ArrayList<>();
addresses.add(new Address());
addresses.add(new Address());
user.setAddressList(addresses);
User clone = user.clone();
System.out.println(user);
System.out.println(clone);
}
@Override
public String toString() {
return "User(" + Integer.toHexString(hashCode()) +"){" +
"addressList=" + addressList +
'}';
}
}
2.1.1 优缺点
**优点:**1)减少了代码量;2)可读性、可维护性好,耦合度减小。
**缺点:**2)不符合单一职责原则;2)不符合开闭原则。当对象添加新的属性时可能需要修改代码。
3 工厂方法模式
需求:
- 将对象创建与业务代码剥离。
- 让用户在不需要知道具体的类型情况下,创建符合的对象。
- 隐藏创建这个实例的创建细节。
3.1 工厂方法模式介绍
将对象的创建与自身的业务逻辑分离。定义一个有创建对象接口的工厂,把创建对应产品的细节封装在不同的工厂实现类中。每增加新的产品,只需增加该产品以及对应的工厂实现类。
图 工厂方法模式UML
public class Car {
private String engine;
protected Car(String engine) {
this.engine = engine;
}
}
public class BMWCar extends Car{
public BMWCar(String engine) {
super(engine);
}
}
public class TeslaCar extends Car{
public TeslaCar(String engine) {
super(engine);
}
}
public interface CarFactory {
Car buildCar();
}
public class BMWCarFactory implements CarFactory{
@Override
public Car buildCar() {
return new BMWCar("汽油发动机");
}
}
public class TeslaCarFactory implements CarFactory{
@Override
public Car buildCar() {
return new TeslaCar("电动发动机");
}
}
public class CarShop {
public static void main(String[] args) {
CarFactory carFactory = new BMWCarFactory();
carFactory.buildCar();
carFactory = new TeslaCarFactory();
carFactory.buildCar();
}
}
3.1.1 优缺点
**优点:**1)符合单一职责原则,可读性好。2)符合开闭原则,扩展性好。3)符合依赖倒置原则,耦合度降低。
**缺点:**类的数量增加,增加了系统的复杂性,可能会影响性能。