您当前的位置: 首页 >  unity

Peter_Gao_

暂无认证

  • 1浏览

    0关注

    621博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Unity设计模式之简单工厂模式、工厂方法模式和抽象工厂模式

Peter_Gao_ 发布时间:2020-07-15 19:04:43 ,浏览量:1

 

实例说明

某软件公司要基于C#语言开发一套图表库,该图表库可以为应用系统提供多种不同外观的图表,例如柱状图(HistogramChart)、饼状图(PieChart)、折线图(LineChart)等。该软件公司图表库设计人员希望为应用系统开发人员提供一套灵活易用的图表库,通过设置不同的参数即可得到不同类型的图表,而且可以较为方便地对图表库进行扩展,以便能够在将来增加一些新类型的图表。  现使用简单工厂模式来设计该图表库。 这里写图片描述  (1) Chart:抽象图表接口,充当抽象产品类  (2) HistogramChart:柱状图类,充当具体产品类  (3) PieChart:饼状图类,充当具体产品类  (4) LineChart:折线图类,充当具体产品类  (5) ChartFactory:图表工厂类,充当工厂类  (6) Program:客户端测试类

模式优点

实现了对象创建和使用的分离  客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可  通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性

模式缺点

模式缺点  工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响  增加系统中类的个数(引入了新的工厂类),增加了系统的复杂度和理解难度  系统扩展困难,一旦添加新产品不得不修改工厂逻辑  由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构,工厂类不能得到很好地扩展

工厂模式适用环境

工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂  客户端只知道传入工厂类的参数,对于如何创建对象并不关心

工厂模式也是封装的思想,把需要频繁创建实例的对象单独封装起来,用的时候可以简单的传给封装函数(工厂)一个标识符参数即可以(生产)得到一个需要的对象实例;

适应的场景:需要频繁复用到一个对象的实例时,可以创建一个生产此实例的工厂。(比如,车厂批量生产汽车,注意是批量,如果仅仅需要一辆车,则没必须搞个工厂,直接手动打造好了)

 

简单工厂模式

简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。

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

使用举例:

一个产品父类(接口):IWeapons

n个产品子类: WeaponFisrt,  WeaponSecond ...

一个静态工厂类: Factory, 返回一个产品类实例

public class Product : MonoBehaviour {
    /// 
    /// 简单工厂模式
    /// 定义一个共同接口,创建不同的对象,简化创建过程,创建与表示分离
    /// 
    // Use this for initialization
    void Start () {
          //根据不同的条件选择不同的攻击方式
        SimpleFactory.CreateAttack(2).Attack();    
       
    }

    // Update is called once per frame
    void Update () {
        
    }

 

 /// 
    /// 举例:游戏中根据不同的攻击范围选择不同的攻击武器
    /// 
    public interface IWeapons//武器接口
    {
        void Attack();
    }

 

  public class WeaponsFirst : IWeapons
    {      
        public virtual void Attack()
        {
            Debug.Log("刀");
        }
    }

 

   public class WeaponsSecond : IWeapons
    {
        public virtual void Attack()
        {
            Debug.Log("机枪");
        }
    }

 

///简单工厂管理

    public class SimpleFactory
    {
        public static IWeapons CreateAttack(int idx)
        {          
            switch (idx)
            {
                case 1:
                    return new WeaponsFirst();
                case 2:
                    return new WeaponsSecond();
                default:
                    return null;
            }
        }
    }
}

 

比如我们想生产两种饮料(农夫山泉和脉动),在不使用任何设计模式时是这样的:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Test : MonoBehaviour
{
 
    void Start()
    {
        Drink drink1 = Instantiate("农夫山泉");
        Drink drink2 = Instantiate("脉动");
    }
    private Drink Instantiate(string type)
    {
        Drink Drink = null;
        if (type.Equals("农夫山泉"))
        {
            Drink = new NongFuShanQuan();
        }
        else if (type.Equals("脉动"))
        {
            Drink = new MaiDong();
        }
        return Drink;
    }
}
public class Drink
{
    public int Id;
    public string content;
    /// 
    /// 构造函数创建饮料实体
    /// 
    public Drink()
    {
        GameObject g = new GameObject(this.GetType().FullName);
    }
 
}

 

public class NongFuShanQuan : Drink
{
    public NongFuShanQuan()
    {
        Id = 1;
        content = "500mL";
    }
}
public class MaiDong : Drink
{
    public MaiDong()
    {
        Id = 2;
        content = "450mL";
    }
}

我们把饮料对象的创建工作放在了Instantiate方法中,通过传入的参数来确定要创建的饮料对象。

简单工厂模式

简单工厂模式将Instantiate方法中的内容封装到一个新的简单工厂类中。

如此我们便可以通过简单工厂类来创建各种饮料。

当需要增加饮料品种时,只需要在简单工厂类里面做修改。(加上新的具体饮料类是都要处理的)

 

一个产品父类:Drink


public class Drink
{
    public int Id;
    public string content;
    /// 
    /// 构造函数创建饮料实体
    /// 
    public Drink()
    {
        GameObject g = new GameObject(this.GetType().FullName);
    }
 
}

N个产品子类:DrinkType1, DrinkType2 ...

