编程语言爱好者.NET

《C#设计模式》-简单工厂模式

2020-05-03  本文已影响0人  张中华

简单工厂模式是最简单的设计模式之一,它虽然属于GoF的23种设计模式,但是应用也较为频繁,同时它也是学习其他创建型模式的基础。在简单工厂模式中,只需要记住一个简单的参数即可获得所需的对象实例,它提供专门的核心工厂类来负责对象的创建,实现对象的创建和使用分离。
创建型模式对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离,对用户隐藏了类的实例创建细节。
每一个创建型模式都通过采用不同的解决方案来回答3个问题:创建什么(What), 由谁创建(Who)和何时创建(When)。

简单工厂模式概述

首先将需要创建的各种不同产品对象的相关代码封装到不同的类中,这些类称为具体产品类,而将它们公共的代码进行抽象和提取后封装在一个抽象产品类中,每一个具体产品类都是抽象产品类的子类;然后提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的工厂方法,该方法可以根据所传入的参数的不同创建不同的具体产品对象;客户端只需要调用工厂类的工厂方法并传入相应的参数即可得到一个产品对象。

定义

简单工厂模式(Simple Factory Patter): 定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。

由于在简单工厂模式中用于创建实例的方法通常是静态方法,所以简单工厂模式又被称为静态工厂方法模式,它是一类创建型模式。

简单工厂模式的结构与实现

简单工厂模式结构图

简单工厂模式包含以下3个角色:

简单工厂模式的实现

抽象工厂类:

public abstract class Product
    {
        // 所有产品类的公共业务方法
        public void MethodSame()
        {
            Console.WriteLine("处理公共业务方法");
        }
        // 声明抽象业务方法
        public abstract void MethidDiff();
    }

具体工厂类A:

    {
        // 实现业务方法
        public override void MethidDiff()
        {
            Console.WriteLine("具体产品A处理业务方法");
        }
    }

具体工厂类B:

    public class ConcreteProduceB: Product
    {
        // 实现业务方法
        public override void MethidDiff()
        {
            Console.WriteLine("具体产品B处理业务方法");
        }
    }

简单工厂模式的核心,工厂类:

    public class Factory
    {
        // 静态工厂方法
        public static Product GetProduct(string arg) =>
            arg switch
            {
                "A" => new ConcreteProduceA(),
                "B" => new ConcreteProduceB(),
                _ => throw new ArgumentException(message: "invalid arg value"),
            };
    }

客户端调用:

            // 简单工厂模式
            var productA = Factory.GetProduct("A");
            productA.MethodSame();
            productA.MethidDiff();

            var productB = Factory.GetProduct("B");
            productB.MethodSame();
            productB.MethidDiff();
测试结果

由示例可以看出,必须通过修改客户端代码中静态方法的参数来更换具体产品对象,客户端代码需要重新编译,这对于客户端而言,违背了开闭原则。
下面介绍一种常用的解决方案,利用App.config配置文件的方式,提高系统的灵活性。只需要添加配置文件和修改客户端使用方式即可。
代码示例:
App.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="Product" value="A" />
  </appSettings>
</configuration>

调用方式:

            // 简单工厂模式 + 配置文件
            var type = System.Configuration.ConfigurationManager.AppSettings["product"]; 
            var productA = Factory.GetProduct(type);
            productA.MethodSame();
            productA.MethidDiff();
测试结果

有时为了简化简单工厂模式,可以将抽象产品类和工厂类合并,将静态工厂方法移到抽象产品类中,根据不同的参数创建不同类型的产品子类对象,这种方法在很多类库和框架中也广泛存在。
代码示例:

 public abstract class Product
    {
        // 静态工厂方法
        public static Product GetProduct(string arg) =>
            arg switch
            {
                "A" => new ConcreteProduceA(),
                "B" => new ConcreteProduceB(),
                _ => throw new ArgumentException(message: "invalid arg value"),
            };
        // 所有产品类的公共业务方法
        public void MethodSame()
        {
            Console.WriteLine("处理公共业务方法");
        }
        // 声明抽象业务方法
        public abstract void MethidDiff();
    }

调用方式:

            // 简单工厂模式 + 配置文件 + 合共抽象产品类和工厂类
            var type = System.Configuration.ConfigurationManager.AppSettings["product"];
            var productA = Product.GetProduct(type);
            productA.MethodSame();
            productA.MethidDiff();
测试结果

简单工厂模式的优缺点与适用环境

简单工厂的优点
简单工厂模式的缺点
简单工厂模式的适用环境

如果觉得文章写得还行,请点个赞。如果想与我进一步交流,可以关注我的公众号或者加我的微信。

个人微信
公众号_DotNet微说.jpg
上一篇下一篇

猜你喜欢

热点阅读