工厂模式

试问:
1.你知道设计模式吗?--当然。
2.告诉我一个商业案例并写下工厂方法的代码片段。--写下了一个简单工厂模式(非常不幸,简单工厂模式不被认为是设计模式)。
在本文,我不会展示如何编写Simple Factory和Factory Method ,相反我更愿意讨论它们是什么以及何时使用它们

如果你关于上面的两个问题的答案和上面的一样,要注意了:
1、实际上是在试图记住设计模式,而不是理解它试图解决的问题。
2、我们无法分析业务的问题并基于它们应用模式。相反,我们试图在业务案例中找到我们所知道的模式。


简单工厂模式

// 外卖接口
public interface Takeaway {
     String getTakeawayName();
}  
// 百度糯米 外卖
public class BaiDuNuomiTakeaway  implements Takeaway{
    @Override
    public String getTakeawayName() {
        return "百度糯米";
    }
}
// 美团  外卖
public class MeiTuanTakeaway  implements Takeaway{
    @Override
    public String getTakeawayName() {
        return "美团";
    }
}

// ** 工厂 **
 public class SimpleFactory {
    public static Takeaway createTakeaway(String type){
        switch (type){
            case "百度糯米": return new BaiDuNuomiTakeaway();
            case "美团": return new MeiTuanTakeaway();
            default: return null;
        }
    }
  public static void main(String[] args) {
        System.out.println(SimpleFactory.createTakeaway("百度糯米").getTakeawayName());
    }
}

使用Simple Factory ,调用者唯一知道的就是通过调用静态方法并传递所需要的参数,工厂就会返回一个外卖对象。但是如何创建外卖,客户端的代码并不知道。

改变是软件开发唯一不变的。比如我希望工厂在创建饿了么,当目前的工厂不能满足我时,毫无疑问,我需要创建饿了么的类,并在工厂中添加饿了么的创建过程。在小范围可能感觉不出来,但在更大的业务范围内,这会损害设计,接下来我们在开看看业务的简单变化,会如何影响设计。

工厂模式系列(工厂方法模式、抽象工厂模式)

除了Simple Factory之外,Factory Pattern系列的另外两个成员:Factory Method和Abstract Factory。我不在此详细介绍这两种模式了。
简而言之,Factory Method 使用实现接口,Abstract Factory 使用继承。Factory Method 是关于创建一种类型的对象,而Abstract Factory是关于创建一系列不同类型的对象。所有这三个都是通过设计原则封装对象创建:封装变化的东西。

如果业务需求不仅仅是产品创建,如果你想要控制产品创建步骤并希望控制每一个步骤,并且步骤是自定义的,那我们可以使用工厂方法模式,换句话说,如果要控制一些列产品的算法策略,可以考虑 工厂方法模式。
如果要创建一个框架,你希望从创建Object到管理该Object的控件,请使用工厂方法模式,这与简单工厂不同,简单工厂只关注产品创建后的结果,而不关心如何创建并管理产品。

回到我们的例子。现在,假设我们的业务要求不仅要创建外卖,还要根据当前外卖人员距离用户远近是否接受订单和发送外卖。
因此,我们需要创建一种算法,创建卖并发送它们,计算运输成本。工厂方法模式是理想的,我们在重新设计一下。

编码
// 抽象工厂  :生产不同种类的产品
public abstract class AbstractFactory {
    public abstract MeiTuanTakeaway createMeiTuanTakeaway();

    public abstract int shippingCharge();

    public final void orderTakeaway(){
        createMeiTuanTakeaway();
        int chagre=shippingCharge();
        System.out.println("运费:"+chagre);
    }

}

// 外卖 

public class Takeaway extends AbstractFactory {
    @Override
    public MeiTuanTakeaway createMeiTuanTakeaway() {
        return  new MeiTuanTakeaway();
    }

    @Override
    public int shippingCharge() {
        return 100;
    }

    public static void main(String[] args) {
        AbstractFactory  factory  =  new Takeaway();
        factory.orderTakeaway();
    }
}

理由:使用工厂方法模式,我们不仅可以抽象产品创建,还可以更进一步,我们可以抽象生产外卖的工厂。因此我们可以控制产品的创建和管理。上面的代码,你会发现,我们使用了抽象工厂,在抽象工厂中,我们创建了一个模板方法,来控制外卖的生命周期-创建外卖和运输成本计算,并可以使抽象工厂可以相应的改变他们。
优点:创建一个框架,控制产品生命周期。


总结:

简单工厂模式:根据调用者传入的参数,工厂动态决定所要创建的产品。只关心结果。
工厂方法模式:核心类成为一个抽象工厂角色,而实现类,只创建一种类型对象。
抽象工厂模式:创建一系列不同类型对象。


推荐阅读:

  1. 详解设计模式六大原则
  2. 详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂)

推荐阅读更多精彩内容

  • 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。通常我们所说的工厂模式是指工厂方法模...
    zfylin阅读 835评论 0 7
  • 一、工厂模式介绍 工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每...
    QuantRuu阅读 525评论 0 51
  • 工厂模式概述 意义 问题引出在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用...
    stoneyang94阅读 180评论 0 0
  • 一、工厂模式介绍 工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每...
    端木轩阅读 11,323评论 1 20
  • 今天下午,突然有种想看电影的冲动,网上一搜,发现评价最高的是《速度与激情8》,就决定前去观影。整个影片非常精彩,除...
    冰上之路阅读 324评论 4 4
  • 跟人聊天,我们喜欢来一句“在忙吗?” 作为开头,再继续话题; 与人相约,一般先问一句“某某时间你忙吗?”,再发出邀...
    段姑娘减肥教练阅读 51评论 0 0