【设计模式】C#实现简单工厂模式

简介: 工厂模式总结三个要点:1、不想直接new这个类的对象,防止这个类改变的时候在new的地方到处去改,麻烦且容易遗漏;2、这个类的对象构建过程非常复杂,不想在代码的各个地方将这么复杂的构建过程反复书写;3、这个类的对象在构建过程中依赖了很多其他的类,而你无法在调用的地方提供。

1、概述

工厂模式总结三个要点:

  • 不想直接new这个类的对象,防止这个类改变的时候在new的地方到处去改,麻烦且容易遗漏;
  • 这个类的对象构建过程非常复杂,不想在代码的各个地方将这么复杂的构建过程反复书写;
  • 这个类的对象在构建过程中依赖了很多其他的类,而你无法在调用的地方提供。

2、结构

简单工厂包含如下角色:

  • 抽象产品 :定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品 :实现或者继承抽象产品的子类
  • 具体工厂 :提供了创建产品的方法,调用者通过该方法来获取产品。

3、背景

需求:设计一个披萨点餐系统。

设计一个披萨类(Pizza),并定义其两个子类(奶酪披萨【CheessPizza】和希腊披萨【GreekPizza】);再设计一个披萨店类(PizzaStore),披萨店具有点披萨的功能。

首先,我们先实现上述的需求。

//1.抽象产品
public abstract class Pizza
    {
        //名字
        public string Name;

        //准备原材料
        public abstract void Prepare();

        public void Bake()
        {
            Console.WriteLine($"{this.Name} bake");
        }

        public void Cut()
        {
            Console.WriteLine($"{this.Name} cut");
        }

        public void Box()
        {
            Console.WriteLine($"{this.Name} box");
        }

    }

//2.具体产品
public class CheessPizza : Pizza
    {
        public override void Prepare()
        {
            Console.WriteLine("CheessPizza 准备原材料");
        }
    }

//2.具体产品
public class GreekPizza : Pizza
    {
        public override void Prepare()
        {
            Console.WriteLine("GreekPizza 准备原材料");
        }
    }

//3.产品商店
    public class PizzaStore
    {
        public static Pizza OrderPizza(string type)
        {
            Pizza pizza = null;
            switch (type)
            {
                case "greek":
                    pizza = new GreekPizza();
                    pizza.Name = "希腊披萨";
                    break;
                case "cheess":
                    pizza = new CheessPizza();
                    pizza.Name = "奶酪披萨";
                    break;
                default:
                    break;
            }
            pizza.Prepare();
            pizza.Bake();
            pizza.Cut();
            pizza.Box();
            return pizza;
        }
    }

class Program
    {
        static void Main(string[] args)
        {
            PizzaStore.OrderPizza("greek");
            PizzaStore.OrderPizza("cheess");
        }
    }

此时,如果我们要新增一个披萨商店,那个就需要增加一个【PizzaStore1】类;当我们要增加一款新的披萨产品(水果披萨【FruitPizza】)时, 我们要去修改每一个披萨商店的OrderPizza方法,也就是产品类和商店类耦合,违反了开闭原则(对于扩展是开放的,但是对于修改是封闭的);

那么有没有办法将产品类和商店类解耦呢?答案是有的,就是引入工厂模式。

4、简单工厂模式

我们首先引入简单工厂,

//具体工厂
public class PizzaSimpleFactory
    {
        public static Pizza CreatPizza(string type)
        {
            Pizza pizza = null;
            switch (type)
            {
                case "greek":
                    pizza = new GreekPizza();
                    pizza.Name = "希腊披萨";
                    break;
                case "cheess":
                    pizza = new CheessPizza();
                    pizza.Name = "奶酪披萨";
                    break;
                default:
                    break;
            }
            pizza.Prepare();
            pizza.Bake();
            pizza.Cut();
            pizza.Box();
            return pizza;
        }
    }
//产品商店
public class PizzaStore
    {
        public static Pizza OrderPizza(string type)
        {
            Pizza pizza = PizzaSimpleFactory.CreatPizza(type);
            return pizza;
        }
    }

可以看出,简单工厂模式的出现,使得我们通过传入不同的参数类型就可以创建不同类型的对象实例,将对象的构建过程完全交给了简单工厂方法类SimpleFactory。我们要增加一款新的披萨产品(水果披萨【FruitPizza】)时,只需要修改【PizzaSimpleFactory】。

一旦有了PizzaSimpleFactory,PizzaStore类中的OrderPizza()就变成此对象的客户,后期如果需要Pizza对象直接从工厂中获取即可。这样也就解除了和Pizza实现类的耦合,同时又产生了新的耦合,PizzaStore对象和SimplePizzaFactory工厂对象的耦合,工厂对象和商品对象的耦合。

但是,后期如果再加新品种的咖啡,我们势必要需求修改SimpleCoffeeFactory的代码,违反了开闭原则。

5、简单工厂模式的缺点

优点:

封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,这样以后就避免了修改客户代码,如果要实现新产品直接修改工厂类,而不需要在原代码中修改,这样就降低了客户代码修改的可能性,更加容易扩展。

缺点:

增加新产品时还是需要修改工厂类的代码,同样违背了“开闭原则”。

为了克服简单工厂模式的缺点,工厂方法模式就被提了出来,我们下篇文章再介绍。

相关文章
|
22天前
|
设计模式 SQL 算法
设计模式了解哪些,模版模式
设计模式了解哪些,模版模式
21 0
|
1月前
|
设计模式 Java uml
C++设计模式之 依赖注入模式探索
C++设计模式之 依赖注入模式探索
37 0
|
3月前
|
数据采集 API 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPISDK设置软件触发模式(C#)
Baumer工业相机堡盟工业相机如何通过NEOAPISDK设置软件触发模式(C#)
40 1
|
2月前
|
设计模式 前端开发 JavaScript
观察者模式 vs 发布-订阅模式:两种设计模式的对决!
欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。
|
18天前
|
设计模式 Java 数据库
小谈设计模式(2)—简单工厂模式
小谈设计模式(2)—简单工厂模式
|
3天前
|
设计模式 消息中间件 Java
Java 设计模式:探索发布-订阅模式的原理与应用
【4月更文挑战第27天】发布-订阅模式是一种消息传递范式,被广泛用于构建松散耦合的系统。在 Java 中,这种模式允许多个对象监听和响应感兴趣的事件。
17 2
|
6天前
|
设计模式 存储 JavaScript
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
|
6天前
|
设计模式 Java Go
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式
|
8天前
|
设计模式
设计模式(一)简单工厂模式
设计模式(一)简单工厂模式
13 0
|
18天前
|
设计模式 Java
小谈设计模式(9)—工厂方法模式
小谈设计模式(9)—工厂方法模式