首页 > 其他分享 >设计模式-工厂模式

设计模式-工厂模式

时间:2022-11-27 21:13:04浏览次数:56  
标签:ordertype 模式 工厂 new 设计模式 public pizza

工厂模式

定义

工厂模式定义:这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式、在工厂模式中,我们在创建对对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

简单来说,使用了c++多态的特性,将存在继承关系的类,通过一个工厂类创建对应的子类(派生类)对象。在项目复杂的情况下,可以便于子类对象的创建。

工厂模式的实现方式可分为简单工厂模式、工厂方法模式、抽象工厂模式,每个实现方式都存在优和劣。

简单工厂模式

  • 定义:定义了一个创建对象的类,由这个类来封装实例化对象的行为。
  • 代码实现
    • pizza工厂一共生产三种类型的pizza:chesse,pepper,greak。通过工厂类(SimplePizzaFactory)实例化这三种类型的对象。
public class SimplePizzaFactory {
     public Pizza CreatePizza(String ordertype) {
            Pizza pizza = null;
            if (ordertype.equals("cheese")) {
                   pizza = new CheesePizza();
            } else if (ordertype.equals("greek")) {
                   pizza = new GreekPizza();
            } else if (ordertype.equals("pepper")) {
                   pizza = new PepperPizza();
            }
            return pizza;
     }
}
  • 简单工厂存在的问题与解决方法: 简单工厂模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了开闭原则,所以,从设计角度考虑,有一定的问题,如何解决?我们可以定义一个创建对象的抽象方法并创建多个不同的工厂类实现该抽象方法,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。这种方法也就是我们接下来要说的工厂方法模式。

工厂方法模式

  • 定义:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。
  • 举例:(依然举pizza工厂的例子,不过这个例子中,pizza产地有两个:伦敦和纽约)。添加了一个新的产地,如果用简单工厂模式的的话,我们要去修改工厂代码,并且会增加一堆的if else语句。而工厂方法模式克服了简单工厂要修改代码的缺点,它会直接创建两个工厂,纽约工厂和伦敦工厂。
  • OrderPizza中有个抽象的方法:
abstract Pizza createPizza();

两个工厂类继承OrderPizza并实现抽象方法:

public class LDOrderPizza extends OrderPizza {
       Pizza createPizza(String ordertype) {
              Pizza pizza = null;
              if (ordertype.equals("cheese")) {
                     pizza = new LDCheesePizza();
              } else if (ordertype.equals("pepper")) {
                     pizza = new LDPepperPizza();
              }
              return pizza;
       }
}
public class NYOrderPizza extends OrderPizza {
 
	Pizza createPizza(String ordertype) {
		Pizza pizza = null;
 
		if (ordertype.equals("cheese")) {
			pizza = new NYCheesePizza();
		} else if (ordertype.equals("pepper")) {
			pizza = new NYPepperPizza();
		}
		return pizza;
 
	}
 
}

通过不同的工厂会得到不同的实例化的对象,PizzaStroe的代码如下:

public class PizzaStroe {
       public static void main(String[] args) {
              OrderPizza mOrderPizza;
              mOrderPizza = new NYOrderPizza();
       }
}

解决了简单工厂模式的问题:增加一个新的pizza产地(北京),只要增加一个BJOrderPizza类:

public class BJOrderPizza extends OrderPizza {
       Pizza createPizza(String ordertype) {
              Pizza pizza = null;
              if (ordertype.equals("cheese")) {
                     pizza = new LDCheesePizza();
              } else if (ordertype.equals("pepper")) {
                     pizza = new LDPepperPizza();
              }
              return pizza;
       }
}

其实这个模式的好处就是,如果你现在想增加一个功能,只需做一个实现类就OK了,无需去改动现成的代码。这样做,拓展性较好!

工厂方法存在的问题与解决方法:客户端需要创建类的具体的实例。简单来说就是用户要订纽约工厂的披萨,他必须去纽约工厂,想订伦敦工厂的披萨,必须去伦敦工厂。 当伦敦工厂和纽约工厂发生变化了,用户也要跟着变化,这无疑就增加了用户的操作复杂性。为了解决这一问题,我们可以把工厂类抽象为接口,用户只需要去找默认的工厂提出自己的需求(传入参数),便能得到自己想要产品,而不用根据产品去寻找不同的工厂,方便用户操作。这也就是我们接下来要说的抽象工厂模式。

抽象工厂模式

  • 定义:定义了一个接口用于创建相关或有依赖关系的对象族,而无需明确指定具体类。
  • 举例:(依然举pizza工厂的例子,pizza工厂有两个:纽约工厂和伦敦工厂)。
    工厂的接口:
public interface AbsFactory {
       Pizza CreatePizza(String ordertype) ;
}

工厂的实现:

