常见设计模式三:工厂模式

前言

前面分别介绍了单例模式和构造者模式,实际开发中,这两个模式的使用概率是很高的,还有一个使用率很高的设计模式就是工厂模式。
今天来了解下工厂模式,工厂模式属于创建性模式的一种,而工厂模式本身又被大家分为三种:

  1. 简单工厂模式
  2. 工厂方法模式
  3. 抽象工厂模式

一、简单工厂模式

简单工厂模式其实更多的是我们平时开发过程中的一个开发习惯,比如在一个类中提供一个静态方法,根据传递进来的不同参数,返回具体的对象。

下面以手机支付为例做说明。

抽象支付功能:

public interface IPay {
    void pay(Double money);
}

具体实现ApplePay 和 HuaWeiPay:

public class ApplePay implements IPay {
    @Override
    public void pay(Double money) {
        System.out.println("使用 ApplePay 支付了 " + money + "元");
    }
}

public class HuaWeiPay implements IPay {
    @Override
    public void pay(Double money) {
        System.out.println("使用 HuaWeiPay 支付了 " + money + "元");
    }
}

获取支付方式的工厂:

public class PayFactory {
    public static IPay getPay(String pay) {
        switch (pay) {
            case "huawei":
                return new HuaWeiPay();
            case "apple":
                return new ApplePay();
            default:
                return new ApplePay();
        }
    }
}

测试类:

public class PayMain {
    public static void main(String[] args) {
        IPay pay = PayFactory.getPay("apple");
        pay.pay(1000d);
        pay = PayFactory.getPay("huawei");
        pay.pay(5000d);
    }
}

结果:

可以看到:在支付工厂中提供了一个静态方法,根据传入的支付类型的不同,返回了不同的支付对象,用来完成最终的支付操作,这就是简单工厂模式,下面来看下工厂方法模式。

二、工厂方法模式

在工厂方法模式中,我们取消了统一创建对象的 PayFactory ,而是提供一个创建对象的抽象,把具体的创建任务交给具体的工厂,比如获取苹果支付的对象,用 ApplePayFactory ,获取华为支付的对象用 HuaWeiPayFactory

还以上面的获取支付对象为例:做出以下改变:

修改 PayFactory 为:

public interface PayFactory {
    IPay create();
}

创建 ApplePayFactory 、 HuaWeiPayFactory 用来分别创建 支付对象:

public class ApplePayFactory implements PayFactory {
    @Override
    public IPay create() {
        return new ApplePay();
    }
}

public class HuaWeiPayFactory implements PayFactory {
    @Override
    public IPay create() {
        return new HuaWeiPay();
    }
}

测试:

public class MethodFactoryMain {
    public static void main(String[] args) {
        IPay pay ;
        HuaWeiPayFactory huaWeiPayFactory = new HuaWeiPayFactory();
        pay = huaWeiPayFactory.create();
        pay.pay(1000d);

        ApplePayFactory applePayFactory = new ApplePayFactory();
        pay = applePayFactory.create();
        pay.pay(5000d);
    }
}

结果:

可以看到和简单工厂的主要区别就是,不再把所有的创建支付方式放在一个工厂类中,而是统一定义一个获取支付方式的工厂,然后由不同的支付 Pay 构建不同的工厂,比如华为支付工厂,苹果支付工厂。

在简单工厂模式下,如果我们想添加一个 Oppo 支付,那么就需要去改变 PayFactory 类,去增加一个类型判断,这样如果不利于项目代码的扩展和稳定性,

而在工厂方法下,只需要定义一个获取支付对象的工厂,由不同的厂家去定义自己的支付工厂,这样就算是添加一个 Oppo 支付,也只用创建 OppoPay 和 OppoPayFactory 就行,不用修改顶层的抽象:

public class OppoPay implements IPay {
    @Override
    public void pay(Double money) {
        System.out.println("使用 OppoPay 支付了 " + money + "元");
    }
}
public class OppoPayFactory implements PayFactory {
    @Override
    public IPay create() {
        return new OppoPay();
    }
}


