【设计模式】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、简单工厂模式的缺点

优点:

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

缺点:

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

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

相关文章
|
27天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
3月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
29天前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
22天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
37 1
|
2月前
|
设计模式 安全 Java
C# 一分钟浅谈:设计模式之单例模式
【10月更文挑战第9天】单例模式是软件开发中最常用的设计模式之一,旨在确保一个类只有一个实例,并提供一个全局访问点。本文介绍了单例模式的基本概念、实现方式(包括饿汉式、懒汉式和使用 `Lazy<T>` 的方法)、常见问题(如多线程和序列化问题)及其解决方案,并通过代码示例详细说明了这些内容。希望本文能帮助你在实际开发中更好地应用单例模式,提高代码质量和可维护性。
36 1
|
2月前
|
设计模式 Java Kotlin
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。对于快速学习Kotlin语法,推荐查看“简洁”系列教程。本文重点介绍了构建者模式在Kotlin中的应用与改良,包括如何使用具名可选参数简化复杂对象的创建过程,以及如何在初始化代码块中对参数进行约束和校验。
26 3
|
3月前
|
设计模式 算法 安全
设计模式——模板模式
模板方法模式、钩子方法、Spring源码AbstractApplicationContext类用到的模板方法
设计模式——模板模式
|
2月前
|
设计模式 程序员 C#
C# 使用 WinForm MDI 模式管理多个子窗体程序的详细步骤
WinForm MDI 模式就像是有超能力一般,让多个子窗体井然有序地排列在一个主窗体之下,既美观又实用。不过,也要小心管理好子窗体们的生命周期哦,否则一不小心就会出现一些意想不到的小bug
135 0
|
3月前
|
设计模式 开发框架 前端开发
MVC 模式在 C# 中的应用
MVC(Model-View-Controller)模式是广泛应用于Web应用程序开发的设计模式,将应用分为模型(存储数据及逻辑)、视图(展示数据给用户)和控制器(处理用户输入并控制模型与视图交互)三部分,有助于管理复杂应用并提高代码可读性和维护性。在C#中,ASP.NET MVC框架常用于构建基于MVC模式的Web应用,通过定义模型、控制器和视图,实现结构清晰且易维护的应用程序。
55 2
|
3月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:如何提高代码的可维护性与扩展性在软件开发领域,PHP 是一种广泛使用的服务器端脚本语言。随着项目规模的扩大和复杂性的增加,保持代码的可维护性和可扩展性变得越来越重要。本文将探讨 PHP 中的设计模式,并通过实例展示如何应用这些模式来提高代码质量。
设计模式是经过验证的解决软件设计问题的方法。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理地使用设计模式可以显著提高代码的可维护性、复用性和扩展性。本文将介绍几种常见的设计模式,包括单例模式、工厂模式和观察者模式,并通过具体的例子展示如何在PHP项目中应用这些模式。