C# 设计模式(一)简单工厂模式(unity演示)

24 篇文章 1 订阅
11 篇文章 7 订阅

目录


  近来打算过一下设计模式那就从简单工厂模式开始吧。而使用设计模式就是为了提高“可维护”、“可复用”、“可扩展”来展开的。工厂模式可分为三类,即:简单工厂模式、工厂模式和抽象工厂模式。

一、简单工厂模式

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

  又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式(同属于创建型模式的还有工厂方法模式,抽象工厂模式,单例模式,建造者模式)。在简单工厂模式中,可以根据参数的不同返回不同类的实例。工厂类中根据条件决定一个接口由哪个具体产品类来实现(也就是由一个工厂对象来决定创建哪一种产品类的实例)。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

2、模式结构

这里写图片描述

从上图可以看出,简单工厂模式由三部分组成:具体工厂、具体产品和抽象产品。

  • 工厂类(Creator)角色:担任这个角色的是简单工厂模式的核心,含有与应用紧密相关的商业逻辑。工厂类在客户端的直接调用下创建产品对象,它往往由一个具体类实现。工厂类在客户端的直接控制下(Create方法)创建产品对象。
  • 抽象产品(AbstractProduct)角色:担任这个角色的类是由简单工厂模式所创建的对象的父类,或它们共同拥有的接口。抽象产品角色可以用一个接口或者抽象类实现。定义简单工厂创建的对象的父类或它们共同拥有的接口。可以是一个类、抽象类或接口。
  • 具体产品(ConcreteProduct)角色:简单工厂模式所创建的任何对象都是这个角色的实例,具体产品角色由一个具体类实现。定义工厂具体加工出的对象。
3、模式动机

  使用简单工厂模式可以将产品的“消费”和生产完全分开,客户端只需要知道自己需要什么产品,如何来使用产品就可以了,具体的产品生产任务由具体的工厂类来实现。工厂类根据传进来的参数生产具体的产品供消费者使用。这种模式使得更加利于扩展,当有新的产品加入时仅仅需要在工厂中加入新产品的构造就可以了。

4、实例分析

  计算器栗子,如:
这里写图片描述

Operation运算类:

public class Operation
{
    private double _numA = 0;
    private double _numB = 0;
    
    public double NumA
    {
        get { return _numA; }
        set { _numA = value; }
    }

    public double NumB
    {
        get { return _numB; }
        set { _numB = value; }
    }

    public virtual double GetResult()
    {
        double result = 0;
        return result;
    }
}

加减乘除类

class OperationAdd : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = NumA + NumB;
        return result;
    }
}

class OperationSub : Operation
{
    public override double GetResult()
    {
        double res = 0;
        res = NumB + NumA;
        return res;
    }
}

class OperationMul : Operation
{
    public override double GetResult()
    {
        double res = 0;
        res = NumB * NumA;
        return res;
    }
}

class OperationDiv : Operation
{
    public override double GetResult()
    {
        double result = 0;
        if (NumB !=0)
        {
            result = NumA / NumB;
        }
        return result;
    }
}

工厂类

public class OperationFactory
{
    public static Operation createOperate(string operate)
    {
        Operation oper = null;
        switch (operate)
        {
            case "+":
                oper = new OperationAdd();
                break;
            case "-":
                oper = new OperationSub();
                break;
            case "*":
                oper = new OperationMul();
                break;
            case "/":
                oper = new OperationDiv();
                break;
        }
        return oper;
    }
}

  调用实例,只需要传入运算符号,工厂就能实例化出合适的对象,通过多态来返回父类的方式获得了计算结果。

Operation oper;
oper = OperationFactory.createOperate("+");
oper.NumA = 1;
oper.NumB = 2;
double res = oper.GetResult();

  那么后期需要修改运算方式只需修改相应的运算就可以了。如果需要增加运算只需要添加运算子类,增加工厂类的分支即可。

5、优点
  • 工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例。它提供了专门的工厂类用于创建对象。
  • 无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
  • 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
  • 当需要引入新的产品是不需要修改客户端的代码,只需要添加相应的产品类并修改工厂类就可以了,所以说从产品的角度上简单工厂模式是符合“开-闭”原则的。
