常用的设计模式之工厂模式

写在前面的话:

   虽然在我们的日常开发过程中,不用设计模式也可以完成相应的功能,但是用好的设计模式可以帮助我们更好的解决实际问题,设计模式一个重要的思想是解耦,降低代码间的粘着性。几乎我们所有的java框架和源码都使用了良好的设计模式,比如spring就使用了诸如BeanFactory的工厂模式,mybatis框架的模板模式等等。学习设计模式可以更好的让我们把业务转化成技术实现。

   工厂模式从名字上来看,脱离于现实生活中的工厂,就是生成和制造各种产品的,比如口罩工厂。在Java的世界里,工厂模式,也是同样的道理,也是用来生产东西的(类实例对象)。在没有该模式的情况下,我们一般生产对象(创建对象)一般都是采用new的形式。那为什么有了new的方式,还要提出一种“工厂模式”呢?原因其实还是比较容易理解,就比如这个生产口罩的工厂内部,口罩分多钟型号,KN94/KN95/KF94等等。假如一个公民想要买口罩,我得告诉工厂我要哪种型号的吧,然后它生产出来给我。但生产某种型号的过程我是不知道的,不知道用了什么材料,不知道用了什么工艺对吧? 然后反过来想new的这种方式,一般代码为KouZhao kouZhao = new KouZhao(),使用new 的前提是什么?得先知道KouZhao这个类吧,也就是说我得知道KouZhao是要用什么材料用什么工艺来做的,工厂模式就是 将这个过程隐藏起来只给结果给调用方。

1.简单工厂模式

  简单工厂就是我给你型号,你帮我生产,隐藏生产过程。new是我自己知道这个型号的制作过程和原理,自己申明生产过程。就 是传入一个型号名称(形参),内部if-else去判断生产对象型号名称的口罩。如果要新增型号,只能修改该工厂内部的if-else语句,新增判断。

    KouZhaoFactory factory = new KouZhaoFactory();
    KN94KouZhao kn94 = (KN94KouZhao) factory.create("KN94");
    KN95KouZhao kn95 = (KN95KouZhao) factory.create("KN95");
    KF94KouZhao kf94 = (KF94KouZhao) factory.create("KF94");
    kn94.protect();
    kn95.protect();
    kf94.protect();

为了避免字符串写错造成的问题可以使用反射改进一下:

 

KouZhaoFactory代码如下:
 KouZhao create(Class <? extends  KouZhao> clazz){
       try {
         if (clazz!=null) {
            return clazz.newInstance();
         }
       } catch (Exception e) {
         e.printStackTrace();
       }
       return  null;
    }

 测试方法如下:

    KouZhaoFactory factory = new KouZhaoFactory();
    KN94KouZhao kn94 =(KN94KouZhao) factory.create(KN94KouZhao.class);
    KN95KouZhao kn95 =(KN95KouZhao) factory.create(KN95KouZhao.class);
    KF94KouZhao kf94 =(KF94KouZhao) factory.create(KF94KouZhao.class);
    kn94.protect();
    kn95.protect();
    kf94.protect();

从上面可以看出简单工厂模式中工厂类的职责相对过重,所有的判断和创建都在内部完成,不易于扩展过于复杂的产品结构。

2.工厂方法模式

    简单工厂模式看起来像一个万能工厂啥型号的口罩都可生成,工厂类的职责过重了,工厂方法模式是对简单工厂进行了升级,不在由工厂类生成具体的口罩了,而是产生一个抽象的口罩接口,我们先创建一个口罩接口,再创建KN94、KN95、KF94实现类实现口罩接口。在使用时,直接给工厂传入指定的实现类,内部利用反射的机制,绑定创建好指定型号(类型)的口罩。类图如下:

测试代码:

 

    KouZhaoFactory factory = new KN94KouZhaoFactory();
    KouZhao kn94 = factory.create();
    kn94.protect();

    KouZhaoFactory factory2 = new KN95KouZhaoFactory();
    KouZhao kn95 = factory2.create();
    kn95.protect();

    KouZhaoFactory factory3 = new KF94KouZhaoFactory();
    KouZhao kf94 = factory3.create();
    kf94.protect();

从上面可以看出工厂方法模式中类的过多比简单工厂模式几乎多了1倍,系统的复杂度也随之增加,理解起来不是那么容易。

3.抽象工厂模式

现实中一个工厂很少只生成1中产品的,通常情况都是如下图所示:

我们将1个工厂相同颜色的各种产品称作1个产品族,不同工厂的相同产品称作1个产品等级结构,即上图中的x轴和y轴。

在我们java世界里抽象工厂模式源于此, 抽象工厂模式是工厂方法的升级。假设现在用户想要购买口罩了,突然又想买点绷带备用,如果没有这个产品就很尴尬了,使用抽象工厂可以给用户更多的选择。类图如下:

测试代码:

    KouZhaoFactory factory = new KN94KouZhaoFactory();
    factory.createBengDai().blood();
    factory.createHuMuJing().protectEyes();
    factory.createKouZhao().protect();


    KouZhaoFactory factory2 = new KN95KouZhaoFactory();
    factory2.createBengDai().blood();
    factory2.createHuMuJing().protectEyes();
    factory2.createKouZhao().protect();

    KouZhaoFactory factory3 = new KF94KouZhaoFactory();
    factory3.createBengDai().blood();
    factory3.createHuMuJing().protectEyes();
    factory3.createKouZhao().protect();

总结:抽象工厂模式可以完美的展现出产品族和产品等级的关系,适用于产品数量不多的情况,过多的产品会使系统复杂度成倍递增。

 

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

焱童鞋

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值