public class MethodFactoryMain {
    public static void main(String[] args) {
        IPay pay;
        HuaWeiPayFactory huaWeiPayFactory = new HuaWeiPayFactory();
        pay = huaWeiPayFactory.create();
        pay.pay(1000d);

        ApplePayFactory applePayFactory = new ApplePayFactory();
        pay = applePayFactory.create();
        pay.pay(5000d);

        OppoPayFactory oppoPayFactory = new OppoPayFactory();
        pay = oppoPayFactory.create();
        pay.pay(7000d);
    }
}

结果:

可以看到,工厂方法模式在不影响原来代码的情况下,扩展性是很好的。

下面再来看下抽象工厂模式

三、抽象工厂模式

抽象工厂模式大概分为四种部分:

  1. AbstractFactory 抽象工厂,声明了一组创建对象的方法

  2. ConcreteFactory 工厂的具体实现,实现了在抽象工厂中声明的创建对象的方法,生成一组对象

  3. AbstractProduct 抽象产品,为每种对象声明接口,在其中声明了该对象具有的业务方法

  4. ConceteeProduct 具体产品,定义工厂要实现的对象。

下面还以支付为例。

我们知道,在不同手机平台上,分别于有不同的支付方式,比如

苹果手机有的支付方式:ApplyPay、支付宝、微信支付等等

HuaWei 手机有的支付方式:HuaWeiPay、支付宝、微信支付等等

大致分为两类:

  1. 手机支付(各种手机Pay)
  2. 软件支付(支付宝、微信等)

创建抽象产品:手机支付接口和软件支付接口:

public interface IPhonePay {
    void pay(Double money);
}
public interface ISoftPay {
    void pay(Double money);
}

创建抽象工厂:

public interface IPayFactory {
    IPhonePay createPhonePay();

    ISoftPay createSoftPay();
}

苹果和华为分别对 手机支付接口的实现:

public class ApplyPay implements IPhonePay {
    @Override
    public void pay(Double money) {
        System.out.println("苹果手机 使用手机支付了 " + money + "元");
    }
}

public class HuaWeiPay implements IPhonePay {
    @Override
    public void pay(Double money) {
        System.out.println("华为手机 使用手机支付了 " + money + "元");
    }
}

苹果和华为分别对 软件支付接口的实现:

public class AppleSoftPay implements ISoftPay {
    @Override
    public void pay(Double money) {
        System.out.println("苹果手机 使用软件(支付宝/微信)支付了 " + money + "元");
    }
}

public class HuaWeiSoftPay implements ISoftPay {
    @Override
    public void pay(Double money) {
        System.out.println("华为手机 使用软件(支付宝/微信)支付了 " + money + "元");
    }
}

苹果手机、华为对支付方式的实现,具体实现抽象工厂:

public class ApplyPayFactory implements IPayFactory {
    @Override
    public IPhonePay createPhonePay() {
        return new ApplyPay();
    }

    @Override
    public ISoftPay createSoftPay() {
        return new AppleSoftPay();
    }
}

public class HuaWeuPayFactory implements IPayFactory {
    @Override
    public IPhonePay createPhonePay() {
        return new HuaWeiPay();
    }

    @Override
    public ISoftPay createSoftPay() {
        return new HuaWeiSoftPay();
    }
}

测试类:

public class Main {
    public static void main(String[] args) {
        IPayFactory payFactory;

        payFactory = new ApplyPayFactory();
        payFactory.createPhonePay().pay(1000d);
        payFactory.createSoftPay().pay(2000d);
        
        payFactory = new HuaWeuPayFactory();
        payFactory.createPhonePay().pay(3000d);
        payFactory.createSoftPay().pay(4000d);
    }
}

结果:

可以看到在最后的使用中,我们只用分别针对苹果手机和华为手机创建支付工厂,然后就可以使用使用不同手机的各种支付功能,如果这个时候 Oppo 又来凑热闹,那么我们就可以单独创建 OppoPhonePay、OppoSoftPay、OppoPayFactory 就可以了。

其实经过和上面工厂方法的对比可以大致可以看出:

工厂方法模式是针对方法的工厂

抽象工厂模式是针对对象的工厂

工厂模式就讲到这里了,还是需要平时工作中仔细揣摩才行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值