6、缺点
  • 由于工厂类集中了所有产品创建逻辑,工厂类一般被我们称作“全能类”或者“上帝类”,因为所有的产品创建他都能完成,这看似是好事,但仔细想想是有问题的。比如全国上下所有的事情都有国家主席一个人干会不会有问题,当然有!一旦不能正常工作,整个系统都要受到影响。
  • 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
  • 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。所以说从工厂的角度来说简单工厂模式是不符合“开-闭”原则的。
  • 简单工厂模式由于使用了static静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
7、适用场景
  • 工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
  • 只知道传入工厂类的参数,对于如何创建对象不关心:既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。

二、工厂(方法)模式

1、工厂方法模式(Factory Method)

  工厂模式又叫工厂方法模式(Factory Method):是一种常用的对象创建型设计模式,此模式的核心精神是封装类中不变的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。它的核心结构有四个角色,分别是抽象工厂、具体工厂、抽象产品、具体产品。

2、工厂方法模式简介

  工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
  工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。
  工厂方法模式对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不再负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。
  工厂方法模式(Factory Method pattern)是最典型的模板方法模式(Template Method pattern)应用。

3、工厂方法模式角色结构

  结构模式如下:
这里写图片描述

  • 抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
  • 具体工厂(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。在上图中有两个这样的角色:BulbCreator与TubeCreator。
  • 抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在上图中,这个角色是Light。
  • 具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。
4、使用步骤
  • 步骤1: 创建抽象工厂类,定义具体工厂的公共接口;
  • 步骤2: 创建抽象产品类 ,定义具体产品的公共接口;
  • 步骤3: 创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
  • 步骤4:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
  • 步骤5:外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例
5、实例讲解
5.1 问题描述
  • 背景:小成有一间塑料加工厂(仅生产A类产品);随着客户需求的变化,客户需要生产B类产品;
  • 冲突:改变原有塑料加工厂的配置和变化非常困难,假设下一次客户需要再发生变化,再次改变将增大非常大的成本;
  • 解决方案:小成决定置办塑料分厂B来生产B类产品;
即工厂方法模式
5.2 使用步骤
  • 步骤1: 创建抽象工厂类,定义具体工厂的公共接口
abstract class Factory
{
	public abstract Product Manufacture();
}
  • 步骤2: 创建抽象产品类 ,定义具体产品的公共接口;
abstract class Product
{
    public abstract void Show();
}
  • 步骤3: 创建具体产品类(继承抽象产品类), 定义生产的具体产品;
/// <summary>
/// 具体产品A类
/// </summary>
class ProductA : Product
{
    public override void Show()
    {
        Console.WriteLine("生产出了产品A");
    }
}

/// <summary>
/// 具体产品B类
/// </summary>
class ProductB : Product
{
    public override void Show()
    {
        Console.WriteLine("生产出了产品B");
    }
}
  • 步骤4:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
/// <summary>
/// 工厂A类 - 生产A类产品
/// </summary>
class FactoryA : Factory
{
    public override Product Manufacture()
    {
        return new ProductA();
    }
}

/// <summary>
/// 工厂B类 - 生产B类产品
/// </summary>
class FactoryB : Factory
{
    public override Product Manufacture()
    {
        return new ProductB();
    }
}
  • 步骤5:外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例
//生产工作流程
//客户要产品A
FactoryA mFactoryA = new FactoryA();
mFactoryA.Manufacture().Show();

//客户要产品B
FactoryB mFactoryB = new FactoryB();
mFactoryB.Manufacture().Show();
  • 结果
生产出了产品A
生产出了产品B
6、工厂方法模式优点
  • 更符合开-闭原则
    新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可
简单工厂模式需要修改工厂类的判断逻辑
  • 符合单一职责原则
    每个具体工厂类只负责创建对应的产品
简单工厂中的工厂类存在复杂的switch逻辑判断
  • 不使用静态工厂方法,可以形成基于继承的等级结构。
简单工厂模式的工厂类使用静态工厂方法

  总结:工厂模式可以说是简单工厂模式的进一步抽象和拓展,在保留了简单工厂的封装优点的同时,让扩展变得简单,让继承变得可行,增加了多态性的体现。

7、工厂方法模式缺点
  • 添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,系统类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,有更多的类需要编译和运行,会给系统带来一些额外的开销;
  • 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
  • 虽然保证了工厂方法内的对修改关闭,但对于使用工厂方法的类,如果要更换另外一种产品,仍然需要修改实例化的具体工厂类;
  • 一个具体工厂只能创建一种具体产品
8、工厂方法模式适用场景
  • 当一个类不知道它所需要的对象的类时
    在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可;
  • 当一个类希望通过其子类来指定创建对象时
    在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
  • 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。

三、抽象工厂模式

1、抽象工厂模式(Abstract Factory)

  前面介绍了工厂方法模式,工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码),而工厂方法模式每个具体工厂类只完成单个实例的创建,所以它具有很好的可扩展性。但是在现实生活中,一个工厂只创建单个产品这样的例子很少,因为现在的工厂都多元化了,一个工厂创建一系列的产品,如果我们要设计这样的系统时,工厂方法模式显然在这里不适用,然后抽象工厂模式却可以很好地解决一系列产品创建的问题,这是本专题所要介绍的内容。
  抽象工厂模式(Abstract Factory)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

