23种设计模式归纳总结——创建型
Posted 化作孤岛的瓜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了23种设计模式归纳总结——创建型相关的知识,希望对你有一定的参考价值。
目录
主要解决“对象的创建”问题,将创建和使用代码解耦
1.单例模式
1.饿汉式:
在类加载时进行实例的创建与初始化
public class IdGenerator
private AtomicLong id = new AtomicLong(0);
private static final IdGenerator instance = new IdGenerator();
private IdGenerator()
public static IdGenerator getInstance()
return instance;
public long getId()
return id.incrementAndGet();
2.懒汉式
用到的时候再进行实例的创建与初始化
public class IdGenerator
private AtomicLong id = new AtomicLong(0);
private static IdGenerator instance;
private IdGenerator()
public static synchronized IdGenerator getInstance()
if (instance == null)
instance = new IdGenerator();
return instance;
public long getId()
return id.incrementAndGet();
3.双重检测
既支持延迟加载、又支持高并发的单例实现方式
public class IdGenerator
private AtomicLong id = new AtomicLong(0);
private static IdGenerator instance;
private IdGenerator()
public static IdGenerator getInstance()
if (instance == null)
synchronized(IdGenerator.class) // 此处为类级别的锁
if (instance == null)
instance = new IdGenerator();
return instance;
public long getId()
return id.incrementAndGet();
4.静态内部类
比双重检测更简单的方式,利用静态内部类实现,SingletonHolder 是一个静态内部类,当外部类IdGenerator被加载的时候,并不会创建SingletonHolder实例对象。只有当调用getInstance()方法时,SingletonHolder才会被加载,这个时候才会创建instance。instance的唯一性、创建过程的线程安全性,都由JVM来保证。
public class IdGenerator
private AtomicLong id = new AtomicLong(0);
private IdGenerator()
private static class SingletonHolder
private static final IdGenerator instance = new IdGenerator();
public static IdGenerator getInstance()
return SingletonHolder.instance;
public long getId()
return id.incrementAndGet();
5.枚举
最简单的完美方式
public enum IdGenerator
INSTANCE;
private AtomicLong id = new AtomicLong(0);
public long getId()
return id.incrementAndGet();
2.工厂模式
1.简单工厂
通过if else或者switch case创建同一基类的不同子类实现
//抽象类,汽车
public abstract class Car
public abstract void run();
//宝马
public class BMWCar extends Car
private String name;
public BMWCar(String name)
this.name = name;
@Override
public void run()
System.out.println(this.name);
//玛莎拉蒂
public class MaseratiCar extends Car
private String name;
public MaseratiCar(String name)
this.name = name;
@Override
public void run()
System.out.println(this.name);
//简单工厂
public class CarFactory
public static Car createCar(String brand)
Car car = null;
switch (brand)
case "maserati": // 玛莎拉蒂
car = new MaseratiCar(brand);
break;
case "bmw": // 宝马
car = new BMWCar(brand);
break;
return car;
2.工厂方法
如果每一个子类实例创建过程复杂,讲创建过程抽象为一个工厂,将复杂逻辑写在创建工厂类里,并通过聚合(工厂的工厂)来统一处理这些工厂类的创建。
当对象的创建逻辑比较复杂,不只是简单的new一下就可以,而是要组合其他类对象,做各种初始化操作的时候,我们推荐使用工厂方法模式,将复杂的创建逻辑拆分到多个工厂类中,让每个工厂类都不至于过于复杂。
//汽车
public static abstract class Car
public abstract void run();
//宝马
public static class BMWCar extends Car
private String name;
public BMWCar(String name)
this.name = name;
@Override
public void run()
System.out.println(this.name);
//汽车工厂
public interface ICarFactory
Car createCar(String name);
//宝马汽车工厂
public static class BWCarFactory implements ICarFactory
@Override
public Car createCar(String name)
//做一些专属于宝马的复杂事情
return new BMWCar(name);
public static class CarFactoryMap //工厂的工厂
private static final Map<String, ICarFactory> cachedFactories = new HashMap<>();
static
cachedFactories.put("bw", new BWCarFactory());
public static ICarFactory getParserFactory(String type)
if (type == null || type.isEmpty())
return null;
ICarFactory parserFactory = cachedFactories.get(type.toLowerCase());
return parserFactory;
public static void main(String[] args)
String brand = "bw";
ICarFactory carFactory = CarFactoryMap.getParserFactory(brand);
Car car = carFactory.createCar(brand);
car.run();
3.抽象工厂
可以把它理解成创建工厂的工厂
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
//电脑产品接口
public interface IComputerProduct
void start();
void shutdown();
//A电脑
public class AComputer implements IComputerProduct
@Override
public void start()
System.out.println("开启A电脑");
@Override
public void shutdown()
System.out.println("关闭A电脑");
//电视机产品接口
public interface ITVProduct
void start();
void shutdown();
//A电视
public class ATV implements ITVProduct
@Override
public void start()
System.out.println("开启A电视");
@Override
public void shutdown()
System.out.println("关闭A电视");
//抽象产品工厂
public interface IProductFactory
//生产电脑
IComputerProduct iComputerProduct();
//生产电视
ITVProduct itvProduct();
public class AFactory implements IProductFactory
@Override
public IComputerProduct iComputerProduct()
return new AComputer();
@Override
public ITVProduct itvProduct()
return new ATV();
3.Builder模式
解决问题:1.某些参数必须要填,或者存在其他约束关系,set和get无法解决 2.防止构造方法膨胀 3.set方法不适合暴露
可以在build方法中做集中的参数校验,防止出错。
public class ResourcePoolConfig
private String name;
private int maxTotal;
private ResourcePoolConfig(Builder builder)
this.name = builder.name;
this.maxTotal = builder.maxTotal;
//...省略getter方法...
//我们将Builder类设计成了ResourcePoolConfig的内部类。
//我们也可以将Builder类设计成独立的非内部类ResourcePoolConfigBuilder。
public static class Builder
private static final int DEFAULT_MAX_TOTAL = 8;
private String name;
private int maxTotal = DEFAULT_MAX_TOTAL;
public ResourcePoolConfig build()
// 校验逻辑放到这里来做,包括必填项校验、依赖关系校验、约束条件校验等
if (StringUtils.isBlank(name))
throw new IllegalArgumentException("...");
if (maxTotal < DEFAULT_MAX_TOTAL)
throw new IllegalArgumentException("...");
return new ResourcePoolConfig(this);
public Builder setName(String name)
if (StringUtils.isBlank(name))
throw new IllegalArgumentException("...");
this.name = name;
return this;
public Builder setMaxTotal(int maxTotal)
if (maxTotal <= 0)
throw new IllegalArgumentException("...");
this.maxTotal = maxTotal;
return this;
4.原型模式
如果对象的创建成本比较大(对象中的数据需要经过复杂的计算才能得到(比如排序、计算哈希值),或者需要从RPC、网络、数据库、文件系统等非常慢速的IO中读取),而同一个类的不同对象之间差别不大(大部分字段都相同),在这种情况下,我们可以利用对已有对象(原型)进行复制(或者叫拷贝)的方式来创建新对象,以达到节省创建时间的目的。这种基于原型来创建对象的方式就叫作原型设计模式(Prototype Design Pattern),简称原型模式。
浅拷贝和深拷贝的区别在于,浅拷贝只会复制图中的索引(散列表),不会复制数据(SearchWord对象)本身。相反,深拷贝不仅仅会复制索引,还会复制数据本身。
// 定义Food类
class Food
String food;
// get set ...
public Food(String food)
this.food = food;
// 定义Student类
class Student implements Cloneable // Cloneable接口
@Override
public Object clone() throws CloneNotSupportedException // 提升访问权限
Student student = (Student) super.clone();
//针对成员变量进行拷贝
student.name = new String(name);
student.food = new Food(food.getFood());
return student;
private Food food;
private String name;
int age;
public Student()
public Student(String name, int age, Food food)
this.name = name;
this.age = age;
this.food = food;
//get set..
//测试
Food food = new Food("apple");
System.out.println(food); // JavaPackage_1.Food@6d311334
//Java深拷贝,对内层的对象也进行拷贝。
Student student1 = new Student("stu", 29,food);
// 通过student1克隆student2,不通过new对象的形式创建
Student student2 = (Student) student1.clone();
System.out.println(student1); // JavaPackage_1.Student@3d075dc0
System.out.println(student2); // JavaPackage_1.Student@214c265e
System.out.println(student1==student2); // false,student1和student2指向的是不同地址
System.out.println(student1.getFood()); // JavaPackage_1.Food@6d311334
System.out.println(student2.getFood()); // JavaPackage_1.Food@448139f0
System.out.println(student1.getFood()==student2.getFood()); // false,student1.food和student2.food指向不同地址
food.setFood("orange");
System.out.println(student1.getFood().getFood()); // orange
System.out.println(student2.getFood().getFood()); // apple
以上是关于23种设计模式归纳总结——创建型的主要内容,如果未能解决你的问题,请参考以下文章