在软件开发系统中,客户程序经常会与复杂系统的内部子系统之间产生耦合,而导致客户程序随着子系统的变化而变化.那么如何简化客户程序与子系统之间的交互接口?如何将复杂系统的内部子系统与客户程序之间的依赖解耦?这就需要用到外观模式(Facade)了.
为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用,又称为门面模式,它是一种对象结构型模式.
第一:目的在于降低系统的复杂程度。
第二:根据单一职责原则,在软件中将一个系统划分为若干个子系统有利于降低整个系统复杂性,一个常见的设计目标是使子系统间通信和相互依赖关系达到最小,而达到该目标的途径之一就是引入一个外观对象,它为子系统的访问提供了一个简单而单一的入口。
第三:是迪米特法则的体现,通过引入一个新的外观类可以降低原有系统的复杂度,同时降低客户类与子系统类的耦合度。
第四:外观模式要求一个子系统的外部和内部的通信通过一个统一的外观对象进行,外观类将客户端与子系统的内部复杂性分隔开,使客户端只需要与外观对象打交道,而不需要与子系统内部的很多对象打交道。
第五:从很大程度上提高了客户端使用的便捷性,使得客户端无须关心子系统的工作细节,通过外观角色即可调用相关功能。
第一:设计初期阶段,有意识的将不同的两个层分离,层与层之间建立外观Facade,这样就可以为复杂的子系统提供一个简单的接口,耦合性降低。
第二:在开发阶段,子系统往往因为不断的重构演化而变的越来越复杂,增加外观Facade可以提供一个简单的接口,减少它们之间的依赖性.
第三:维护一个大型系统时,可能这个系统已经非常难以维护和扩展,此时可以为系统新开发一个Facade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单接口,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作。
对客户屏蔽子系统详细内容,减少客户处理的对象的个数并让子系统使用容易。
实现子系统与客户之间的松耦合关系,使子系统组件变化不会影响到调用它的客户类,只需要调整外观类就可以了。
降低大型软件系统中的编译依赖性,简化系统在不同平台之间的移植过程。
提供一个访问子系统的统一入口,并不影响用户直接使用子系统类。
不能很好的限制客户使用子系统类,否则减少了可变性和灵活性
不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背开闭原则。
class Program { static void Main(string[] args) { Boss wangsan = new Boss(); StockObserver tongshi1=new StockObserver ("lisi",wangsan); wangsan .Attach (tongshi1 ); wangsan .SubjectState ="我回来了"; wangsan .Notify (); } }
interface Subject //接口 { void Attach(Observer observer); void Detach(Observer observer); void Notify(); string SubjectState { get; set; } }
class Boss : Subject { private IList<Observer> observers = new List<Observer>(); private string action; public void Attach(Observer observer) { observers.Add(observer); } public void Detach(Observer observer) { observers.Remove(observer); } public void Notify() { foreach (Observer o in observers) o.Update(); } public string SubjectState { get { return action; } set { action = value; } } }
abstract class Observer { protected string name; protected Subject sub; public Observer(string name, Subject sub) { this.name = name; this.sub = sub; } public abstract void Update(); }
class StockObserver : Observer { public StockObserver(string name, Subject sub) : base(name, sub) { } public override void Update() { Console.WriteLine("{0}{1}关闭游戏,继续学习!", sub.SubjectState, name); } }