【设计模式】创建型设计模式

创建型设计模式

文章目录

  • 创建型设计模式
    • 一、概述
    • 二、单例模式
    • 三、工厂模式
      • 3.1 简单工厂模式(静态工厂模式)
      • 3.2 工厂方法模式
      • 3.3 抽象工厂模式
      • 3.3 工厂模式小结
    • 四、原型模式
    • 五、建造者模式

一、概述

这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

  • 单例模式(Singleton Pattern)
  • 工厂模式(Factory Pattern)
  • 抽象工厂模式(Abstract Factory Pattern)
  • 原型模式(Prototype Pattern)
  • 建造者模式(Builder Pattern)

二、单例模式

所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,让某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。

使用场景:需要频繁的进行创建和销毁的对象、创建对象时耗时过多或耗费资源过多(即:重量级对象),但又经常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源session 工厂等);Spring 默认注入对象都是单例模式的。

单例模式有多种实现方式,这里提供三种实现方式:

实现的选择:一般可用饿汉式,涉及反序列化用枚举,要求懒加载用静态内部类

  1. 饿汉式:无懒加载效果,缺点:无懒加载,无法防止反序列化
public class Singleton {
	private final static Singleton INSTANCE = new Singleton();
	private Singleton (){}
	public static Singleton getInstance() {
		return INSTANCE;
	}
}
  1. 枚举实现:确保了单例,且能防止反序列化,缺点:无法懒加载
public enum SingletonEnum {
	INSTANCE;
	public void func() {
		System.out.println("只能通过INSTANCE枚举执行我");
	}
}
  1. 静态内部类:确保多线程下也能保持单例懒加载,缺点:无法防止反序列化创建对象
public class Singleton {
	private Singleton() {}

	private static class SingletonHolder {
		private final static Singleton INSTANCE = new Singleton();
	}

	public static Singleton getInstance() {
		return SingletonHolder.INSTANCE;
	}
}

三、工厂模式

在工厂模式中,在创建对象时不会对调用方暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。

3.1 简单工厂模式(静态工厂模式)

看一个披萨项目:要便于披萨种类的扩展,要便于维护。

  1. 披萨的种类很多(比如 GreekPizza、CheesePizza 等)
  2. 披萨的制作有 prepare,bake, cut, box
  3. 完成披萨店订购功能PizzaOrder

传统方式:

【设计模式】创建型设计模式_第1张图片

	public void orderPizza(String type) {
		Pizza pizza = null;
		if ("greek".equals(type)) {
			pizza = new GreekPizza();
		} else if ("cheese".equals(type)) {
			pizza = new CheesePizza();
		} else if ("paper".equals(type)) {
			pizza = new PepperPizza();
		} else {
			throw new RuntimeException("No such pizza!");
		}
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
	}

上面设计违反了开闭原则,当需要增加一个披萨种类时,调用端也必须修改代码增加判断逻辑。用简单工厂模式实现,则可以将调用方与披萨接口的实现解耦,代码如下,此时增加品种,调用方也无需修改代码。

public class PizzaFactory {
	public static Pizza getPizza(String type) {
		Pizza pizza = null;
		if ("greek".equals(type)) {
			pizza = new GreekPizza();
		} else if ("cheese".equals(type)) {
			pizza = new CheesePizza();
		} else if ("paper".equals(type)) {
			pizza = new PepperPizza();
		} else {
			throw new RuntimeException("No such pizza!");
		}
		return pizza;
	}
}
	public void orderPizza(String type) {
		Pizza pizza = PizzaFactory.getPizza(type);
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
	}

3.2 工厂方法模式

披萨项目新的需求:客户在点披萨时,可以点不同口味的披萨,比如 北京的奶酪 pizza、北京的胡椒 pizza 或者是伦敦的奶酪 pizza、伦敦没有胡椒 pizza。

传统方式:将工厂分为北京的和伦敦的,分别生产不同口味的披萨

工厂方法模式:在上个工厂类中,新增两个方法,分别代表北京的披萨和伦敦的披萨,对应方法中再创建不同口味的实现类,这种方式即工厂方法模式。

3.3 抽象工厂模式

模式如其名,抽象工厂即超级工厂,用来进行统一工厂的创建,将分类进一步解耦。

【设计模式】创建型设计模式_第2张图片

3.3 工厂模式小结

注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

四、原型模式

原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。需要克隆一个对象时,尽量不要创建新的对象,然后一个个设置值。

  1. Java中可以通过实现Cloneable接口,复写clone方法调用父类Object中的clone方法实现,注意:这种方式对于该类中引用数据类型会进行浅拷贝
  2. 通过序列化与反序列化的方式深拷贝克隆原型对象

【设计模式】创建型设计模式_第3张图片

原理结构图说明

  1. Prototype : 原型类,声明一个克隆自己的接口
  2. ConcretePrototype: 具体的原型类, 实现一个克隆自己的操作
  3. Client: 让一个原型对象克隆自己,从而创建一个新的对象(属性一样)

五、建造者模式

建造者模式(Builder Pattern) 又叫生成器模式,是一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。

建造者模式 是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。

主要解决在软件系统中,有时候面临着 “一个复杂对象” 的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

【设计模式】创建型设计模式_第4张图片

原理图中,创建过程由 Director 指定,也就是构建 Builder 的整体流程被抽象出来了,当需要根据情况,先执行 C 再执行 B时,只需要更改 Director 中的执行顺序即可。

你可能感兴趣的:(设计模式,设计模式)