前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式之工厂方法模式(FACTORY METHOD)问题模拟工厂方法模式分析依赖倒置原则小结

设计模式之工厂方法模式(FACTORY METHOD)问题模拟工厂方法模式分析依赖倒置原则小结

作者头像
desperate633
发布2018-08-22 09:43:25
3230
发布2018-08-22 09:43:25
举报
文章被收录于专栏:desperate633desperate633

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。 我们依然接着简单工厂模式提出的披萨店问题继续探讨

问题模拟

我们假设有多种不同的pizza店,比如纽约的pizza点,芝加哥的pizza店,他们都有自己制作的不同种类的pizza。 如果我们采用简单模式方法,那么我们就需要分别建立纽约pizzafactory和芝加哥的factory等等工厂,但这样做没有弹性。我们能不能将制作pizza的行为局限在旁pizzaStore类中,但同时又能让不同类的点去各自实例化自己的pizza类。 显然,我们可以将pizzaStore由一个具体类,变为一个抽象的接口:

代码语言:javascript
复制
public abstract class PizzaStore {
    public Pizza orderPizza(String type) {
      Pizza pizza;
      pizza=createPizza(type);
      pizza.prepare();
      pizza.bake();
      pizza.cut();
      pizza.box();
      return pizza;
  }
  abstract Pizza createPizza(String type);
}

Paste_Image.png

定义了一个抽象的基类,里面有个抽象的create方法,我们让其他的纽约地区,芝加哥地区等等不同的继承自这个基类,让子类自己决定怎么创建pizza。

代码语言:javascript
复制
public class NYPizzaStore extends PizzaStore {
Pizza createPizza(String item) {
if (item.equals(“cheese”)) {
return new NYStyleCheesePizza();
} else if (item.equals(“veggie”)) {
return new NYStyleVeggiePizza();
} else if (item.equals(“clam”)) {
return new NYStyleClamPizza();
} else if (item.equals(“pepperoni”)) {
return new NYStylePepperoniPizza();
} else return null;
}
}

以上是我们实现的一个具体的纽约pizzastore类。他继承实现了基类的抽象方法。

然后我们继承实现抽象的pizza类和具体的pizza类

代码语言:javascript
复制
public abstract class Pizza {
String name;
String dough;
String sauce;
ArrayList toppings = new ArrayList();
void prepare() {
System.out.println(“Preparing “ + name);
System.out.println(“Tossing dough...”);
System.out.println(“Adding sauce...”);
System.out.println(“Adding toppings: “);
for (int i = 0; i < toppings.size(); i++) {
System.out.println(“ “ + toppings.get(i));
}
}
void bake() {
System.out.println(“Bake for 25 minutes at 350”);
}
void cut() {
System.out.println(“Cutting the pizza into diagonal slices”);
}
void box() {
System.out.println(“Place pizza in official PizzaStore box”);
}
public String getName() {
return name;
}
}

具体的产品类

代码语言:javascript
复制
public class NYStyleCheesePizza extends Pizza {
public NYStyleCheesePizza() {
name = “NY Style Sauce and Cheese Pizza”;
dough = “Thin Crust Dough”;
sauce = “Marinara Sauce”;
toppings.add(“Grated Reggiano Cheese”);
}
}
代码语言:javascript
复制
public class NYStyleCheesePizza extends Pizza {
public NYStyleCheesePizza() {
name = “NY Style Sauce and Cheese Pizza”;
dough = “Thin Crust Dough”;
sauce = “Marinara Sauce”;
toppings.add(“Grated Reggiano Cheese”);
}
}

public class ChicagoStyleCheesePizza extends Pizza {
public ChicagoStyleCheesePizza() {
name = “Chicago Style Deep Dish Cheese Pizza”;
dough = “Extra Thick Crust Dough”;
sauce = “Plum Tomato Sauce”;
toppings.add(“Shredded Mozzarella Cheese”);
}
void cut() {
System.out.println(“Cutting the pizza into square slices”);
}
}

最后测试我们的代码:

代码语言:javascript
复制
public class PizzaTestDrive {
public static void main(String[] args) {
PizzaStore nyStore = new NYPizzaStore();
PizzaStore chicagoStore = new ChicagoPizzaStore();
Pizza pizza = nyStore.orderPizza(“cheese”);
System.out.println(“Ethan ordered a “ + pizza.getName() + “\n”);
pizza = chicagoStore.orderPizza(“cheese”);
System.out.println(“Joel ordered a “ + pizza.getName() + “\n”);
}
}

工厂方法模式分析

Paste_Image.png

工厂方法模式常常分为两大类:一个创建产品的创建类,一个产品类,其中创建类定义一个抽象的接口,外加其余的继承自他的具体实现。产品类也是类似,定义一个抽象的产品类接口,具体的产品类实现继承自基类。

Paste_Image.png

Paste_Image.png

把创建对象的代码集中在一个对象或者方法中,可以避免代码的重复,并且更方便的以后的维护,这意味着客户在实例化对象的时候,依赖的是接口,而不是具体的对象,而正是我们之前提到的具体设计原则中的一种,针对接口编程。

依赖倒置原则

这是我们提出的又一设计原则:**要依赖抽象,不要依赖具体实现 ** 工厂方法模式中,就很好的应用这个原则: 如果我们采用简单工厂模式,依赖关系是这样的:

Paste_Image.png

而采用工厂方法模式,依赖关系如图:

Paste_Image.png

这就是依赖倒置原则,高层组件依赖了底层的pizza组件!

小结

工厂方法模式对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不再负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。

工厂方法经常用在以下两种情况中:

  • 第一种情况是对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品来。Java Collection中的iterator() 方法即属于这种情况。
  • 第二种情况,只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂为生产的,即最终选用哪个具体工厂的决定权在生产者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程这对于使用者来说是透明的。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016.07.30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题模拟
  • 工厂方法模式分析
  • 依赖倒置原则
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档