浅谈设计模式-简单工厂模式

书接上回,本篇讲一下创建型模式-简单工厂设计模式

简单工厂设计模式

工厂设计模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。目前流行的说法,工厂设计模式有3种:

简单工厂设计模式

目前找不到定义,一个较为认可的说法:简单工厂并不是一个种设计模式,反而比较像一种编程习惯。

工厂方法设计模式

工厂方法设计模式:通过让子类决定该创建对象是什么,来达到将对象创建过程封装的目的。

抽象工厂设计模式

抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

本篇重点讲解一下简单工厂设计模式

案例分析 

工厂顾名思义,生产产品的地方,所以工厂模式参与核心角色:产品,工厂,而它的精髓在于:工厂如何科学生产产品

需求:华为工厂创建华为手机/华为电脑

 产品:

//华为商品基类
public abstract class HWProduct {
    //商品展示
    public abstract void show();
}
//华为手机继承华为商品基类
public class HWPhoneProduct extends HWProduct{
    @Override
    public void show() {
        System.out.println("HWPhone被创建了.....");
    }
}
//华为电脑继承华为商品基类
public class HWComputerProduct extends HWProduct{
    @Override
    public void show() {
        System.out.println("HWComputer被创建了.....");
    }
}

工厂: 

//华为工厂
public class HWProductFactory {
    //根据产品类型生成产品
    public HWProduct produce(String type){
        if("hwphone".equals(type)){
            return new HWPhoneProduct();
        }else if("hwcomputer".equals(type)){
            return new HWComputerProduct();
        }
        return null;
    }
}

客户端:

public class App {

    public static void main(String[] args) {
        //工厂
        HWProductFactory factory = new HWProductFactory();

        //手机
        HWProduct phone = factory.produce("hwphone");
        phone.show();
        //电脑
        HWProduct computer = factory.produce("hwcomputer");
        computer.show();

    }
}

分析

        简单工厂设计模式就是一种创建对象的编码习惯, 按照传统方式直接使用new就可以啦,引入factory类的目的是隐藏对象new过程细节。观察App类,HWPhoneProduct,HWComputerProduct个对象的创建是通过factory的produce方法,具体对象初始化过程,App类是不需要知道。居于此,简单工厂设计模一般用在需要遮蔽实例构建过程场景。比如:实例初始化操作。

        但是,这种代码设计方法存在一定瑕疵啦:违背了开闭原则设计原则(软件实体应当对扩展开放,对修改关闭)。比如:当新增华为平板产品时,就需要变动HWProductFactory类啦,这个改动就犯大忌了。那怎办?可以使用下一篇讲的:工厂方法设计模式。

适用场景

上面的分析说了,简单工厂方法存在瑕疵,当新增产品时,会违背开闭原则,那它就无用了么?其实不然,下面场景还是可以使用简单工厂设计模式的。

1>工厂类负责创建的对象较少(最好是个数固定)
2>客户端(应用层)关心对象创建结果,不关心创建对象过程

优缺点

优点:隐藏对象构建细节
只需要传入一个正确的参数,就可以获取你所需要的对象而无须知道其构建细节

缺点:违背开闭原则
工厂类的职责相对过重,增加新产品时需要修改工厂类的判断逻辑,违背开闭原则(扩展放开,修改关闭)

开发案例

JDK中有很多工厂模式的运用,这里说一个简单的:日历类Calendar

public static Calendar getInstance(){
    Locale aLocale = Locale.getDefault(Locale.Category.FORMAT);
    return createCalendar(defaultTimeZone(aLocale), aLocale);
}
private static Calendar createCalendar(TimeZone zone, Locale aLocale){
	//.....
    Calendar cal = null;

    if (aLocale.hasExtensions()) {
        String caltype = aLocale.getUnicodeLocaleType("ca");
        if (caltype != null) {
            switch (caltype) {
            case "buddhist":
            cal = new BuddhistCalendar(zone, aLocale);
                break;
            case "japanese":
                cal = new JapaneseImperialCalendar(zone, aLocale);
                break;
            case "gregory":
                cal = new GregorianCalendar(zone, aLocale);
                break;
            }
        }
    }
    //.......
}    

上面代码中,根据传入的Locale参数使用switch语法区分不同地区,然后创建不同的Calendar对象,标准的简单工厂模式。这里可能会有朋友问:这里的工厂是谁, 产品是谁?
工厂:Calendar, 产品:JapaneseImperialCalendar,BuddhistCalendar,GregorianCalendar,而这些产品跟工厂又是子父类关系,那又如何,依然不妨碍它们是标准的简单工厂模式。这里强调:学习设计模式学习其神而不是其形。

总结

1>简单工厂本质是选择实现,创建对象实例根据具体传入决定具体实现。

2>简单工厂设计模式适用场景:创建的对象种类有限的情况下使用

3>设计模式学习其神而不是其形,设计思路不变,而代码表现形式可能有多种

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浪飞yes

我对钱没兴趣~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值