【愚公系列】2021年12月 二十三种设计模式(零)-简单工厂模式(Simple Factory Pattern)

简介: 【愚公系列】2021年12月 二十三种设计模式(零)-简单工厂模式(Simple Factory Pattern)

文章目录

前言

一、简单工厂模式(Simple Factory Pattern)

二、使用步骤

角色

示例

总结

优点

缺点

使用场景

前言

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。


提示:以下是本篇文章正文内容,下面案例可供参考


一、简单工厂模式(Simple Factory Pattern)

简单工厂模式属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GoF设计模式之一。学习简单工厂模式是学习其它工厂模式的前提条件。


简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。


二、使用步骤

角色

1、工厂(Creator)


简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象;


2、抽象产品(Product)


简单工厂模式所创建的所有对象的抽象基类,它负责描述所有实例所共有的公共接口;


3、具体产品(Concrete Product)


这是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。


示例

image.png


命名空间SimpleFactory中包含抽象水果基类Fruit、三个具体水果类、水果工厂类FruitFactory、未知水果异常类UnknowFruitException。本案例将向大家展示如何使用简单工厂模式来生产不同种类的水果。

public abstract class Fruit {
    protected Color Color { get; set; } = Color.Orange;
    protected abstract string BornInfo();
    protected const string LINE_BREAK =
        "------------------------------------------------------------";
    public void WhatsFruit() {
        Console.WriteLine("Printing!");
        OnPrint();
        Console.WriteLine("Printed!");
        OnPrinted();
    }
    protected virtual void OnPrint() {
        Console.WriteLine($"I'm a(n) {this.ToString().Replace(nameof(SimpleFactory) + ".", "")} " +
                            $"with {Color.ToString()} and I born in {BornInfo()}!");
    }
    protected virtual void OnPrinted() {
        Console.WriteLine(LINE_BREAK);
    }
}

抽象水果基类Fruit 包含颜色Color属性、出生信息BornInfo抽象方法、这是什么水果WhatsFruit方法、打印水果OnPrint和打印完OnPrinted方法。

public class Apple : Fruit {
    public Apple() {
        Color = Color.Red;
    }
    protected override string BornInfo() => "summer";
    protected override void OnPrint() {
        Console.WriteLine($"I'm an apple with {Color.ToString()},not an IPhone!");
    } 
}
public class Orange : Fruit {
    protected override string BornInfo() => "autumn";
    protected override void OnPrinted() {
        Console.WriteLine("override OnPrinted()!");
        Console.WriteLine(LINE_BREAK);
    }
}
public class Pear : Fruit {
    public Pear() {
        Color = Color.Yellow;
    }
    protected override string BornInfo() => "China";
}

具体水果类,苹果Apple类、橘子Orange类和梨子Pear类,各自实现或重写不同的构造函数、抽象方法、虚拟方法和属性。

public enum FruitType {
    Unknow = -1,
    Apple,
    Orange,
    Pear
}
public static class FruitFactory {
    public static Fruit CreateFruit(FruitType type) {
        Fruit fruit = null;
        switch (type) {
            case FruitType.Apple:
                fruit = new Apple();
                break;
            case FruitType.Orange:
                fruit = new Orange();
                break;
            case FruitType.Pear:
                fruit = new Pear();
                break;
            default:
                throw new UnknowFruitException();
        }
        return fruit;
    }
}

水果工厂类FruitFactory,该类是简单工厂的核心类,包含CreateFruit方法,传递FruitType参数以便确定产出何种水果。方法返回抽象水果基类,以便调用方使用基类变量接受返回值。

public class UnknowFruitException : Exception {
    public UnknowFruitException()
        : base("Not Supported Fruit!") {
    }
    public UnknowFruitException(string message, Exception innerException)
        : base(message, innerException) {
    }
}


使用未知水果异常类UnknowFruitException,进行简单的异常处理。

public static void Main(string[] args) {
    try {
        var fruit = FruitFactory.CreateFruit(FruitType.Pear);
        fruit.WhatsFruit();
        fruit = FruitFactory.CreateFruit(FruitType.Apple);
        fruit.WhatsFruit();
        fruit = FruitFactory.CreateFruit(FruitType.Orange);
        fruit.WhatsFruit();
        fruit = FruitFactory.CreateFruit(FruitType.Unknow);
        fruit.WhatsFruit();
    }
    catch (UnknowFruitException ex) {
        Console.WriteLine(nameof(UnknowFruitException) + ":" + ex.Message);
    }
    catch (Exception ex) {
        Console.WriteLine(nameof(Exception) + ":" + ex.Message);
    }
    Console.ReadKey();
}

