设计模式-创建型-工厂模式

工厂设计模式:

  顾名思义,该模式是用来生产对象的。在面向对象的设计模式中,万物皆对象,若使用new来创建对象,就会对该对象产生强耦合,加入我们需要更换该对象,那么使用该对象的对象都需要进行修改,这显然违背了开闭原则(OCP)。如果我们使用工厂来产生对象,我们只需要与这个工厂打交道就可以了,无需关心具体的对象,达到解耦的目的。

  接下来我们从实际的案例出发,从无工厂到有工厂的区别。

  去披萨店订购披萨,首先披萨的种类很多(CheesePizza、GreekPizza、DurianPizza{等),披萨的制作流程有prepare、bake、cut、box。

传统模式:

  

 1 internal class Program
 2 {
 3     private static void Main(string[] args)
 4     {
 5         new OrderPizza();
 6     }
 7 }
 8
 9 internal class OrderPizza
10 {
11     public OrderPizza()
12     {
13         Pizza pizza = null;
14         string orderType = "";
15         do
16         {
17             orderType = Console.ReadLine();
18             if (orderType == "cheese")
19             {
20                 pizza = new CheesePizza();
21                 pizza.setName("芝士披萨");
22             }
23             else if (orderType == "greek")
24             {
25                 pizza = new GreekPizza();
26                 pizza.setName("希腊披萨");
27             }
28             else
29             {
30                 Console.WriteLine("订购失败");
31                 break;
32             }
33             //开始制作
34             pizza.prepare();
35             pizza.bake();
36             pizza.cut();
37             pizza.box();
38         } while (true);
39     }
40 }
41
42 internal abstract class Pizza
43 {
44     private string name;
45
46     public abstract void prepare();
47
48     public void bake()
49     {
50         Console.WriteLine($"{this.name} 烘培");
51     }
52
53     public void cut()
54     {
55         Console.WriteLine($"{this.name} 修剪");
56     }
57
58     public void box()
59     {
60         Console.WriteLine($"{this.name} 打包");
61     }
62
63     public void setName(string name)
64     {
65         this.name = name;
66     }
67 }
68
69 internal class CheesePizza : Pizza
70 {
71     public override void prepare()
72     {
73         Console.WriteLine("芝士披萨准备中");
74     }
75 }
76
77 internal class GreekPizza : Pizza
78 {
79     public override void prepare()
80     {
81         Console.WriteLine("希腊披萨准备中");
82     }
83 }

view code

  传统模式的优缺点:

    1、比较好理解,易于操作

    2、违反OCP原则,即对扩展开放,对修改关闭。

    3、这里只订购了两种pizza,若现在又新增了品种DurianPizza,这个时候就需要添加该类以及修改OrderPizza中的代码。从上图中可以看出,OrderPizza依赖抽象类及具体实现类的,那怎样才能切断OrderPizza与类之间的依赖关系呢。于是我们想到,可以定义一个工厂,订购者不需要知道具体pizza的制作流程,只要直到我需要订购什么类型的pizza就行了。

简单工厂模式:

  

  1 internal class Program
  2 {
  3     private static void Main(string[] args)
  4     {
  5         new OrderPizza();
  6     }
  7 }
  8
  9 internal class OrderPizza
 10 {
 11     public OrderPizza()
 12     {
 13         Pizza pizza = null;
 14         string orderType = "";
 15         do
 16         {
 17             Console.Write("请输入订购类型:");
 18             orderType = Console.ReadLine();
 19             pizza = SimpleFactory.createPizza(orderType);
 20             if (pizza == null)
 21             {
 22                 Console.WriteLine("订购失败");
 23                 break;
 24             }
 25             //开始制作
 26             pizza.prepare();
 27             pizza.bake();
 28             pizza.cut();
 29             pizza.box();
 30         } while (true);
 31     }
 32 }
 33
 34 internal static class SimpleFactory
 35 {
 36     public static Pizza createPizza(string orderType)
 37     {
 38         Pizza pizza = null;
 39         do
 40         {
 41             if (orderType == "cheese")
 42             {
 43                 pizza = new CheesePizza();
 44                 pizza.setName("芝士披萨");
 45             }
 46             else if (orderType == "greek")
 47             {
 48                 pizza = new GreekPizza();
 49                 pizza.setName("希腊披萨");
 50             }
 51             else if (orderType == "durian")
 52             {
 53                 pizza = new DurianPizza();
 54                 pizza.setName("榴莲披萨");
 55             }
 56             return pizza;
 57         } while (true);
 58     }
 59 }
 60
 61 internal abstract class Pizza
 62 {
 63     private string name;
 64
 65     public abstract void prepare();
 66
 67     public void bake()
 68     {
 69         Console.WriteLine($"{this.name} 烘培");
 70     }
 71
 72     public void cut()
 73     {
 74         Console.WriteLine($"{this.name} 修剪");
 75     }
 76
 77     public void box()
 78     {
 79         Console.WriteLine($"{this.name} 打包");
 80     }
 81
 82     public void setName(string name)
 83     {
 84         this.name = name;
 85     }
 86 }
 87
 88 internal class CheesePizza : Pizza
 89 {
 90     public override void prepare()
 91     {
 92         Console.WriteLine("芝士披萨准备中");
 93     }
 94 }
 95
 96 internal class GreekPizza : Pizza
 97 {
 98     public override void prepare()
 99     {
100         Console.WriteLine("希腊披萨准备中");
101     }
102 }
103
104 internal class DurianPizza : Pizza
105 {
106     public override void prepare()
107     {
108         Console.WriteLine("榴莲披萨准备中");
109     }
110 }

view code

  简单工厂模式优缺点:

    1、由代码可以看出,虽然简单工厂模式一定程度上减少了因需求变更而导致的代码更改,但是实际仍违背了OCP原则。

    2、所以简单工厂模式只适合产品对象相对较少,且产品固定的需求,对产品变化无常的需求来说显然不适合。

工厂方法设计模式:

  披萨项目需求变更,客户点披萨时可以点不同口味的披萨。

  

  1 internal class Program
  2 {
  3     private static void Main(string[] args)
  4     {
  5         new BJOrderPizza();
  6     }
  7 }
  8
  9 internal abstract class OrderPizza
 10 {
 11     public OrderPizza()
 12     {
 13         Pizza pizza = null;
 14         string orderType = "";
 15         do
 16         {
 17             Console.Write("请输入订购类型:");
 18             orderType = Console.ReadLine();
 19             pizza = createPizza(orderType);
 20             if (pizza == null)
 21             {
 22                 Console.WriteLine("订购失败");
 23                 break;
 24             }
 25             //开始制作
 26             pizza.prepare();
 27             pizza.bake();
 28             pizza.cut();
 29             pizza.box();
 30         } while (true);
 31     }
 32
 33     public abstract Pizza createPizza(string orderType);
 34 }
 35
 36 internal class BJOrderPizza : OrderPizza
 37 {
 38     public override Pizza createPizza(string orderType)
 39     {
 40         Pizza pizza = null;
 41         if (orderType == "cheese")
 42         {
 43             pizza = new BJCheesePizza();
 44         }
 45         else if (orderType == "greek")
 46         {
 47             pizza = new BJGreekPizza();
 48         }
 49         return pizza;
 50     }
 51 }
 52
 53 internal class LDOrderPizza : OrderPizza
 54 {
 55     public override Pizza createPizza(string orderType)
 56     {
 57         Pizza pizza = null;
 58         if (orderType == "cheese")
 59         {
 60             pizza = new LDCheesePizza();
 61         }
 62         else if (orderType == "greek")
 63         {
 64             pizza = new LDGreekPizza();
 65         }
 66         return pizza;
 67     }
 68 }
 69
 70 internal abstract class Pizza
 71 {
 72     private string name;
 73
 74     public abstract void prepare();
 75
 76     public void bake()
 77     {
 78         Console.WriteLine($"{this.name} 烘培");
 79     }
 80
 81     public void cut()
 82     {
 83         Console.WriteLine($"{this.name} 修剪");
 84     }
 85
 86     public void box()
 87     {
 88         Console.WriteLine($"{this.name} 打包");
 89     }
 90
 91     public void setName(string name)
 92     {
 93         this.name = name;
 94     }
 95 }
 96
 97 internal class BJCheesePizza : Pizza
 98 {
 99     public override void prepare()
100     {
101         Console.WriteLine("北京的芝士披萨准备中");
102     }
103 }
104
105 internal class BJGreekPizza : Pizza
106 {
107     public override void prepare()
108     {
109         Console.WriteLine("北京的希腊披萨准备中");
110     }
111 }
112
113 internal class LDCheesePizza : Pizza
114 {
115     public override void prepare()
116     {
117         Console.WriteLine("伦敦的芝士披萨准备中");
118     }
119 }
120
121 internal class LDGreekPizza : Pizza
122 {
123     public override void prepare()
124     {
125         Console.WriteLine("伦敦的希腊披萨准备中");
126     }
127 }

view code

  工厂方法模式的优缺点:

    1、让父类的实现延迟到子类中去,减少判断。

    2、换汤不换药,和简单工程模式类似,一般适用于产品对象相对较少,且产品固定的需求。

    3、工厂方法一定程度上减轻了工厂的职责,将职责细化,避免工厂类无法正常运行而导致程序崩溃。

参考:https://www.jianshu.com/p/38493eb4ffbd

原文地址:https://www.cnblogs.com/az4215/p/11516734.html

时间: 2024-10-10 05:04:29

设计模式-创建型-工厂模式的相关文章

JAVA设计模式(01):创建型-工厂模式【工厂方法模式】(Factory Method)

简单工厂模式尽管简单,但存在一个非常严重的问题.当系统中须要引入新产品时,因为静态工厂方法通过所传入參数的不同来创建不同的产品,这必然要改动工厂类的源码,将违背"开闭原则".怎样实现添加新产品而不影响已有代码?工厂方法模式应运而生,本文将介绍另外一种工厂模式--工厂方法模式. 1 日志记录器的设计 Sunny软件公司欲开发一个系统执行日志记录器(Logger).该记录器能够通过多种途径保存系统的执行日志,如通过文件记录或数据库记录,用户能够通过改动配置文件灵活地更换日志记录方式. 在设

设计模式之创建型工厂模式

通过对产品类的抽象使其创建业务主要负责用于创建多类产品的实例.创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象.定义一个创建对象的接口,让其子类决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行,最终生成复杂对象.主要解决接口选择的问题. 您需要一辆汽车,可以直接从工厂里提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现. var PageFactory = function(type, content) { if(this instan

设计模式-创建型-原型模式

引言: 原型模式是什么?它是在什么场景下被提出的呢?本章节,我们将详细了解下原型模式. 在软件系统中,当创建一个类的实例过程过于昂贵或复杂,并且我们需要创建多个这样类的实例时,如果我们通过new来创建类实例,这就会增加创建类的复杂度和创建过程与客户代码复杂的耦合度.如果采用工厂模式来创建这样的实例对象的话,随着产品类的不断增加,导致子类的数量不断增多,也导致了相应工厂类的增加,维护的代码维度增加了,因为有产品和工厂两个维度了,反而增加了系统复杂程度,所以在这里使用工厂模式来封装类创建过程并不合适

【C#设计模式——创建型模式】抽象工厂模式

抽象工厂模式比工厂模式具有更高层次的抽象性.当要返回一系列相关类中的某一个,而每个类都能根据需要返回不同的对象时,可以选择这种模式.直接进入示例. 示例描述:完成花园的规划,多种花园种类,每个里面多种植物 编写一个基类Garden,Garden就是抽象工厂.它定义了具体类中的方法,并返回一系列相关类中的某个类. public class Garden { protected Plant center, shade, border; protected bool showCenter, showS

C#设计模式之三抽象工厂模式(AbstractFactory)【创建型】

原文:C#设计模式之三抽象工厂模式(AbstractFactory)[创建型] 一.引言 写了3篇有关设计模式的文章了,大家有了些反馈,说能从中学到一些东西,我感到很欣慰,那就继续努力.今天我要写第四个模式了,该模式叫抽象工厂.上一篇文章我们讲了[工厂方法]模式,它是为了解决[简单工厂]模式所面对的问题,它的问题就是:如果我们增加新的产品,工厂类的方法就要修改本身的代码,增加产品越多,其逻辑越复杂,同时这样的修改也是不符合[开放关闭原则OCP],对修改代码关闭,对增加代码开放.为了解决[简单工厂

JDK 源码 阅读 - 2 - 设计模式 - 创建型模式

A.创建型模式 抽象工厂(Abstract Factory) javax.xml.parsers.DocumentBuilderFactory DocumentBuilderFactory通过FactoryFinder实例化具体的Factory. 使用例子: DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docBuilder

设计模式——创建型模式

简单的说我们可以把23种设计模式可以归为三大类,分别是创建型模式.结构型模式和行为型模式. 今天,首先看一下创建型模式.创建型设计模式包括5种:单例模式(Singleton).工厂方法模式(Factory Method).抽象工厂模式(Abstract Factory).建造者模式(Builder).原型模式(Prototype).  1.单例模式(Singleton)        1)简介 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式是一种常用的软件设计模式.在它的核心结

C#设计模式-创建型模式(转)

一.简单工厂模式 简单工厂模式Simple Factory,又称静态工厂方法模式.它是类的创建模式.是由一个工厂对象决定创建出哪一种产品类的实例,是不同的工厂方法模式的一个特殊实现. 优点: u 模式的核心是工厂类,该类中含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅负责"消费"产品. u 简单工厂模式实现了对责任的分割. 缺点: u 当产品类有复杂的多层次等级结构时,工厂类只有它自己.以不变应万变. u 模式中工厂类集中了所

【C#设计模式——创建型模式】工场方法模式

工场方法模式对简单工场模式进行了乔庙的扩展,不是用一个专门的类来决定实例化哪一个子类.相反,超类把这种决定延迟到每个子类.这种模式实际上没有决策点,就是没有直接选择一个子类实例化的决策. 看书上的例子有点复杂,自己写了一个简单例子: 示例目标:对数组进行定向排序 基类FormatList对指定数组进行排序,具体实现交给子类实现 public abstract class FormatList { public int[] result; protected abstract void Forma