2、抽象工厂模式(Abstract Factory)详细介绍

  这里首先以一个生活中抽象工厂的例子来实现一个抽象工厂,然后再给出抽象工厂的定义和UML图来帮助大家更好地掌握抽象工厂模式,同时大家在理解的时候,可以对照抽象工厂生活中例子的实现和它的定义来加深抽象工厂的UML图理解。

2.1 抽象工厂模式 Abstract Factory)问题描述

  下面就以生活中 “绝味” 连锁店的例子来实现一个抽象工厂模式。例如,绝味鸭脖想在江西南昌和上海开分店,但是由于当地人的口味不一样,在南昌的所有绝味的东西会做的辣一点,而上海不喜欢吃辣的,所以上海的所有绝味的东西都不会做的像南昌的那样辣,然而这点不同导致南昌绝味工厂和上海的绝味工厂生成所有绝味的产品都不同,也就是某个具体工厂需要负责一系列产品(指的是绝味所有食物)的创建工作,下面就具体看看如何使用抽象工厂模式来实现这种情况。

2.2 抽象工厂模式 Abstract Factory)具体实现
/// <summary>
/// 抽象工厂类,提供创建两个不同地方的鸭架和鸭脖的接口
/// </summary>
public abstract class AbstractFactory
{
    // 抽象工厂提供创建一系列产品的接口,这里作为例子,只给出了绝味中鸭脖和鸭架的创建接口
    public abstract YaBo CreateYaBo();
    public abstract YaJia CreateYaJia();
}

/// <summary>
/// 南昌绝味工厂负责制作南昌的鸭脖和鸭架
/// </summary>
public class NanChangFactory : AbstractFactory
{
    // 制作南昌鸭脖
    public override YaBo CreateYaBo()
    {
        return new NanChangYaBo();
    }
    // 制作南昌鸭架
    public override YaJia CreateYaJia()
    {
        return new NanChangYaJia();
    }
}

/// <summary>
/// 上海绝味工厂负责制作上海的鸭脖和鸭架
/// </summary>
public class ShangHaiFactory : AbstractFactory
{
    // 制作上海鸭脖
    public override YaBo CreateYaBo()
    {
        return new ShangHaiYaBo();
    }
    // 制作上海鸭架
    public override YaJia CreateYaJia()
    {
        return new ShangHaiYaJia();
    }
}

/// <summary>
/// 鸭脖抽象类,供每个地方的鸭脖类继承
/// </summary>
public abstract class YaBo
{
    /// <summary>
    /// 打印方法,用于输出信息
    /// </summary>
    public abstract void Print();
}

/// <summary>
/// 鸭架抽象类,供每个地方的鸭架类继承
/// </summary>
public abstract class YaJia
{
    /// <summary>
    /// 打印方法,用于输出信息
    /// </summary>
    public abstract void Print();
}

/// <summary>
/// 南昌的鸭脖类,因为江西人喜欢吃辣的,所以南昌的鸭脖稍微会比上海做的辣
/// </summary>
public class NanChangYaBo : YaBo
{
    public override void Print()
    {
        Console.WriteLine("南昌的鸭脖");
    }
}

/// <summary>
/// 上海的鸭脖没有南昌的鸭脖做的辣
/// </summary>
public class ShangHaiYaBo : YaBo
{
    public override void Print()
    {
        Console.WriteLine("上海的鸭脖");
    }
}

/// <summary>
/// 南昌的鸭架
/// </summary>
public class NanChangYaJia : YaJia
{
    public override void Print()
    {
        Console.WriteLine("南昌的鸭架子");
    }
}

