【创建型设计模式】工厂模式

前言(一些废话,可以忽略)

  • 工厂模式是非常重要的一种设计模式,相比单例模式来说,更有结构上的设计,有思想上深一层的东西,但是和跟复杂的模式相比,其实也是很简单的。
  • 网络上有很多工厂模式的讲解,如果你看得比较多,你会发现,一会这么实现,一会那么实现,怎么感觉每一篇文章讲得都大同小异,又感觉不太一样,让人很是迷糊。
  • 是的,开始的时候我也是这样迷茫,当我继续阅读更多的设计模式的时候,恍然大悟。这不就是大师打拳的境界么,神似而形异。
  • 其实设计模式就是这样的,不要说同一种设计模式都有相似的地方,哪怕是不同的设计模式,它们的结构也大同小异,我们要做的,是将设计的原则精神掌握内化,而这些设计模式,只是一个工具,帮主你内化代码设计精神的工具,举个例子,具体A讲的工厂模式和B说的工厂模式可能不一样,这不重要,重要的是他们所讲的工厂模式的精髓是一样的。
  • 所以在你学习设计模式的时候,期望大家能够自己进行演化,这样更能方便大家,使大家更容易,更快速的内化掌握代码设计精髓。
  • PS.部分类实现见文末

简单工厂模式
  • 这是将类创建进行简单封装的模式,很容易就能够想到,将需要的对象封装在一个方法,通过参数判断需要创建哪个类对象
/**
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:09
 **/
public class SimpleAeratedWaterFactory {

    public ColaAeratedWater getAeratedWater(String type){
        if("ColaOriginal".equals(type)){
            return new ColaOriginal();
        }else if("ColaBule".equals(type)){
            return new ColaBule();
        }else if("ColaDiet".equals(type)){
            return new ColaDiet();
        }else{
            throw new RuntimeException("没有此类型可乐");
        }
    }
}
  • 调用也简单,无需解释
/**
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:09
 **/
public class SimpleFactoryMode {
    public static void main(String[] args) {
        SimpleAeratedWaterFactory factory = new SimpleAeratedWaterFactory();
        ColaAeratedWater water = factory.getAeratedWater("ColaOriginal");
        System.out.println(water.getName());

    }
}
  • 存在一个问题,如果要增加的新的可乐口味,我们不仅需要新增实现不同味道的可乐,而且还需要在工厂中添加if else代码,据说这里是违反ocp原则,是的,自己仔细想一想也是,工厂代码被修改了

工厂方法模式
  • 我们将可乐的不同味道,实现在不同的类中,让这个类去实现一个统一的创建可乐的工厂,即所谓网络上流传的将具体的实现延迟到子类中进行实现
/**
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:10
 **/
public interface ColaFactory {

    ColaAeratedWater createCola();
}
  • 蓝色口味的可乐,实现可乐工厂ColaFactory实现其方法,返回蓝色可乐对象
/**
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:10
 **/
public class BuleColaFactory implements ColaFactory {
    @Override
    public ColaAeratedWater createCola() {
        return new ColaBule();
    }
}

同理,无糖口味可乐的工厂

/**
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:10
 **/
public class DietColaFactory implements ColaFactory {
    @Override
    public ColaAeratedWater createCola() {
        return new ColaDiet();
    }
}
  • 在使用的时候,通过创建对应口味的可乐工厂,调用同样的创建可乐方法
/**
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:08
 **/
public class FactoryMethodMode {

    public static void main(String[] args) {
        ColaFactory factory = new BuleColaFactory();
        ColaAeratedWater water = factory.createCola();
        System.out.println(water.getName());
    }

}
  • 简单画一下工厂方法模式的uml图
    在这里插入图片描述
抽象工厂模式
  • 在工厂方法模式的基础上进行扩展,比如要新增雪碧Sprite,工厂方法模式似乎就不能满足设计模式原则的扩展需求了
  • 将蓝色可乐工厂进一步抽象为蓝色汽水工厂,这样不仅可以生产蓝色可乐,也可以生产蓝色雪碧(当然,我们目前没有蓝色雪碧,这种情况如何处理,我是有点木讷,是实现一个空方法还是在实现的方法里抛出异常,又或是有更好的方法,希望看到此文的同学能告诉我)或其他蓝色口味汽水
/**
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:11
 **/
public abstract class BuleAeratedWaterFactory implements AeratedWaterFactory {
    @Override
    public ColaAeratedWater createColaAeratedWater() {
        return new ColaBule();
    }

    @Override
    public SpriteAeratedWater createSpriteAeratedWater() {
        return null;
    }
}
  • 接下来是原味的汽水,可乐和雪碧都有,都得实现
/**
 *
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:11
 **/
public class OriginalAeratedWaterFactory implements AeratedWaterFactory{
    @Override
    public ColaAeratedWater createColaAeratedWater() {
        return new ColaOriginal();
    }

    @Override
    public SpriteAeratedWater createSpriteAeratedWater() {
        return new SpriteOriginal();
    }
}

抽象工厂,即可以生产可乐也可以生产雪碧,在扩展的时候,直接添加其他汽水饮料

/**
 * absFactory
 *
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:10
 **/
public interface AeratedWaterFactory {

      ColaAeratedWater createColaAeratedWater();

      SpriteAeratedWater createSpriteAeratedWater();

	  //增加其他汽水
	  //SodaAeratedWater createSodaAeratedWater();
}
  • 使用,创建不同口味的汽水工程,然后生产需要的汽水
/**
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:10
 **/
public class AbsFactoryMode {
    public static void main(String[] args) {
        AeratedWaterFactory originalAeratedWaterFactory = new OriginalAeratedWaterFactory();
        AeratedWater water = originalAeratedWaterFactory.createColaAeratedWater();
        System.out.println(water.getName());

    }
}

其他类

/**
 * 汽水
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:11
 **/
public interface AeratedWater {
    String getName();
}
/**
 * 工厂方法模式 
 * 使用的可乐父接口(也可以不要 用AeratedWater代替 个人认为这些就是所谓的在学习过程中或初学时__不需要特别纠结的细节__ 在使用过程中遇到情况再随机应变)
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:09
 **/
public interface ColaAeratedWater extends AeratedWater{
}
/**
 * 蓝色可乐
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:09
 **/
public class ColaBule implements ColaAeratedWater {
    @Override
    public String getName() {
        return "ColaBule";
    }
}
/**
 * 原味可乐
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:09
 **/
public class ColaOriginal implements ColaAeratedWater {
    @Override
    public String getName() {
        return "ColaOriginal";
    }
}
/**
 * 雪碧
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:10
 **/
public interface SpriteAeratedWater extends AeratedWater{
}
/**
 * 原味雪碧
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-21 21:11
 **/
public class SpriteOriginal implements SpriteAeratedWater {

    @Override
    public String getName() {
        return "SpriteOriginal";
    }
}

总结

  • 工厂模式的三种基本分支大概就是这样了,个人感觉自己还是要理解其精神内涵,不要盲目的生搬硬套,不能钻牛角尖,特别在当前博客泛滥相互借鉴质量不高的情况下,要有自己的理解,才能有所提升。

愿你不舍爱与自由。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值