public class LDFactory implements AbsFactory {
       @Override
       public Pizza CreatePizza(String ordertype) {
              Pizza pizza = null;
              if ("cheese".equals(ordertype)) {
                     pizza = new LDCheesePizza();
              } else if ("pepper".equals(ordertype)) {
                     pizza = new LDPepperPizza();
              }
              return pizza;
       }
}

PizzaStroe的代码如下:

public class PizzaStroe {
       public static void main(String[] args) {
              OrderPizza mOrderPizza;
              mOrderPizza = new OrderPizza("London");
       }
}

解决了工厂方法模式的问题:在抽象工厂中PizzaStroe中只需要传入参数就可以实例化对象。

工厂模式适用的场合

大量的产品需要创建,并且这些产品具有共同的接口

三种工厂模式的使用选择

简单工厂 : 用来生产同一等级结构中的任意产品。(不支持拓展增加产品)

工厂方法 :用来生产同一等级结构中的固定产品。(支持拓展增加产品)

抽象工厂 :用来生产不同产品族的全部产品。(支持拓展增加产品;支持增加产品族)

简单工厂的适用场合:只有伦敦工厂(只有这一个等级),并且这个工厂只生产三种类型的pizza:chesse,pepper,greak(固定产品)。

工厂方法的适用场合:现在不光有伦敦工厂,还增设了纽约工厂(仍然是同一等级结构,但是支持了产品的拓展),这两个工厂依然只生产三种类型的pizza:chesse,pepper,greak(固定产品)。

抽象工厂的适用场合:不光增设了纽约工厂(仍然是同一等级结构,但是支持了产品的拓展),这两个工厂还增加了一种新的类型的pizza:chinese pizza(增加产品族)。

所以说抽象工厂就像工厂,而工厂方法则像是工厂的一种产品生产线。因此,我们可以用抽象工厂模式创建工厂,而用工厂方法模式创建生产线。

总结

简单工厂模式就是建立一个实例化对象的类,在该类中对多个对象实例化。工厂方法模式是定义了一个创建对象的抽象方法,由子类决定要实例化的类。这样做的好处是再有新的类型的对象需要实例化只要增加子类即可。抽象工厂模式定义了一个接口用于创建对象族,而无需明确指定具体类。抽象工厂也是把对象的实例化交给了子类,即支持拓展。同时提供给客户端接口,避免了用户直接操作子类工厂。

标签:ordertype,模式,工厂,new,设计模式,public,pizza
From: https://www.cnblogs.com/De3pInSky/p/16930616.html

相关文章

  • 06.枚举与模式匹配
    定义枚举IP地址:IPv4、IPv6enumIpAddrKindf{V4,V6}枚举值letfour=lpAddrKind::V4;letsix=lpAddrKind::V6;将数据附加到枚举的变体中优点:......
  • LVS负载均衡集群--DR模式
    一、LVS-DR工作原理LVS-DR(LinuxVirtualServerDirectorServer)工作模式,是生产环境中最常用的一种工作模式。LVS-DR模式,DirectorServer作为群集的访问入口,不作为......
  • Java设计模式之 单例模式实验报告书
    目录Java​​​设计模式​​​之1​​​单例模式​​​实验报告书1*实验四:单例模式2一、实验目的2二、实验内容3三、实验步骤3Appconfige.java4Client.java43......
  • Java设计模式之 单例模式实验报告书
    目录Java​​​设计模式​​​之1​​​单例模式​​​实验报告书1*实验四:单例模式2一、实验目的2二、实验内容3三、实验步骤3Appconfige.java4Client.java43......
  • php不同运行模式(sapi)下清空内存缓冲池提前返回结果的实现
    if(PHP_SAPI=='cgi-fcgi'){echo$response;fastcgi_finish_request();}elseif(PHP_SAPI=='apache2handler'){header("Connection:cl......
  • 备忘录模式(Memento)
    支持回滚状态的一种模式。核心:创建一个拷贝对象进行备份。给数据对象两个方法:1、进行备份。2、回滚。需要备份的数据:publicclassDatas{privateint......
  • 观察者模式(Observer)
    多个观察者关注同一个目标,当目标发生改变时,观察者们可以收到消息。(立刻更新消息,或者想知道的时候更新消息。)实现:1、自定义观察者:观察者与目标有一致的状态属性,目标......
  • 【ClickHouse为什么这么快?】Hyperscan 超扫描算法:用于现代CPU的“快速-多模式”正则表
    ASIMDinstructionexecutesthesameoperationonmultipledatainparallel.ASIMDOperationASIMDoperationisperformedon multiplelanesoftwoSIMDregiste......
  • 17-设计模式
    typora-root-url:images一、概述​ 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。​ 设计模式免去我们自己再思考......
  • AcWing 1471. 牛奶工厂
    \(AcWing\)\(1471\).牛奶工厂一、题目描述牛奶生意正红红火火!农夫约翰的牛奶加工厂内有\(N\)个加工站,编号为\(1…N\),以及\(N−1\)条通道,每条连接某两个加工站。(......