public class NongFuShanQuan : Drink
{
    public NongFuShanQuan()
    {
        Id = 1;
        content = "500mL";
    }
}

public class MaiDong : Drink
{
    public MaiDong()
    {
        Id = 2;
        content = "450mL";
    }
}

 一个工厂类:Factory, 返回一个产品类实例


public class DrinkFactory
{
    public Drink Instantiate(string type)
    {
        Drink Drink = null;
        if (type.Equals("农夫山泉"))
        {
            Drink = new NongFuShanQuan();
        }
        else if (type.Equals("脉动"))
        {
            Drink = new MaiDong();
        }
        return Drink;
    }
}

测试调用类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Test : MonoBehaviour
{
 
    void Start()
    {
        DrinkFactory factory = new DrinkFactory();
        factory.Instantiate("农夫山泉");
        factory.Instantiate("脉动");
    }
}
工厂方法模式(单厂单品)

但是增加新的饮料品种我们觉得要修改的地方还是太多了,这样可拓展性比较差,于是工厂方法模式来了

一个产品父类:


public class Drink
{
    public int Id;
    public string content;
    /// 
    /// 构造函数创建饮料实体
    /// 
    public Drink()
    {
        GameObject g = new GameObject(this.GetType().FullName);
    }
 
}

 N个产品子类:


public class NongFuShanQuan : Drink
{
    public NongFuShanQuan()
    {
        Id = 1;
        content = "500mL";
    }
}
public class MaiDong : Drink
{
    public MaiDong()
    {
        Id = 2;
        content = "450mL";
    }
}

 

一个生产产品父类的工厂父类:


public abstract class DrinkFactory
{
    public abstract Drink Instantiate();
 
}

N个对应产品子类的工厂子类

public class NongFuShanQuanFactory : DrinkFactory
{
    public override Drink Instantiate()
    {
        return new NongFuShanQuan();
    }
}
public class MaiDongnFactory : DrinkFactory
{
    public override Drink Instantiate()
    {
        return new MaiDong();
    }
}

 

测试调用类:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Test : MonoBehaviour
{
 
    void Start()
    {
        DrinkFactory nongfushanquanfactory = new NongFuShanQuanFactory();
        DrinkFactory maidongfactory = new MaiDongnFactory();
 
        Drink nongfushanqaun = nongfushanquanfactory.Instantiate();
        Drink maidong = maidongfactory.Instantiate();
 
    }
}

工厂方法模式核心是专业的工厂生产专业的饮料,简单来讲就是脉动厂只生产脉动饮料,农夫山泉厂只生产农夫山泉。因此我们需要加入新的具体工厂类,并且各自实现父类工厂的生产方法。

 

但是一个工厂只生产一种饮料太奢侈了,我要生产两个或多个,而且我要开放生产每种饮料的方法,让客户自己选择。于是抽象工厂模式来了:

抽象工厂模式(单厂多品)

一个产品父类:


public class Drink
{
    public int Id;
    public string content;
    public Drink()
    {
        GameObject g = new GameObject(this.GetType().FullName);
    }
}

N个产品子类:


public class NongFuShanQuan : Drink
{
    public NongFuShanQuan()
    {
        Id = 1;
        content = "500mL";
    }
}
public class MaiDong : Drink
{
    public MaiDong()
    {
        Id = 2;
        content = "450mL";
    }
}
public class NongFuShanQuan_1000 : Drink
{
    public NongFuShanQuan_1000()
    {
        Id = 3;
        content = "1000mL";
    }
}
public class MaiDong_600 : Drink
{
    public MaiDong_600()
    {
        Id = 4;
        content = "600mL";
    }
}
 

 一个能生产多种产品的超级工厂父类:

public abstract class Factory
{
    public abstract Drink CreateMaiDong();
    public abstract Drink CreateNongFuShanQuan();
}

 N个超级子工厂


public class DrinkFactory : Factory
{
    public override Drink CreateMaiDong()
    {
        return new MaiDong();
    }

    public override Drink CreateNongFuShanQuan()
    {
        return new NongFuShanQuan();
    }
}
public class OtherDrinkFactory : Factory
{
    public override Drink CreateMaiDong()
    {
        return new MaiDong_600();
    }
 
    public override Drink CreateNongFuShanQuan()
    {
        return new NongFuShanQuan_1000();
    }
}

测试调用类:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
 
public class Test : MonoBehaviour
{
 
    void Start()
    {
        Factory factory = new DrinkFactory();
        Drink maidong = factory.CreateMaiDong();
        Drink nongfushanquan = factory.CreateNongFuShanQuan();
        Factory otherfactory = new OtherDrinkFactory();
        Drink coco = otherfactory.CreateMaiDong();
        Drink bear = otherfactory.CreateNongFuShanQuan();
    }
}

 

 

例二:

简单工厂模式
 

#include 
using namespace std;

enum PigType{PAIGE, ZHUBAJIE};

class Pig   //猪
{
public:
    virtual void getAbility(void) = 0;
};

class Paige : public Pig //佩奇
{
public:
    Paige()
    {
        cout            
关注
打赏
1664521772
查看更多评论
0.1130s