/// <summary>
/// 上海的鸭架
/// </summary>
public class ShangHaiYaJia : YaJia
{
    public override void Print()
    {
        Console.WriteLine("上海的鸭架子");
    }
}

下面是调用实例:

// 南昌工厂制作南昌的鸭脖和鸭架
AbstractFactory nanChangFactory = new NanChangFactory();
YaBo nanChangYabo = nanChangFactory.CreateYaBo();
nanChangYabo.Print();
YaJia nanChangYajia = nanChangFactory.CreateYaJia();
nanChangYajia.Print();

// 上海工厂制作上海的鸭脖和鸭架
AbstractFactory shangHaiFactory = new ShangHaiFactory();
shangHaiFactory.CreateYaBo().Print();
shangHaiFactory.CreateYaJia().Print();
2.3 抽象工厂模式 (Abstract Factory)的定义和类图

  上面代码中都有详细的注释,这里就不再解释上面的代码了,下面就具体看看抽象工厂模式的定义吧(理解定义可以参考上面的实现来加深理解)

抽象工厂模式 Abstract Factory)
提供一个创建产品的接口来负责创建相关或依赖的对象,而不具体明确指定具体类

  抽象工厂允许客户使用抽象的接口来创建一组相关产品,而不需要知道或关心实际生产出的具体产品是什么。这样客户就可以从具体产品中被解耦。下面通过抽象工模式的类图来了解各个类中之间的关系:
这里写图片描述

2.4 抽象工厂模式 (Abstract Factory)应对需求变更

  看完上面抽象工厂的实现之后,如果 “绝味”公司又想在湖南开一家分店怎么办呢? 因为湖南人喜欢吃麻辣的,下面就具体看看应用了抽象工厂模式的系统是如何应对这种需求的。

/// <summary>
/// 如果绝味又想开一家湖南的分店时,因为湖南喜欢吃麻的
/// 所以这是有需要有一家湖南的工厂专门制作
/// </summary>
public class HuNanFactory : AbstractFactory
{
    // 制作湖南鸭脖
    public override YaBo CreateYaBo()
    {
        return new HuNanYaBo();
    }

    // 制作湖南鸭架
    public override YaJia CreateYaJia()
    {
        return new HuNanYajia();
    }
}

/// <summary>
/// 湖南的鸭脖
/// </summary>
public class HuNanYaBo : YaBo
{
    public override void Print()
    {
        Console.WriteLine("湖南的鸭脖");
    }
}

/// <summary>
/// 湖南的鸭架
/// </summary>
public class HuNanYajia : YaJia
{
    public override void Print()
    {
        Console.WriteLine("湖南的鸭架子");
    }
}

  此时,只需要添加三个类:一个是湖南具体工厂类,负责创建湖南口味的鸭脖和鸭架,另外两个类是具有湖南口味的鸭脖类和鸭架类。从上面代码看出,抽象工厂对于系列产品的变化支持 “开放——封闭”原则(指的是要求系统对扩展开放,对修改封闭),扩展起来非常简便,但是,抽象工厂对于添加新产品这种情况就不支持”开放——封闭 “原则,这也是抽象工厂的缺点所在,这点会在后面详细介绍。

3、抽象工厂模式(Abstract Factory)的分析

  抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展,这正是抽象工厂模式的优点所在,然而抽象模式同时也存在不足的地方。下面就具体看下抽象工厂的缺点(缺点其实在前面的介绍中以已经涉及了):
  抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。

4、抽象工厂模式(Abstract Factory)适用场景

  知道了抽象工厂的优缺点之后,也就能很好地把握什么情况下考虑使用抽象工厂模式了,下面就具体看看使用抽象工厂模式的系统应该符合那几个前提:

  • 一个系统不要求依赖产品类实例如何被创建、组合和表达的表达,这点也是所有工厂模式应用的前提;
  • 这个系统有多个系列产品,而系统中只消费其中某一系列产品;
  • 系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现。
5、.NET中抽象工厂模式实现

  抽象工厂模式在实际中的应用也是相当频繁的,然而在我们.NET类库中也存在应用抽象工厂模式的类,这个类就是System.Data.Common.DbProviderFactory,这个类位于System.Data.dll程序集中,该类扮演抽象工厂模式中抽象工厂的角色,我们可以用reflector反编译工具查看该类的实现:

