简单工厂和工厂方法的优缺点及解决到生产的应用

目录

背景

需求

分析

代码

1.工厂类

2.业务类

3.客户端

总结


背景

工厂模式实际开发中用到很多,网上的介绍案例非常多。工厂模式存在一些问题:

使用工厂前:我们有一系列的产品类,都有共同的父类。这种情况才会想到工厂。

简单工厂

定义:专门定义一个类来负责创建产品对象(根据唯一标识分发)

优点简单

缺点:耦合度高,如果有变动就需要修改唯一的工厂的入口方法。

工厂方法

定义:专门定义一个用于创建产品对象接口,子工厂类去决定,实例化具体产品类。每个产品都有自己的工厂。

本质:就是把简单工厂的方法抽象了,具体产品都要去实现各自的工厂。解决简单工厂缺点。这样服务端新增产品,不需要改代码。只需新增,产品,和其对应的工厂。

优点符合开闭原则(具体的业务类有具体工厂),

缺点:每增加一个产品,相应的也要增加一个子工厂,加大了额外的开发量。但是实际开发中,客户端也不会去主动找工厂的啊,这就好比你买手机,你买苹果手机去苹果官网买,买华为去华为商城买。我再想买小米,又要搞一个小米的商城,才能买手机。这确实是扩展性好。实际中我们是通过一个入口去买更方便,这才是用户比较迫切的需求,就比如,我在京东,输入苹果,就买买到苹果,输入华为就能买到华为了。所以工厂方法我觉得存在的问题复杂了,回归本初,回到最初简单工厂思想:通过一个唯一入口,根据不同的参数,即可获得具体的业务类。

需求

实现一个网关,路由不同的渠道。考虑扩展,符合开闭原则,怎么才能写好符合开闭的工厂呢?

开闭原则:就是说对扩展开放,对修改关闭。

分析

我们要设计的网关,来路由不同的业务类,要满足的条件:

1.开闭原则必须满足;

2.工厂类提供唯一入口分发;避免新增业务增加新的工厂代码量

3.具体业务类且只需要实现自己的业务,其他的一概不需要关心。业务类扩展性好,且不用修改工厂类,或者增加工厂。

代码

使用的开发环境:springboot、jdk1.8

抽象一个造手机的工厂业务

1.工厂类

public class JdMallFactory {

    private static Map<String, Phone> map = new HashMap<>();

    public static Phone getPhoneService(String phoneName){
        return map.get(phoneName);
    }

    public static void addPhoneService(String phoneName, Phone phone) {
        map.put(phoneName, phone);
    }
}

2.业务类

1)枚举:业务名唯一标示

public enum PhoneNameEnum {
    apple,huawei,xiaomi
}

2)接口:定义业务功能

public interface Phone {
    void call();
}

3)抽象类:具体业务和工厂合作抽象模版化,后续业务类不需要关心,继承此类即可

public abstract class AbstractPhone implements Phone {

    abstract String getPhoneName();

    @PostConstruct
    public void providePhoneToFactory() {
        JdMallFactory.addPhoneService(getPhoneName(), this);
    }
}

4)业务扩展类,华为手机

public class HuaWeiService extends AbstractPhone {

    @Override
    public String getPhoneName() {
        return PhoneNameEnum.huawei.name();
    }

    @Override
    public void call() {
        System.out.println(getPhoneName() + "增加定制功能");
        System.out.println("使用" + getPhoneName() + "打电话");
    }
}

5)业务扩展类,苹果手机

public class AppleService extends AbstractPhone {

    @Override
    public String getPhoneName() {
        return PhoneNameEnum.apple.name();
    }

    @Override
    public void call() {
        System.out.println(getPhoneName() + "增加定制功能");
        System.out.println("使用" + getPhoneName() + "打电话");
    }
}

3.客户端

public class FactoryTest {

    @Test
    public void testFactory() {
        // 1、模拟服务端启动,华为和苹果公司成立。(使用Spring框架,这一步使用组件注入到IOC即可,不用new)
        new HuaWeiService();
        new AppleService();

        // 2、模拟客户端:用户买手机(京东商城买手机)
        Phone phoneService = JdMallFactory.getPhoneService(PhoneNameEnum.huawei.name());
        // 用户使用手机
        phoneService.call();
        phoneService = JdMallFactory.getPhoneService(PhoneNameEnum.apple.name());
        phoneService.call();
    }

}

 测试输出:

huawei增加定制功能
使用huawei打电话
apple增加定制功能
使用apple打电话

总结

以上代码实现,可以看出是满足我们想法的:

1.开闭原则必须满足;- 满足

2.工厂类提供唯一入口分发;避免新增业务增加新的工厂代码量。- 满足

3.具体业务类且只需要实现自己的业务,其他的一概不需要关心。业务类扩展性好,且不用修改工厂类,或者增加工厂。- 满足

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值