前言:笔者在最开始写程序的时候经常会遇到一种情况,例如更改一个字段、或者添加一种小功能,就要把原来写过的东西几乎废弃掉,或者更改大量以前写过的代码。又或者自己写的东西时间久了再去回顾,完全找不到到时为什么这么写的头绪,如果遇到了Bug更是无法快速定位在哪里小范围出现的问题。如果你也经常遇到这种问题,就说明你现阶段非常需要学习下设计模式了。
在网上经常说的设计模式有23种,也有一些更多的设计模式,无非也是从这些设计模式中变种而来。如果让笔者来形容什么是设计模式,我认为设计模式是:一种思想,一种模式,一种套路,一种解决问题的高效策略。
有说的不正确或者不准确的地方欢迎留言指正
有什么有趣的写作技巧或者想法欢迎大家给我留言,大家的帮助是我写下去最有效的动力
今天笔者跟大家介绍一个新的设计模式:外观模式或者叫门面模式,这种设计模式在相对于其他设计模式来讲是一种既简单有很实用的编程技巧。其实外观模式的这种思想在生活中也有很广的应用,例如:
- 我们去餐厅吃饭时菜单和点菜器,这就是一种外观模式的体现,我们不需要跟各类厨师进行交互,只需要对菜单发出“指令”即可。
- 电脑的开机键,一键开机,不需要通知CPU、显卡、内存、硬盘等电子元件开始工作
- 又或者汽车,驾驶者只需要知道方向盘、仪表盘就可以轻易操控汽车,不需要其内部的具体操作
外观模式(Facade),为子系统中的一组接口提供一个一直的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
示例代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Custom.Log;
interface IPhysicalSystem
{
void Initialize();
void Update();
}
interface IRenderingSystem
{
void Initialize();
void Update();
}
interface IMoveSystem
{
void Initialize();
void Update();
}
public class PhysicalSystem : IPhysicalSystem
{
public void Initialize() { this.Log($"初始化{nameof(PhysicalSystem)}"); }
public void Update() { this.Log($"更新{nameof(PhysicalSystem)}"); }
}
public class RenderingSystem : IRenderingSystem
{
public void Initialize() { this.Log($"初始化{nameof(RenderingSystem)}"); }
public void Update() { this.Log($"更新{nameof(RenderingSystem)}"); }
}
public class MoveSystem : IMoveSystem
{
public void Initialize() { this.Log($"初始化{nameof(MoveSystem)}"); }
public void Update() { this.Log($"更新{nameof(MoveSystem)}"); }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Custom.Log;
public class Facade
{
#region Facade
static Facade() { }
private Facade() { }
private readonly object sync = new object();
private readonly static object staticsync = new object();
private volatile static Facade instance = null;
public static Facade Instance
{
get
{
if (instance == null)
{
lock (staticsync)
{
if (instance == null)
{
instance = new Facade();
}
}
}
return instance;
}
}
#endregion
private IMoveSystem moveSystem = new MoveSystem();
private IPhysicalSystem physicalSystem = new PhysicalSystem();
private IRenderingSystem renderingSystem = new RenderingSystem();
public void Initialize()
{
moveSystem.Initialize();
physicalSystem.Initialize();
renderingSystem.Initialize();
}
public void Update()
{
moveSystem.Update();
physicalSystem.Update();
renderingSystem.Update();
}
}
调用
public class FacadeComponent : MonoBehaviour
{
Facade facade = null;
void Start()
{
facade = Facade.Instance;
facade.Initialize();
}
private void Update()
{
facade.Update();
}
}
这种结构,使得我们上层调用的时候不需要知道明确的子系统,只需要知道Facade定义的对应接口就可以,降低耦合性,符合迪米特法则,但他的缺点就是破坏了开闭原则,如果后期子系统有改动,Facade会改的比较频繁。
还有一个要注意的是,Facade只能调用其中子类的里面含有的一些方法,主要是各个子系统自带函数的拼装,不能自建新的业务逻辑,例如我们的示例,要在Facade类里面根据移动系统实现一套物体的移动业务逻辑这个是不允许的,,而且外观模式封装的是单向的交互,是从客户端访问系统的调用,没有从系统中来访问客户端的调用。
这些注意要素其实在PureMVC中就有很好的体现,在对应的Facade类中,仅仅就是模型、视图、控制层这些子系统的单向的调用自身的函数,并没有添加一些其他的自建业务逻辑
网友评论