/// 扮演抽象工厂的角色
/// 创建连接数据库时所需要的对象集合,
/// 这个对象集合包括有 DbConnection对象(这个是抽象产品类,如绝味例子中的YaBo类)、DbCommand类、DbDataAdapter类,针对不同的具体工厂都需要实现该抽象类中方法,
public abstract class DbProviderFactory
{
	// 提供了创建具体产品的接口方法
	protected DbProviderFactory();
	public virtual DbCommand CreateCommand();
	public virtual DbCommandBuilder CreateCommandBuilder();
	public virtual DbConnection CreateConnection();
	public virtual DbConnectionStringBuilder CreateConnectionStringBuilder();
	public virtual DbDataAdapter CreateDataAdapter();
	public virtual DbDataSourceEnumerator CreateDataSourceEnumerator();
	public virtual DbParameter CreateParameter();
	public virtual CodeAccessPermission CreatePermission(PermissionState state);
}

四、模式应用举例(unity)

1、简单工厂模式实例:

抽象产品基类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/// <summary>
/// 资源管理器基类,抽象产品
/// </summary>
public abstract class ResouceManager
{
	public abstract void LoadConfig(string path);
	public abstract void LoadAsset(string name);
	public abstract void UnLoadResource(bool status);
}

产品实例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

/// <summary>
/// UI资源管理器,抽象产品的具体产品
/// </summary>
public class UIResouceManager : ResouceManager
{
    public override void LoadConfig(string path)
    {
        Debug.Log("加载UI的配置文件");
    }
    public override void LoadAsset(string name)
    {
        Debug.Log("加载UI里面的资源");
    }
    public override void UnLoadResource(bool status)
    {
        Debug.Log("卸载加载的UI资源");
    }
}

产品实例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

/// <summary>
/// Audio资源管理器,抽象产品的具体产品
/// </summary>
public class AudioResourceManager : ResouceManager
{
    public override void LoadConfig(string path)
    {
        Debug.Log("加载和音乐有关的配置文件");
    }
    public override void LoadAsset(string name)
    {
        Debug.Log("加载音乐文件");
    }
    public override void UnLoadResource(bool status)
    {
        Debug.Log("卸载加载的音乐文件");
    }
}

产品枚举:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


/// <summary>
/// 定义资源枚举类型
/// </summary>
public enum ResourceEnum
{
    None,
    UIResource,
    AudioResouce
}

工厂:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


/// <summary>
/// 简单资源工厂类,负责创建UI,Audio等管理器的实例。
/// </summary>
public class ResouceSimpleFactory
{
    // 方式一
    public ResouceManager CreateManager(string type)
    {
        if (type == "UI")
        {
            return new UIResouceManager();
        }
        else if (type == "Audio")
        {
            return new AudioResourceManager();
        }
        else
        {
            return null;
        }
    }
    //方式二
    public ResouceManager CreateManager(ResourceEnum re)
    {
        switch (re)
        {
            case ResourceEnum.UIResource:
                return new UIResouceManager();
            case ResourceEnum.AudioResouce:
                return new AudioResourceManager();
            default:
                return null;
        }
    }
}

客户端测试:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;


/// <summary>
/// 使用资源管理器的客户端
/// </summary>
public class ResouceSimpleFactoryClient : MonoBehaviour
{
    ResouceSimpleFactory rf;
    public void Start()
    {
        rf = new ResouceSimpleFactory();
    }
    public void OnGUI()
    {
        if (GUILayout.Button("UI管理器"))
        {
            ResouceManager ui = rf.CreateManager("UI");
            ui.LoadConfig("http:.......");
            ui.LoadAsset("UI...");
            ui.UnLoadResource(false);
        }
        if (GUILayout.Button("Audio管理器"))
        {
            ResouceManager am = rf.CreateManager("Audio");
            am.LoadConfig("http:.....");
            am.LoadAsset("声音...");
            am.UnLoadResource(false);
        }
    }
}
2、工厂方法模式实例:

工厂方法模式的 抽象产品类:

/// <summary>
/// 工厂方法模式的抽象产品类,由具体的产品类继承实现
/// </summary>
public abstract class ResourceManager
{
    public abstract void LoadConfig(string path);
    public abstract void LoadAsset(string name);
    public abstract void UnLoadResource(bool status);
}

工厂方法模式的 抽象工厂:

/// <summary>
/// 简单方法模式的抽象工厂,由具体工厂来继承实现
/// </summary>
public abstract class CreatorResourceFactory
{
    public abstract ResourceManager CreateFactory();
}

工厂方法模式的 具体产品实现-UI资源管理产品类:

using UnityEngine;

/// <summary>
/// 工厂方法模式抽象产品的具体产品实现-UI资源管理产品类
/// </summary>
public class UIResourceManager : ResourceManager
{
    public override void LoadConfig(string path)
    {
        Debug.Log("加载UI有关的配置文件");
    }
    public override void LoadAsset(string name)
    {
        Debug.Log("加载UI文件");
    }
    public override void UnLoadResource(bool status)
    {
        Debug.Log("卸载加载的UI文件");
    }
}

工厂方法模式的 具体工厂实现-UI资源管理工厂:

/// <summary>
/// 简单方法模式里面的具体产品工厂-UI资源管理工厂
/// </summary>
public class UIResouceManagerFactory : CreatorResourceFactory
{
    public override ResourceManager CreateFactory()
    {
        return new UIResourceManager();
    }
}

工厂方法模式的 的具体产品实现-音频资源管理产品类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

/// <summary>
/// 工厂方法模式抽象产品的具体产品实现-音频资源管理产品类
/// </summary>
public class AudioResouceManager : ResourceManager
{
    public override void LoadConfig(string path)
    {
        Debug.Log("加载和音乐有关的配置文件");
    }
    public override void LoadAsset(string name)
    {
        Debug.Log("加载音乐文件");
    }
    public override void UnLoadResource(bool status)
    {
        Debug.Log("卸载加载的音乐文件");
    }
}

工厂方法模式的 具体工厂-音频资源管理工厂:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/// <summary>
/// 简单方法模式里面的具体工厂-音频资源管理工厂
/// </summary>
public class AudioResouceManagerFactory : CreatorResourceFactory
{
    public override ResourceManager CreateFactory()
    {
        return new AudioResouceManager();
    }
}

客户端测试类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

public class ResouceFactoryMethodClient : MonoBehaviour
{
    #region 定义具体产品工厂
    CreatorResourceFactory audioFactory;
    CreatorResourceFactory uiFactory;
    #endregion
    #region 定义具体产品
    AudioResouceManager audioManager;
    UIResourceManager uiManager;
    #endregion
    void Start()
    {
        audioFactory = new AudioResouceManagerFactory();
        uiFactory = new UIResouceManagerFactory();
    }
    void OnGUI()
    {
        if (GUILayout.Button("音乐管理器"))
        {
            audioManager = audioFactory.CreateFactory() as AudioResouceManager;
            audioManager.LoadConfig("http:....");
            audioManager.LoadAsset("声音...");
            audioManager.UnLoadResource(false);
        }
        if (GUILayout.Button("界面管理器"))
        {
            uiManager = uiFactory.CreateFactory() as UIResourceManager;
            uiManager.LoadConfig("http:....");
            uiManager.LoadAsset("UI...");
            uiManager.UnLoadResource(false);
        }
    }
}
3、抽象工厂模式实例:

  抽象工厂:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 定义抽象工厂
/// </summary>
public abstract class ResourceAbstractFactory
{
	public abstract UIResourceAbstract CreateUIManager();
	public abstract AudioResoucesAbstract CreateAudioManager();
}

  抽象工厂的中抽象产品类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 定义音乐资源抽象类
/// </summary>
public abstract class AudioResoucesAbstract
{
    public abstract void LoadConfig(string path);
    public abstract void LoadAsset(string name);
    public abstract void UnLoadResource(bool status);
}

  抽象工厂的中抽象产品类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 定义UI资源的抽象类
/// </summary>
public abstract class UIResourceAbstract
{
    public abstract void LoadConfig(string path);
    public abstract void LoadAsset(string name);
    public abstract void UnLoadResource(bool status);
}

  具体工厂类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PrimaryManagerFactory : ResourceAbstractFactory
{
    public override UIResourceAbstract CreateUIManager()
    {
        return new PrimaryUIManager();
    }

    public override AudioResoucesAbstract CreateAudioManager()
    {
        return new PrimaryAudioManager();
    }
}

  具体工厂类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
