目录
🎗️1.工厂模式介绍
🎞️2.简单工厂模式
🎟️3.工厂方法模式
🎠5.测试
1.工厂模式介绍
- 1.工厂模式属于创建型模式,它提供了一种创建对象的最佳方式,它在创建对象时提供了一种封装机制,将实际创建对象的代码与使用代码分离。
- 2.工厂模式有三种不同的实现方式:
- 简单工厂模式:通过传入相关的类型来返回相应的类,这种方式比较单一,可扩展性相对较差;
- 工厂方法模式:通过实现类实现相应的方法来决定相应的返回结果,这种方式的可扩展性比较强;
- 抽象工厂模式:基于上述两种模式的拓展,且支持细化产品
- 应用场景
- 解耦**:分离职责,把复杂对象的创建和使用的过程分开**
- 复用代码降低维护成本**:**
- 如果对象创建复杂且多处需用到,如果每处都进行编写,则很多重复代码,如果业务逻辑发生了改变,需用四处修改;
- 使用工厂模式统一创建,则只要修改工厂类即可,降低成本;
- 优点
- 1、一个调用者想创建一个对象,只要知道其名称就可以了。
- 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
- 3、屏蔽产品的具体实现,调用者只关心产品的接口。
- 缺点
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
2.简单工厂模式
- 又称静态工厂方法,可以根据参数的不同返回不同类的实例,专门定义一个类来负责创建其他类的实例。被创建的实例通常都具有共同的父类
- 由于工厂方法是静态方法,可通过类名直接调用,而且只需要传入简单的参数即可
- 核心角色
- Factory:工厂类,简单工厂模式的核心,它负责实现创建所有实例的内部逻辑
- IProduct:抽象产品类,简单工厂模式所创建的所有对象的父类,描述所有实例所共有的公共接口。
- Product:具体产品类,是简单工厂模式的创建目标
2.1支付模拟
- 1.创建支付接口
java
/**
* 统一支付接口
*/
public interface Pay {
/**
* 统一支付接口
*/
void unifiedOrder();
}
- 2.创建微信支付实现类
java
/**
* 微信支付
*/
public class WeChatPay implements Pay {
@Override
public void unifiedOrder() {
System.out.println("微信支付~");
}
}
- 3.支付接调用类
java
/**
* 简单工厂模式
*/
public class SimplePayFactory {
/**
* 根据类型选择支付
* @param payType
*/
public static Pay toPay(String payType){
if (payType==null){
return null;
}
if (payType.equals("WeChat_PAY")){
return new WeChatPay();
}
if (payType.equals("Ali_PAY")){
return new AliPay();
}
return null;
}
}
- 优点
将对象的创建和对象本身业务处理分离可以降低系统的耦合度,使得两者修改起来都相对容易。
- 缺点
- 工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原则是相
- 违背即开闭原则(Open Close Principle)对扩展开放,对修改关闭,程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果
- 将会增加系统中类的个数,在一定程度上增加了系统的复杂度和理解难度,不利于系统的扩展和维护,创建简单对象就不用模式
3.工厂方法模式
- 又称工厂模式,是对简单工厂模式的进一步抽象化
- 其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则
- 通过工厂父类定义负责创建产品的公共接口,通过子类来确定所需要创建的类型
- 相比简单工厂而言,此种方法具有更多的可扩展性和复用性,同时也增强了代码的可读性
- 将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化哪一个类。
- 核心角色
- 1.IProduct:抽象产品类,描述所有实例所共有的公共接口
- 2.Product:具体产品类,实现抽象产品类的接口,工厂类创建对象,如果有多个需要定义多个
- 3.IFactory:抽象工厂类,描述具体工厂的公共接口
- 4.Factory:具体工场类,实现创建产品类对象,实现抽象工厂类的接口,如果有多个需要定义多个
3.1支付模拟
- 1.创建支付接口
java
/**
* 统一支付接口
*/
public interface Pay {
/**
* 统一支付接口
*/
void unifiedOrder();
}
- 2.创建微信支付实现类
java
/**
* 微信支付
*/
public class WeChatPay implements Pay {
@Override
public void unifiedOrder() {
System.out.println("微信支付~");
}
}
- 3.创建抽象工厂
java
/**
* 抽象工厂类
*/
public interface FactoryPatten {
/**
* 调用具体的支付方式
* @return
*/
Pay getPay();
}
- 4.创建微信支付工厂
java
/**
* 微信支付具体实现类
*/
public class WeChatFactory implements FactoryPatten{
/**
* 创建微信支付支付对象
* @return
*/
@Override
public Pay getPay() {
return new WeChatPay();
}
}
- 5.创建支付宝支付工厂
java
/**
* 支付宝具体实现类
*/
public class AliPayFactory implements FactoryPatten{
/**
* 创建支付宝支付对象
* @return
*/
@Override
public Pay getPay() {
return new AliPay();
}
}
- 优点
- 1.符合开闭原则,增加一个产品类,只需要实现其他具体的产品类和具体的工厂类;
- 2.符合单一职责原则,每个工厂只负责生产对应的产品;
- 3.使用者只需要知道产品的抽象类,无须关心其他实类,满足迪米特法则、依赖倒置原则和里氏替换原则;
- 迪米特法则:最少知道原则,实体应当尽量少地与其他实体之间发生相互作用
- 依赖倒置原则:针对接口编程,依赖于抽象而不依赖于具体
- 里氏替换原则:俗称LSP,任何基类可以出现的地方,子类一定可以出现,对实现抽象化的具体步骤的规范
- 缺点
- 增加一个产品,需要实现对应的具体工厂类和具体产品类;
- 每个产品需要有对应的具体工厂和具体产品类
4.抽象工厂方法模式
- 1.抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂
- 2.抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体实现类。
- 3.通过使用抽象工厂模式,可以将客户端与具体产品的创建过程解耦,使得客户端可以通过工厂接口来创建一族产品。
- 4.在一个产品族里面,定义多个产品,在一个工厂里聚合多个同类产品
4.1支付模拟
- 1.创建支付工厂接口
java
/**
* 支付接口
*/
public interface PayFactory {
/**
* 统一支付接口
*/
void unifiedOrder();
}
- 2.创建退款工厂接口
java
/**
* 退款接口
*/
public interface RefundFactory {
/**
* 退款接口
*/
void getRefund();
}
- 3.创建订单接口,管理支付工厂合退款工厂
java
/**
* 订单接口,包括支付退和款
*/
public interface OrderFactory {
/**
* 创建支付
* @return
*/
PayFactory createPay();
/**
* 创建退款
* @return
*/
RefundFactory createRefund();
}
- 4.创建微信支付实现工厂
java
/**
* 具体的微信支付实现类
*/
public class WeChatPay_a implements PayFactory {
@Override
public void unifiedOrder() {
System.out.println("支付宝支付~");
}
}
- 5.创建微信退款实现工厂
java
/**
* 微信退款实现类
*/
public class WeChatRefund_a implements RefundFactory {
@Override
public void getRefund() {
System.out.println("微信退款~");
}
}
- 6.创建微信订单实现工厂
java
/**
* 微信订单具体实现类
*/
public class WeChatOrder implements OrderFactory {
//创建支付
@Override
public PayFactory createPay() {
return new WeChatPay_a();
}
//创建退款
@Override
public RefundFactory createRefund() {
return new WeChatRefund_a();
}
}
- 7.创建支付宝支付实现工厂
java
/**
* 具体的支付宝支付实现类
*/
public class AliPay_a implements PayFactory {
@Override
public void unifiedOrder() {
System.out.println("支付宝支付~");
}
}
- 8.创建支付宝退款实现工厂
java
/**
* 具体的支付宝退款实现类
*/
public class AliRefund implements RefundFactory {
@Override
public void getRefund() {
System.out.println("支付宝退款~");
}
}
- 9.创建支付宝订单实现工厂
java
/**
* 支付宝订单具体实现类
*/
public class AliOrder implements OrderFactory {
//创建支付
@Override
public PayFactory createPay() {
return new AliPay_a();
}
//创建退款
@Override
public RefundFactory createRefund() {
return new AliRefund();
}
}
- 10.创建超级工厂,实现具体的订单方式
java
/**
*超级工厂创造器
*/
public class FactoryProduct {
public static OrderFactory getFactory(String type){
if (type==null){
return null;
}
if (type.equals("WeChat")){
return new WeChatOrder();
}else if (type.equals("Ali")){
return new AliOrder();
}
return null;
}
}
- 优点
当一个产品族中的多个对象被设计成一起工作时,它能保证使用方始终只使用同一个产品族中的对象
- 缺点
- 产品族扩展困难,要增加一个系列的某一产品,既要在抽象的工厂和抽象产品里修改代码,又要在具体的里面加产品里加代码,不是很符合开闭原则
- 增加了系统的抽象性和理解难度
5.测试
java
/**
* 测试实现
*/
public class MyTest {
public static void main(String[] args) {
/**
* 根据不同的支付类型,调用相应的接口实现类
*/
System.out.println("=======简单工厂模式=======");
Pay pay1 = SimplePayFactory.toPay("Ali_PAY");
Pay pay2 = SimplePayFactory.toPay("WeChat_PAY");
pay1.unifiedOrder();
pay2.unifiedOrder();
System.out.println("=======简单工厂模式=======");
System.out.println("+++++++++++++++++++++++++++++++++++++");
System.out.println("=======工厂模式=======");
//调用支付宝支付
FactoryPatten aliPayFactory = new AliPayFactory();
Pay aliPay = aliPayFactory.getPay();
aliPay.unifiedOrder();
//调用微信支付
WeChatFactory weChatFactory = new WeChatFactory();
Pay weChatPay = weChatFactory.getPay();
weChatPay.unifiedOrder();
System.out.println("=======工厂模式=======");
System.out.println("=======抽象工厂模式=======");
OrderFactory ali = FactoryProduct.getFactory("Ali");
ali.createPay().unifiedOrder();
ali.createRefund().getRefund();
OrderFactory weChat = FactoryProduct.getFactory("WeChat");
weChat.createPay().unifiedOrder();
weChat.createRefund().getRefund();
System.out.println("=======抽象工厂模式=======");
}
}