简单工厂

ID:17399 / 打印

什么是简单工厂?

简单工厂不是设计模式。它只是将对象创建与客户端代码解耦。换句话说,简单工厂通过将实例化逻辑移至单独的类来封装对象实例化。

简单工厂经常与工厂模式混淆。我们将研究简单工厂来阐明它们的区别。另外,学习简单工厂可以帮助我们轻松理解工厂模式。

简单工厂可以解决什么问题?

应避免对具体实现进行编程,因为这会使应用程序非常难以维护。对接口进行编程总是更好的选择。如果您在客户端代码中实例化一个具体类,那么简单工厂会派上用场,因为简单工厂可以将对象创建与客户端分离。这使得我们的应用程序更具可扩展性和可维护性。

问题

我们正在开发汉堡店系统。系统需要制作牛肉汉堡、鸡肉汉堡等各种汉堡。

我们的第一次尝试是这样的:

// client orders a burger burger orderburger(string type) {     burger burger;      if (type.equals("beef")) {         burger = new beefburger();     } else if (type.equals("chicken")) {         burger = new chickenburger();     } else if (type.equals("fish")) {         burger = new fishburger();     }      burger.preparebun();     burger.grillpatty();     burger.addtoppings();     burger.wrap();      return burger; } 

问题是,我们正在针对实现进行编码,而不是针对接口进行编码。在哪里?我们使用 if 语句并根据汉堡类型实例化一个具体类。
为什么会出现这个问题呢?我们的客户端代码与对象创建紧密耦合,导致灵活性降低!假设我们不再销售鱼汉堡,并开始销售素食汉堡。我们需要访问我们的客户端代码并修改它。也就是说不关闭修改。

解决方案

为了解决这个问题,我们可以创建单独的类,它只负责对象的创建。那么我们的客户端代码就不需要担心对象创建并且能够依赖抽象。这种技术被称为“封装变化的内容”。我们预计有关实例化具体对象的代码将经常更改,而未来所有汉堡中的preparebun()、grillpatty()、addtoppings()、wrap()过程可能会保持不变。
简单工厂的优点是可以被其他类重用。我们可能有其他客户端类,例如 burgerrestaurant、burgercateringshop,它们将使用 simpleburgerfactory.createburger() 方法。

简单工厂

  1. 客户
    客户端通过simpleburgerfactory实例化特定的汉堡对象。请注意,从客户端角度来看,我们不知道将创建哪个具体汉堡,即对象创建逻辑现在与客户端解耦。

  2. 简单汉堡工厂
    这个类封装了不同的内容,在本例中是对象创建逻辑! createburger() 被声明为静态方法,因为客户端想要使用此类来实例化对象(当然,在实例化它之前我们不能有实例!)。 createburger() 接受 burgertype 枚举来确定应创建哪种类型的汉堡。

  3. 汉堡
    这个抽象类提供所有汉堡之间的通用接口并定义默认行为。

  4. 汉堡子类
    这是我们的混凝土产品。只要扩展 burger 类,他们就可以通过重写方法来实现特定行为。

结构

简单工厂

代码

public enum burgertype {     beef,     chicken,     fish,     veggie } 
// abstract product public abstract class burger {      public burgertype burgertype;     public list<string> toppings = new arraylist<>();      public void preparebun() {         system.out.println("preparing a bun");     }      public void grillpatty() {         if (burgertype == null) {             throw new illegalstateexception("pattytype is undefined");         }         system.out.println("grill a " + burgertype + " patty");     }      public void addtoppings() {         for (string item : toppings) {             system.out.println("add " + item);         }     }      public void wrap() {         system.out.println("wrap a burger up");     } } 
// concrete product public class beefburger extends burger {      public beefburger() {         burgertype = burgertype.beef;         list<string> items = list.of("lettuce", "pickle slices", "tomato slice", "bbq sauce");         toppings.addall(items);     } } 
// concrete product public class veggieburger extends burger {      public veggieburger() {         burgertype = burgertype.veggie;         list<string> items = list.of("smoked paprika", "garlic chips", "crushed walnuts", "veggie sauce");         toppings.addall(items);     }      // concrete product can implement specific behavior that differs from other products     @override     public void wrap() {         system.out.println("wrapping paper shouldn't print any meats but vegetables");     } } 
// simple factory, responsible for instantiating an object public class simpleburgerfactory {      public static burger createburger(burgertype type) {         return switch (type) {             case beef -> new beefburger();             case chicken -> new chickenburger();             case fish -> new fishburger();             case veggie -> new veggieburger();             default -> throw new illegalargumentexception("unknown burger type");         };     } } 
public class client {      public static void main(string[] args) {         burger burger = orderburger(burgertype.veggie);         system.out.println(burger); // check if the object is actually veggie burger     }      public static burger orderburger(burgertype type) {         // factory is responsible for object creation         burger burger = simpleburgerfactory.createburger(type);          burger.preparebun();         burger.grillpatty();         burger.addtoppings();         burger.wrap();          return burger;     } } 

输出:

Preparing a bun Grill a VEGGIE patty Add smoked paprika Add garlic chips Add crushed walnuts Add veggie sauce Wrapping paper shouldn't print any meats but vegetables com.factories.simpleFactory.VeggieBurger@9807454 

陷阱

  • 对象实例化的决策代码有时可能会更加复杂。这种情况下,我们不妨考虑使用factory方法来代替。

与工厂模式的比较

  • 简单工厂中,通常有一个工厂类来决定创建哪种类型的产品,而工厂模式可能会引入多个工厂。
  • 简单工厂经常使用静态方法创建对象,调用容易但扩展困难。另一方面,工厂方法在超类中使用抽象方法,它充当所有工厂和子类的接口,将为对象实例化提供具体的实现。

您可以在这里查看所有设计模式的实现。
github 存储库


附注
我是刚开始写科技博客,如果您对我的写作有什么建议,或者有任何困惑的地方,请留言!
感谢您的阅读:)

上一篇: 如何为安卓开发中的按钮添加单击事件并弹出“Hello World”消息?
下一篇: Android自定义适配器样式问题:为什么自定义样式显示红色提示“无法解释符号mainitem”?

作者:admin @ 24资源网   2024-11-27

本站所有软件、源码、文章均有网友提供,如有侵权联系308410122@qq.com

与本文相关文章

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。