单例模式
单例模式比较简单
以下代码重点演示单例的会是同一个地址,返回同一个哈希值
using System .Collections ;using System .Collections .Generic ;using UnityEngine ;public class MySingleton { private static MySingleton instance ; public static MySingleton Instance { get { if (instance == null ) instance = new MySingleton (); return instance ; } } private MySingleton () { Debug .Log ("构造函数执行" ); } public void Show () { Debug .Log ("Show" ); } }public class DesignPattern : MonoBehaviour { // Start is called before the first frame update void Start () { MySingleton single1 = MySingleton .Instance ; single1 .Show (); Debug .Log (single1 .GetHashCode ()); MySingleton single2 = MySingleton .Instance ; single2 .Show (); Debug .Log (single2 .GetHashCode ()); MySingleton single3 = MySingleton .Instance ; single3 .Show (); Debug .Log (single3 .GetHashCode ()); //以上这三个对象指向同一个地址 } }
观察者模式
代码示例:
using System .Collections ;using System .Collections .Generic ;using UnityEngine ;using System ;//这里介绍观察者模式 //例子是:猫来了,所有的老鼠开始逃跑 public class Animal { protected string strName ; public Animal (string name ) { this .strName = name ; } public virtual void Run () { } }public class Cat : Animal { public Action action ;//发布者 public Cat (string name ):base (name )//构造函数 { } public void Coming (/*Animal mouseA, Animal mouseB, Animal mouseC*/ ) { Debug .Log (strName + "来了" ); //mouseA.Run(); //mouseB.Run(); //mouseC.Run(); //在没有观察者模式的时候需要挨个调用 if (action != null ) action ();//触发事件;通过多播委托完成一对多的关系 this .Run (); } public override void Run ()//函数的重载 { Debug .Log (strName + "开始追" ); } }public class Mouse : Animal { public Mouse (string name , Cat cat ):base (name ) { cat .action += this .Run ;//订阅者 } public override void Run ()//事件处理器 { Debug .Log ( strName + "开始逃跑" ); } }public class ObserverPattern : MonoBehaviour { // Start is called before the first frame update void Start () { Cat cat = new Cat ("小野猫" ); Animal mouseA = new Mouse ("mouseA" , cat ); Animal mouseB = new Mouse ("mouseB" , cat ); Animal mouseC = new Mouse ("mouseC" , cat ); Animal mouseD = new Mouse ("mouseD" , cat ); //cat.Coming(mouseA, mouseB, mouseC); cat .Coming (); } }
运行结果:
以下代码展示观察者模式和非观察者模式的写法差异
//普通写法 //缺点在于如果后续需要新增相应的对象,那么每次都需要在cat的函数中手动新增响应对象 public class Cat : Animal { public Cat (string name ):base (name )//构造函数 { } public void Coming (Animal mouseA , Animal mouseB , Animal mouseC ) { Debug .Log (strName + "来了" ); mouseA .Run (); mouseB .Run (); mouseC .Run (); this .Run (); } public override void Run ()//函数的重载 { Debug .Log (strName + "开始追" ); } }//观察者模式的写法 public class Cat : Animal { public Action action ; public Cat (string name ):base (name )//构造函数 { } public void Coming (Animal mouseA , Animal mouseB , Animal mouseC ) { Debug .Log (strName + "来了" ); if (action != null ) action ();//在Mouse的构造函数中将其Run方法注册给这个cat的 this .Run (); } public override void Run ()//函数的重载 { Debug .Log (strName + "开始追" ); } }public class Mouse : Animal { public Mouse (string name , Cat cat ):base (name ) { cat .action += this .Run ;//订阅者 } public override void Run ()//事件处理器 { Debug .Log ( strName + "开始逃跑" ); } }
工厂家族
简单工厂模式
关键词:创建型模式,本质上是一种静态工厂方法模式(Static Factory Method)
主要思想:
我们创建了两个脚本,包含四个类:
MouseProduct:父类,还有两个品牌的子类Dell和HP
MainFactory:一个MainFactory类+一个SimpleFactory类,SimpleFactory类在MainFactory中进行调用;其中SimpleFactory类中还用到了一个枚举
MouseProduct脚本:
using System .Collections ;using System .Collections .Generic ;using UnityEngine ;namespace MouseManufactoring { public abstract class MouseProduct { public abstract void Print (); } public class DellMouse : MouseProduct { public override void Print () { Debug .Log ("生产了一个戴尔鼠标" ); } } public class HpMouse : MouseProduct { public override void Print () { Debug .Log ("生产了一个HP鼠标" ); } } }
MainFactory脚本:
using System .Collections ;using System .Collections .Generic ;using UnityEngine ;using MouseManufactoring ;public enum MouseType { DellMouse , HpMouse ,};public class MainFactory : MonoBehaviour { void Start () { RunFactoryMode (); } public void RunNormal () { DellMouse dellMouse = new DellMouse (); dellMouse .Print (); HpMouse hpMouse = new HpMouse (); hpMouse .Print (); } public void RunFactoryMode () { SimpleFactory simpleFactory = new SimpleFactory ();//将简单工厂实例化 simpleFactory .CreateMouse (MouseType .DellMouse ).Print (); simpleFactory .CreateMouse (MouseType .HpMouse ).Print (); } }public class SimpleFactory { public MouseProduct CreateMouse (MouseType type ) { MouseProduct mouse = null ; switch (type ) { case MouseType .DellMouse : mouse = new DellMouse (); break ; case MouseType .HpMouse : mouse = new HpMouse (); break ; } return mouse ; } }
也可以做如下改造使得可以控制生产的品牌:
public enum MouseType { DellMouse , HpMouse ,};public class MainFactory : MonoBehaviour { public MouseType brand ; void Start () { RunFactoryMode (brand ); } public void RunNormal () { DellMouse dellMouse = new DellMouse (); dellMouse .Print (); HpMouse hpMouse = new HpMouse (); hpMouse .Print (); } public void RunFactoryMode (MouseType type ) { SimpleFactory simpleFactory = new SimpleFactory ();//将简单工厂实例化 simpleFactory .CreateMouse (type ).Print (); } }
缺陷:简单工厂模式如果需要再增加一个产品,需要新建一个类、枚举,并且需要修改CreateMouse的方法,违背了开闭原则。
工厂模式
关键词:解决简单工厂模式中,新增产品品牌的时候,需要直接修改工厂类的问题。
解决了简单工厂模式中出现的开闭原则问题,一个中间件只能生产一种产品。以下展示了简单工厂和工厂模式的区别。
本次我们创建了3个脚本:
产品脚本:由一个抽象类和其子类组成,子类分别代表不同的品牌,包含各自的Print函数
中间件脚本:由一个抽象类和其子类组成,子类分别代表不同品牌的工厂,包含各自的生产函数
主要工厂脚本:挂载在游戏物体上,在Start中调用一个运行方法
产品脚本:
using System .Collections ;using System .Collections .Generic ;using UnityEngine ;namespace FactoryPattern { public abstract class PorductFactoryPattern { public abstract void Print (); } public class DellMouse : PorductFactoryPattern { public override void Print () { Debug .Log ("生产了一个Dell鼠标" ); } } public class HPMouse : PorductFactoryPattern { public override void Print () { Debug .Log ("生产了一个HP鼠标" ); } } }
中间件脚本:
using System .Collections ;using System .Collections .Generic ;using UnityEngine ;using FactoryPattern ;public abstract class MidBase { public abstract PorductFactoryPattern CreateMouse (); }public class DellFactoryMid : MidBase //Dell中间件 { public override PorductFactoryPattern CreateMouse () { return new DellMouse (); } }public class HPFactoryMid : MidBase //HP中间件 { public override PorductFactoryPattern CreateMouse () { return new HPMouse (); } }
主要工厂脚本:
using System .Collections ;using System .Collections .Generic ;using UnityEngine ;using FactoryPattern ;public class MainFactoryPattern : MonoBehaviour { void Start () { RunFactoryMode (); } public void RunNormal ()//普通模式的运行方法 { DellMouse dellMouse = new DellMouse (); dellMouse .Print (); HPMouse hpMouse = new HPMouse (); hpMouse .Print (); } public void RunFactoryMode (MouseType type )//简单工厂模式的运行方法 { SimpleFactory simpleFactory = new SimpleFactory ();//将简单工厂实例化 simpleFactory .CreateMouse (type ).Print (); } public void RunFactoryMode () { DellFactoryMid dellFactoryMid = new DellFactoryMid (); dellFactoryMid .CreateMouse ().Print (); HPFactoryMid hpFactoryMid = new HPFactoryMid (); hpFactoryMid .CreateMouse ().Print (); } }
抽象工厂模式
关键词:解决生产系列产品的问题,比如我们不只是生产鼠标,我们还生产键盘
具体的脚本构成:
鼠标脚本:鼠标抽象父类+鼠标子类
键盘脚本:键盘抽象父类+键盘子类
中间件脚本:中间件抽象父类+中间件子类(生成鼠标和键盘)
主要工厂脚本:Start中调用运行方法
适配器模式(Adapter Pattern)
脚本构成:
具体数据线脚本:可以用抽象父类,也可以不用
适配器脚本:根据枚举判断不同的类型调用各自的方法
主要调用脚本:在Start中进行调用
具体数据线脚本:
using System .Collections ;using System .Collections .Generic ;using UnityEngine ;namespace AdapterPattern { public abstract class Lines { public abstract void Charge (); } public class AndroidLine : Lines { public override void Charge () { Debug .Log ("这是安卓充电线在充电中……" ); } } public class IOSLine : Lines { public override void Charge () { Debug .Log ("这是苹果充电线在充电中……" ); } } }
适配器脚本:
using System .Collections ;using System .Collections .Generic ;using UnityEngine ;using AdapterPattern ;public interface IAdapter { void Charge (LineType type ); }public enum LineType { None , ios , android , };public class Adapter : IAdapter { AndroidLine androidLine = new AndroidLine (); IOSLine iOSLine = new IOSLine (); public void Charge (LineType type ) { if (type == LineType .ios ) { iOSLine .Charge (); } else if (type == LineType .android ) { androidLine .Charge (); } } }
using System .Collections ;using System .Collections .Generic ;using UnityEngine ;using AdapterPattern ;public class MainAdapter : MonoBehaviour { public LineType type ; // Start is called before the first frame update void Start () { Adapter adapter = new Adapter (); //IAdapter adapter = new Adapter(); //这里这种写法也是可以的,还没有弄懂为什么,记个Todo adapter .Charge (type ); } }