///定义抽象工厂的具体工厂AssistantManagerFactory
/// </summary>
public class AssistantManagerFactory : ResourceAbstractFactory
{
    public override UIResourceAbstract CreateUIManager()
{
        return new AssistantUIManager();
}
 
    public override AudioResoucesAbstract CreateAudioManager()
    {
        return new AssistantAudioManager();
    }
}

  具体产品类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 定义UI抽象类的具体产品PrimaryUIManager
/// </summary>
public class PrimaryUIManager : UIResourceAbstract
{
    public override void LoadConfig(string path)
    {
        Debug.Log("PrimaryUIManager: " + path);
    }

    public override void LoadAsset(string name)
    {
        Debug.Log("PrimaryUIManager: " + name);
    }

    public override void UnLoadResource(bool status)
    {
        Debug.Log("PrimaryUIManager: " + status);
    }
}

  具体产品类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 定义Audio抽象类的具体产品PrimaryAudioManager
/// </summary>
public class PrimaryAudioManager : AudioResoucesAbstract
{
    public override void LoadConfig(string path)
    {
        Debug.Log("PrimaryAudioManager:" + path);
    }

    public override void LoadAsset(string name)
    {
        Debug.Log("PrimaryAudioManager: " + name);
    }

    public override void UnLoadResource(bool status)
    {
        Debug.Log("PrimaryAudioManager: " + status);
    }
}

  具体产品类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AssistantAudioManager : AudioResoucesAbstract
{
    public override void LoadConfig(string path)
    {
        Debug.Log("AssistantAudioManager: " + path);
    }

    public override void LoadAsset(string name)
    {
        Debug.Log("AssistantAudioManager: " + name);
    }

    public override void UnLoadResource(bool status)
    {
        Debug.Log("AssistantAudioManager: " + status);
    }
}

  具体产品类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 抽象产品的具体产品AssignmentUIManager
/// </summary>
public class AssistantUIManager : UIResourceAbstract
{
    public override void LoadConfig(string path)
    {
        Debug.Log("AssistantUIManager:" + path);
    }

    public override void LoadAsset(string name)
    {
        Debug.Log("AssistantUIManager:" + name);
    }

    public override void UnLoadResource(bool status)
    {
        Debug.Log("AssistantUIManager:" + status);
    }
}

  客户端测试类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ResourceAbstractFactoryClient : MonoBehaviour
{
    ResourceAbstractFactory rfPrimary;
    AudioResoucesAbstract audioPrimry;
    UIResourceAbstract uiPrimary;

    ResourceAbstractFactory rfAssistant;
    AudioResoucesAbstract audioAssistant;
    UIResourceAbstract uiAssistant;

    void Start()
    {
        rfPrimary = new PrimaryManagerFactory();
        rfAssistant = new AssistantManagerFactory();
    }

    void OnGUI()
    {
        if (GUILayout.Button("主城产品族"))
        {
            audioPrimry = rfPrimary.CreateAudioManager();
            audioPrimry.LoadConfig("http:...");
            audioPrimry.LoadAsset("主城...");
            audioPrimry.UnLoadResource(false);

            uiPrimary = rfPrimary.CreateUIManager();
            uiPrimary.LoadConfig("http:...");
            uiPrimary.LoadAsset("主城...");
            uiPrimary.UnLoadResource(false);
        }

        if (GUILayout.Button("副城产品族"))
        {
            audioAssistant = rfAssistant.CreateAudioManager();
            audioAssistant.LoadConfig("http:...");
            audioAssistant.LoadAsset("副城...");
            audioAssistant.UnLoadResource(false);

            uiAssistant = rfAssistant.CreateUIManager();
            uiAssistant.LoadConfig("http:...");
            uiAssistant.LoadAsset("副城...");
            uiAssistant.UnLoadResource(false);
        }
    }
}

   搞懂了以上这些再添加动画管理类是不是就很简单了。
  GoF23设计模式里面的每种模式都是针对某类特定问题的解决策略。So,没有什么设计模式是完美的!
   Tips:告诉大家一个小秘密,简单工厂模式实际上不是GoF23设计模式的一员哦!


The End
  好了,今天的分享就到这里,如有不足之处,还望大家及时指正,随时欢迎探讨交流!!!


喜欢的朋友们,请帮顶、点赞、评论!您的肯定是我写作的不竭动力!

相关阅读
C# 23种设计模式(unity演示)

  • 9
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

对酒当歌﹏✍

您的鼓励是我写作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值