创建型模式主要解决对象的创建问题,封装复杂的创建过程,解耦对象的创建代码和使用代码。

  • 单例模式用来创建全局唯一的对象。
  • 工厂模式用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象。
  • 建造者模式是用来创建复杂对象,可以通过设置不同的可选参数,“定制化”地创建不同的对象。
  • 原型模式针对创建成本比较大的对象,利用对已有对象进行复制的方式进行创建,以达到节省创建时间的目的。


单例模式

构造单例时考虑的问题:

  • 构造函数需要是 private 访问权限的,这样才能避免外部通过 new 创建实例;
  • 考虑对象创建时的线程安全问题;
  • 考虑是否支持延迟加载;
  • 考虑 getInstance() 性能是否高(是否加锁)。

饿汉式

  1. /**
  2. * 饿汉式单例
  3. *
  4. * @author xinzhang
  5. * @date 2021/1/29 11:13
  6. */
  7. public class HungrySingleton {
  8. private static final HungrySingleton INSTANCE = new HungrySingleton();
  9. private HungrySingleton() {
  10. }
  11. public static HungrySingleton getInstance() {
  12. return INSTANCE;
  13. }
  14. }

懒汉式

  1. /**
  2. * 懒汉式单例
  3. *
  4. * @author xinzhang
  5. * @date 2021/1/29 11:16
  6. */
  7. public class LazySingleton {
  8. private static LazySingleton instance;
  9. private LazySingleton() {
  10. }
  11. public static synchronized LazySingleton getInstance() {
  12. if (instance == null) {
  13. instance = new LazySingleton();
  14. }
  15. return instance;
  16. }
  17. }

双重检测

  1. /**
  2. * 双重检查单例
  3. *
  4. * @author xinzhang
  5. * @date 2021/1/29 11:18
  6. */
  7. public class DoubleCheckSingleton {
  8. private static volatile DoubleCheckSingleton instance;
  9. private DoubleCheckSingleton() {
  10. }
  11. public static DoubleCheckSingleton getInstance() {
  12. if (instance == null) {
  13. synchronized (DoubleCheckSingleton.class) {
  14. if (instance == null) {
  15. instance = new DoubleCheckSingleton();
  16. }
  17. }
  18. }
  19. return instance;
  20. }
  21. }

静态内部类

  1. /**
  2. * 静态内部类单例
  3. *
  4. * @author xinzhang
  5. * @date 2021/1/29 11:20
  6. */
  7. public class StaticInnerClassSingleton {
  8. private static class InnerClassSingleton {
  9. private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
  10. }
  11. public static StaticInnerClassSingleton getInstance() {
  12. return InnerClassSingleton.INSTANCE;
  13. }
  14. }

枚举

  1. /**
  2. * @author xinzhang
  3. * @date 2021/1/29 11:22
  4. */
  5. public enum EnumSingleton {
  6. INSTANCE;
  7. public EnumSingleton getInstance() {
  8. return INSTANCE;
  9. }
  10. }

工厂模式

太简单, 略

建造者模式

建造者模式使用场景:
1)类的构造函数必填属性很多,通过set设置,没有办法校验必填属性
2)如果类的属性之间有一定的依赖关系,构造函数配合set方式,无法进行依赖关系和约束条件校验
3)需要创建不可变对象,不能暴露set方法。
(前提是需要传递很多的属性,如果属性很少,可以不需要建造者模式)

  1. public class ResourcePoolConfig {
  2. private String name;
  3. private int maxTotal;
  4. private int maxIdle;
  5. private int minIdle;
  6. private ResourcePoolConfig(Builder builder) {
  7. this.name = builder.name;
  8. this.maxTotal = builder.maxTotal;
  9. this.maxIdle = builder.maxIdle;
  10. this.minIdle = builder.minIdle;
  11. }
  12. //...省略getter方法...
  13. //我们将Builder类设计成了ResourcePoolConfig的内部类。
  14. //我们也可以将Builder类设计成独立的非内部类ResourcePoolConfigBuilder。
  15. public static class Builder {
  16. private static final int DEFAULT_MAX_TOTAL = 8;
  17. private static final int DEFAULT_MAX_IDLE = 8;
  18. private static final int DEFAULT_MIN_IDLE = 0;
  19. private String name;
  20. private int maxTotal = DEFAULT_MAX_TOTAL;
  21. private int maxIdle = DEFAULT_MAX_IDLE;
  22. private int minIdle = DEFAULT_MIN_IDLE;
  23. public ResourcePoolConfig build() {
  24. // 校验逻辑放到这里来做,包括必填项校验、依赖关系校验、约束条件校验等
  25. if (StringUtils.isBlank(name)) {
  26. throw new IllegalArgumentException("...");
  27. }
  28. if (maxIdle > maxTotal) {
  29. throw new IllegalArgumentException("...");
  30. }
  31. if (minIdle > maxTotal || minIdle > maxIdle) {
  32. throw new IllegalArgumentException("...");
  33. }
  34. return new ResourcePoolConfig(this);
  35. }
  36. public Builder setName(String name) {
  37. if (StringUtils.isBlank(name)) {
  38. throw new IllegalArgumentException("...");
  39. }
  40. this.name = name;
  41. return this;
  42. }
  43. public Builder setMaxTotal(int maxTotal) {
  44. if (maxTotal <= 0) {
  45. throw new IllegalArgumentException("...");
  46. }
  47. this.maxTotal = maxTotal;
  48. return this;
  49. }
  50. public Builder setMaxIdle(int maxIdle) {
  51. if (maxIdle < 0) {
  52. throw new IllegalArgumentException("...");
  53. }
  54. this.maxIdle = maxIdle;
  55. return this;
  56. }
  57. public Builder setMinIdle(int minIdle) {
  58. if (minIdle < 0) {
  59. throw new IllegalArgumentException("...");
  60. }
  61. this.minIdle = minIdle;
  62. return this;
  63. }
  64. }
  65. }
  66. // 这段代码会抛出IllegalArgumentException,因为minIdle>maxIdle
  67. ResourcePoolConfig config = new ResourcePoolConfig.Builder()
  68. .setName("dbconnectionpool")
  69. .setMaxTotal(16)
  70. .setMaxIdle(10)
  71. .setMinIdle(12)
  72. .build();

原型模式

基于原型来创建对象的方式就叫作原型设计模式,简称原型模式。
比如clone()方法