调用方用变量fruit接受水果工厂不同的产出,由WhatsFruit方法在控制台打印出水果信息,用catch分别处理不同类型的异常。以下是这个案例的输出结果:

Printing!
I'm a(n) Pear with Color [Yellow] and I born in China!
Printed!
-----------------------------------------------------------
Printing!
I'm an apple with Color [Red],not an IPhone!
Printed!
-----------------------------------------------------------
Printing!
I'm a(n) Orange with Color [Orange] and I born in autumn!
Printed!
override OnPrinted()!
-----------------------------------------------------------
UnknowFruitException:Not Supported Fruit!

总结

优点

1、工厂类是整个模式最核心的部分,包含了对象的创建逻辑。调用者无需关心对象创建的细节,只要给出参数,就可以得到相应的对象;

2、他们之间相互独立,各司其职,有利于整个软件体系架构。


缺点

1、由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则;

2、将全部创建逻辑集中到了一个工厂类中,如果需要添加新的类,则就需要改变工厂类了,明显违反开闭原则。工厂方法模式中这个问题有一定程度的缓解。


使用场景

1、工厂类负责创建的对象比较少;

2、客户只知道传入工厂类的参数,对于创建对象的细节不关心或无法知道;

3、由于简单工厂很容易违反高内聚责任分配原则,所以在实际开发中很少用到。


相关文章
|
5月前
|
设计模式
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
这篇文章详细解释了工厂模式,包括简单工厂、工厂方法和抽象工厂三种类型。每种模式都通过代码示例展示了其应用场景和实现方法,并比较了它们之间的差异。简单工厂模式通过一个工厂类来创建各种产品;工厂方法模式通过定义一个创建对象的接口,由子类决定实例化哪个类;抽象工厂模式提供一个创建相关或依赖对象家族的接口,而不需要明确指定具体类。
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
|
5月前
|
设计模式 Java
设计模式--适配器模式 Adapter Pattern
这篇文章介绍了适配器模式,包括其基本介绍、工作原理以及类适配器模式、对象适配器模式和接口适配器模式三种实现方式。
|
9月前
|
设计模式 安全 Java
【设计模式】JAVA Design Patterns——Curiously Recurring Template Pattern(奇异递归模板模式)
该文介绍了一种C++的编程技巧——奇异递归模板模式(CRTP),旨在让派生组件能继承基本组件的特定功能。通过示例展示了如何创建一个`Fighter`接口和`MmaFighter`类,其中`MmaFighter`及其子类如`MmaBantamweightFighter`和`MmaHeavyweightFighter`强制类型安全,确保相同重量级的拳手之间才能进行比赛。这种设计避免了不同重量级拳手间的错误匹配,编译时会报错。CRTP适用于处理类型冲突、参数化类方法和限制方法只对相同类型实例生效的情况。
|
8月前
|
设计模式
设计模式-05建造者模式(Builder Pattern)
设计模式-05建造者模式(Builder Pattern)
|
9月前
|
设计模式
设计模式之工厂 Factory
设计模式之工厂 Factory
74 1
|
2月前
|
设计模式 前端开发 搜索推荐
前端必须掌握的设计模式——模板模式
模板模式(Template Pattern)是一种行为型设计模式,父类定义固定流程和步骤顺序,子类通过继承并重写特定方法实现具体步骤。适用于具有固定结构或流程的场景,如组装汽车、包装礼物等。举例来说,公司年会节目征集时,蜘蛛侠定义了歌曲的四个步骤:前奏、主歌、副歌、结尾。金刚狼和绿巨人根据此模板设计各自的表演内容。通过抽象类定义通用逻辑,子类实现个性化行为,从而减少重复代码。模板模式还支持钩子方法,允许跳过某些步骤,增加灵活性。
126 11
|
3月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
16天前
|
设计模式
「全网最细 + 实战源码案例」设计模式——模式扩展(配置工厂)
该设计通过配置文件和反射机制动态选择具体工厂,减少硬编码依赖,提升系统灵活性和扩展性。配置文件解耦、反射创建对象,新增产品族无需修改客户端代码。示例中,`CoffeeFactory`类加载配置文件并使用反射生成咖啡对象,客户端调用时只需指定名称即可获取对应产品实例。
76 40
|
17天前
|
设计模式 关系型数据库
「全网最细 + 实战源码案例」设计模式——简单工厂模式
简单工厂模式是一种创建型设计模式,通过工厂类根据传入参数创建不同类型的对象,也称“静态工厂方法”模式。其结构包括工厂类、产品接口和具体产品类。优点是封装性强、代码复用性好;缺点是扩展性差,增加新产品时需修改工厂类代码,违反开闭原则。适用于对象种类较少且调用者无需关心创建细节的场景。
49 19
|
5月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。