设计模式之工厂模式

设计模式之工程设计模式

工厂设计模式介绍

  • 它提供了一种创建对象的最佳方式,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

  • 例子:

    • 需要购买一辆车,不用管车辆如何组装,且可以购买不同类型的比如轿车、SUV、跑车,直接去4S店购买就行(4S店就是工厂)
    • 工厂生产电脑,除了A品牌、还可以生产B、C、D品牌电脑
    • 业务开发中,支付很常见,里面有统一下单和支付接口,具体的支付实现可以微信、支付宝、银行卡等
  • 工厂模式有3种不同的实现方式

    • 简单工厂模式:通过传入相关的类型来返回相应的类,这种方式比较单一,可扩展性相对较差
    • 工厂方法模式:通过实现类实现相应的方法来决定相应返回结果,这种方法的可扩展性比较强
    • 抽象工厂模式:基于上诉两种模式的拓展,且支持细化产品
  • 应用场景:

    • 解耦:分离职责,把复杂对象的创建和使用的过程分开
    • 复用代码 降低维护成本:
      • 如果对象创建复杂且多处需用到,如果每处都进行编写,则很多重复代码,如果业务逻辑发生了改变,需要四处修改
      • 使用工厂模式统一创建,则只要修改工厂类即可,降低成本

简单工厂模式

介绍

  • 又称静态工厂方法,可以根据参数的不同返回不同类的实例,专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类
  • 由于工厂方法是静态方法,可通过类名直接调用,而且只需要传入简单的参数即可

核心组成

  • Factory:工厂类,简单工厂模式的核心,它负责实现创建所有实例的内部逻辑
  • IProduct:抽象产品类,简单工厂模式所创建的所有对象的父类,描述所有实例所共有的公共接口
  • Product:具体产品类,是简单工厂模式的创建目标

实现步骤

  • 创建抽象产品类,里面有产品的抽象方法,有具体的产品类去实现
  • 创建具体产品类,继承了他们的父类,并实现具体方法
  • 创建工厂类,提供了一个静态方法createXXX用来生产产品,只需要传入你想的产品名称

优点

  • 将对象的创建和对象本身业务处理分离可以降低系统的耦合度,市两者修改起来都相对容易。
    缺点
  • 工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原则是相违背的。
  • 即开闭原则 对外扩展开放,对修改关闭,程序需要进行扩展的时候,不能去修改原有代码,实现一个热插拔的效果。
  • 将会增加系统中类的个数,在一定程度上增加了系统的复杂度和理解难度,不利于系统的扩展和维护,创建简单对象不需要模式

工厂方法模式

介绍

  • 又称工厂模式,是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则
  • 通过工厂父类定义负责创建产品的公共接口,通过子类来确定所需要创建的类型
  • 相比简单工厂而言,此方法具有更多的可扩展性和复用性,同时也增加了代码的可读性
  • 将类的实例化延迟到工厂类的子类中完成,即由子类来决定应该实例化哪个类
    核心组成
  • IProduct:抽象产品类,描述所有实例化共有的公共接口
  • Product:具体产品类,实现抽象产品类的接口,工厂类创建对象,如果有多个需要定义多个
  • IFactory:抽象工厂类,描述具体工厂的公共接口
  • Factory:具体工厂类,实现创建产品类对象,实现抽象工厂类的接口,如果有多个需要定义多个

    编码实战
/**
*抽象工厂方法
*/
public interface PayFactory{
	Pay getPay();
}
/**
*具体产品工厂
*/
public class AliPayFactory implements PayFactory{

	@Override
	public Pay getPay(){
		return new AliPay();
	}

}
/**
*抽象产品
*/
public interface Pay{
//统一下单
void unifiedorder();

}
/**
*具体产品
*/
public class AliPay implements Pay{

	@Override
	public void unifiedorder(){
		System.out.printIn("支付宝支付 统一下单接口");
	}

}


优点

  • 符合开闭原则,增加一个产品类,只需要实现其他具体的产品类和具体的工厂类;
  • 符合单一职责原则,每个工厂只负责生产对应的产品
  • 使用者只需要知道产品的抽象类,无须关心其他实现类,满足迪卡特法则、依赖倒置原则和里氏替换原则
    • 迪米特法则:最少知道原则,实体应当尽量少地与其他实体之间发生相互作用。
    • 依赖倒置原则:针对接口编程,依赖与抽象而不依赖于具体
    • 里氏替换原则:任何基类可以出现的地方,子类一定可以出现,对实现抽象化的具体步骤的规范

缺点

  • 增加一个产品,需要实现对应的具体工厂类和具体产品类
  • 每个产品需要有相应的具体工厂和具体产品类

抽象工厂模式

介绍

  • 基于上述两种模式的拓展,是工厂方法模式的升级版,当需要创建的产品有多个产品线时使用,抽象工厂模式是比较好的选择

  • 抽象工厂模式在spring中应用最为广泛的一种设计模式

背景

  • 工厂方法模式引入工厂等级结构,解决了简单工厂模式中工厂类职责过重的问题
  • 但工厂方法模式中每个工厂只创建一类具体类的对象,后续发展可能会导致工厂类过多,因此将一些相关的具体类组成一个具体类族,由同一个工厂来统一生产,强调的是一系列相关的产品对象。

    实现步骤
    1、定义两个接口Pay、Refund
    2、创建具体的Pay产品、创建具体的Refund产品
    3、创建抽象工厂 OrderFactory 接口
    里面两个方法 createPay/createRefund
    4、创建支付宝产品族AliOrderFactory,实现OrderFactory抽象工厂
    5、创建微信支付产品族WechatOrderFactory,实现OrderFactory抽象工厂
    6、定义一个超级工厂创造器,通过传递参数获取对应的工厂
    编码实战
/**
* 超级⼯厂,定义同个产品族的其他相关子工厂
*/
public interface OrderFactory {

	PayFactory createPay();
	RefundFactory createRefund();
	
}

//产品族⼯厂的产品
public interface PayFactory {
	/**
	* 统一下单
	*/
	void unifiedorder();
}
//产品族⼯厂
public class AliOrderFactory implements OrderFactory {
	@Override
	public PayFactory createPay() {
		return new AliPay();
	}
	
	@Override
	public RefundFactory createRefund() {
		return new AliRefund();
	}
}
//具体产品
public class AliPay implements PayFactory {
	@Override
	public void unifiedorder() {
		System.out.println("⽀付宝支付 统⼀下单接⼝");
	}
}
//超级⼯⼚⽣产器,传参⽣生产对应的⼦⼯厂
public class FactoryProducer {
	public static OrderFactory getFactory(String type){
		if (type.equalsIgnoreCase("WECHAT")) {
			return new WechatOrderFactory();
		} else if(type.equalsIgnoreCase("ALI")) {
			return new AliOrderFactory();
		}
		return null;
	}
}
//Main函数使⽤
OrderFactory orderFactory = FactoryProducer.getFactory("ALI");
orderFactory.createPay().unifiedorder();
orderFactory.createRefund().refund()

工厂方法模式和抽象工厂方法模式

  • 当抽象工厂模式中每个具体工厂类只创建一个产品对象,抽象工厂模式退化成工厂方法模式

优点

  • 当一个产品族中多个对象被设计成一起工作时,它能保证使用方始终只使用同一个产品族中的对象
  • 产品等级结构扩展容易,如果需要增加多个一个产品等级,只需要增加新的工厂类和产品类即可,比如增加退款

缺点

  • 产品族扩展困难,要增加一系列的某个产品,既要在抽象的工厂和抽象产品里修改代码,不是符合开闭原则
  • 增加了系统的抽象性和理解难度
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值