设计模式之简单工厂模式(simple factory pattern)

什么是简单工厂模式, 举个不恰当的例子, 就说生产雪糕吧, 雪糕什么形状的都有, 有长方形,有圆形等等, 怎么生产呢?

首先肯定是先造个机器, 然后弄几个按钮,上面依次写上长方形, 圆形等等,我按长方形就给我出长方形的, 我按圆形的按钮就给我出圆形的。

大概就是这样接下来开始实现

首先肯定要定义什么是雪糕  连雪糕是什么都不知道 所以 更别提什么是长方形雪糕 和圆形雪糕了, 所以要先搞出来他

一般都定义为抽象类或者接口,当父亲要有当父亲的样子, 毕竟不管什么样的雪糕都是他的孩子。来跟大家sayHello一下

/**
 * 我是雪糕
 */
public abstract class IceCream {
    public abstract  String sayHello();
}

接下来 是圆形雪糕  同样跟大家sayHello一下 

/**
 * 我是圆形雪糕
 */
public class CircleIceCream extends IceCream {
    @Override
    public String sayHello() {
        return "我是圆形雪糕, 请多多关照";
    }
}

再来个长方形雪糕  sayHello还是要的

/**
 * 我是长方形雪糕
 */
public class RectangleIceCream extends IceCream{
    @Override
    public String sayHello() {
        return "我是长方形雪糕, 请多多关照";
    }
}

雪糕有了, 造个机器吧

/**
 * 雪糕简单工厂
 * 你想要什么形状的要告诉我一声 我跟你生产什么样子的,
 * 请不要超出我的能力范围, 不然我就罢工了
 */
public class IceCreamSimpleFactory {
    public static IceCream getShapeIceCream(String shape){
        if("circle".equals(shape)){
            return new CircleIceCream();
        }else if("rectangle".equals(shape)){
            return new RectangleIceCream();
        }else {
            return null;
        }
    }
}

造出来的机器还挺有脾气

接下来开始造雪糕吧, 等不及了

public class IceCreamSimpleFactoryTest {
    public static void main(String[] args) {
        String warning = "超出机器范围了, 他罢工了";
        IceCream circleIceCream = IceCreamSimpleFactory.getShapeIceCream("circle");
        System.out.println(circleIceCream == null ? warning : circleIceCream.sayHello());

        IceCream rectangleIceCream = IceCreamSimpleFactory.getShapeIceCream("rectangle");
        System.out.println(rectangleIceCream == null ? warning : rectangleIceCream.sayHello());

        IceCream heartIceCream = IceCreamSimpleFactory.getShapeIceCream("heart");
        System.out.println(heartIceCream == null ? warning : heartIceCream.sayHello());
    }
}

雪糕出来了看看结果

我是圆形雪糕, 请多多关照
我是长方形雪糕, 请多多关照
超出机器范围了, 他罢工了

果然比较笨, 就会两种形状的, 给你装了一大堆零件就给我造出来两种, 丢人啊,

而且我要是还想生产个别的形状的还要给你加零件, 都是钱啊, 唉  改造一下, 能不能弄成一劳永逸的

package com.yxw.simplefactory;

/**
 * 通过反射改造工厂类, 一劳永逸
 */
public class IceCreamReflectSimpleFactory {
    /**
     * 你让我造各种各样的雪糕, 首先你必须是雪糕,
     * 你要让我造圆形豆沙包, 对不起,我真干不了
     * 就算真干得了, 我也不能给你, 因为我越线了
     * @param shape
     * @return
     */
    public static IceCream getShapeIceCream(String shape){
        try {
            /**
             * 通过反射实例化对象, newInstance()默认调用无参构造方法
             */
           Object object = Class.forName(shape).newInstance();
           if(object instanceof IceCream){
               return (IceCream)object;
           }
        } catch (InstantiationException e) {
        } catch (IllegalAccessException e) {
        } catch (ClassNotFoundException e) {
        }
        return null;
    }
}

试一下子

package com.yxw.simplefactory;

public class IceCreamReflectSimpleFactoryTest {
    public static void main(String[] args) {
        String warning = "不好意思, 真干不了";
        IceCream circleIceCream =  IceCreamReflectSimpleFactory.getShapeIceCream(CircleIceCream.class.getName());
        System.out.println(circleIceCream == null ? warning : circleIceCream.sayHello());

        IceCream rectangelIceCream =  IceCreamReflectSimpleFactory.getShapeIceCream(RectangleIceCream.class.getName());
        System.out.println(rectangelIceCream == null ? warning : rectangelIceCream.sayHello());

        IceCream heart =  IceCreamReflectSimpleFactory.getShapeIceCream("heart");
        System.out.println(heart == null ? warning : heart.sayHello());
    }
}


 /**
     * 测试结果:
     * 我是圆形雪糕, 请多多关照
     * 我是长方形雪糕, 请多多关照
     * 不好意思, 真干不了
     */

挺好 改造后果然省了不少零件, 败家玩意,下次再加别的形状就不用动你了 就这最后一次了。

ok  接下来化比较官方, 如果你理解了 就别浪费时间往下看了 

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

模式结构:

工厂角色

工厂角色负责实现创建所有实例的内部逻辑

抽象产品角色

抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口

具体产品角色

具体产品角色是创建目标,所有创建的对象都是抽象产品角色的子类

 模式分析

  • 将对象的创建和对象本身业务处理分离可以降低系统的耦合度,使得两者修改起来都相对容易。

  • 在调用工厂类的工厂方法时,由于工厂方法是静态方法,使用起来很方便,可通过类名直接调用,而且只需要传入一个简单的参数即可,在实际开发中,还可以在调用时将所传入的参数保存在XML等格式的配置文件中,修改参数时无须修改任何源代码。

  • 简单工厂模式最大的问题在于工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原则是相违背的。

  • 简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。

简单工厂模式的优点

  • 工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。

  • 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。

  • 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

 简单工厂模式的缺点

  • 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。

  • 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。

  • 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。

  • 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

     适用环境

    在以下情况下可以使用简单工厂模式:

  • 工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。

  • 客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。​​​​​​​

  • 模式应用

  • JDK类库中广泛使用了简单工厂模式,如工具类java.text.DateFormat,它用于格式化一个本地日期或者时间。

  •  总结

  • 创建型模式对类的实例化过程进行了抽象,能够将对象的创建与对象的使用过程分离。

  • 简单工厂模式又称为静态工厂方法模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

  • 简单工厂模式包含三个角色:工厂角色负责实现创建所有实例的内部逻辑;抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口;具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。

  • 简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。

  • 简单工厂模式最大的优点在于实现对象的创建和对象的使用分离,将对象的创建交给专门的工厂类负责,但是其最大的缺点在于工厂类不够灵活,增加新的具体产品需要修改工厂类的判断逻辑代码,而且产品较多时,工厂方法代码将会非常复杂。

  • 简单工厂模式适用情况包括:工厂类负责创建的对象比较少;客户端只知道传入工厂类的参数,对于如何创建对象不关心

参考资料 

https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/simple_factory.html#id25

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值