委托和设计模式(二)

时间:2022-03-21 08:28:22

此篇简单抽取了几个设计模式分别按照多态和委托的方式去实现,当然这里的重点并不是讲设计模式,而是为了使读者更好地理解委托。所以设计模式的很多细节,本篇可能会略过。

一、简单工厂模式:本篇就借助计算器的例子加以说明。

1、多态实现简单工厂模式。

   class Program2 { static void Main(string[] args) { //1.使用多态实现简单工厂模式 int x = 8, y = 2; var iRes1 = GetObject("+").Compute(x, y); var iRes2 = GetObject("-").Compute(x, y); var iRes3 = GetObject("*").Compute(x, y); var iRes4 = GetObject("http://www.mamicode.com/").Compute(x, y); Console.WriteLine(iRes1); Console.WriteLine(iRes2); Console.WriteLine(iRes3); Console.WriteLine(iRes4); Console.ReadKey(); } static Calculator GetObject(string type) { Calculator oRes = null; switch (type) { case "+": oRes = new Add(); break; case "-": oRes = new Subtract(); break; case "*": oRes = new Multiply(); break; case "http://www.mamicode.com/": oRes = new Divide(); break; } return oRes; } } public class Calculator { public virtual int Compute(int x, int y) { return 0; } } public class Add : Calculator { public override int Compute(int x, int y) { return x + y; } } public class Subtract : Calculator { public override int Compute(int x, int y) { return x - y; } } public class Multiply : Calculator { public override int Compute(int x, int y) { return x * y; } } public class Divide : Calculator { public override int Compute(int x, int y) { if (y == 0) { return 0; } return x / y; } }

代码应该很容易看懂,直接通过方法的重写去实现,在此就不过多讲解。

2、委托方式实现简单工厂模式。

class Program2 { static void Main(string[] args) { #region 2.委托实现简单工厂模式 int x = 8, y = 2; var oCalculator = new Calculator(); var iRes1 = oCalculator.Compute(x, y, oCalculator.Add);//将方法作为参数传下去 var iRes2 = oCalculator.Compute(x, y, oCalculator.Subtract); var iRes3 = oCalculator.Compute(x, y, oCalculator.Multiply); var iRes4 = oCalculator.Compute(x, y, oCalculator.Divide); Console.WriteLine(iRes1); Console.WriteLine(iRes2); Console.WriteLine(iRes3); Console.WriteLine(iRes4); #endregion Console.ReadKey(); } } public delegate int DelegateCalculator(int x, int y); public class Calculator {
     //将方法的实例传递进来,在Compute方法里面执行 public int Compute(int x, int y, DelegateCalculator calculator) { return calculator(x, y); } public int Add(int x, int y) { return x + y; } public int Subtract(int x, int y) { return x - y; } public int Multiply(int x, int y) { return x * y; } public int Divide(int x, int y) { if (y == 0) { return 0; } return x / y; } }

这里需要定义四个实现方法Add、Subtract、Multiply、Divide,而不用在意这四个方法在哪个类下面,只要这四个方法的的参数和返回值和委托的定义保持一致即可。这也验证了上面说的 “站在方法的层面,委托实例的一个非常有用的特性是它既不知道,也不关心其封装方法所属类的详细信息,对它来说最重要的是这些方法与该委托的参数和返回值的兼容性” 。两种方式得到的结果是相同的:

二、观察者模式:观察者模式最典型的场景就是订阅者和订阅号的场景

1、纯多态方式实现观察者模式:这种代码园子里面非常多。

class Program3 { static void Main(string[] args) { // 具体主题角色通常用具体自来来实现 ConcreteSubject subject = new ConcreteSubject(); subject.Attach(new ConcreteObserver(subject, "Observer A")); subject.Attach(new ConcreteObserver(subject, "Observer B")); subject.Attach(new ConcreteObserver(subject, "Observer C")); subject.SubjectState = "Ready"; subject.Notify(); Console.Read(); } } //抽象主题类 public abstract class Subject { private IList<Observer> observers = new List<Observer>(); /// <summary> /// 增加观察者 /// </summary> /// <param></param> public void Attach(Observer observer) { observers.Add(observer); } /// <summary> /// 移除观察者 /// </summary> /// <param></param> public void Detach(Observer observer) { observers.Remove(observer); } /// <summary> /// 向观察者(们)发出通知 /// </summary> public void Notify() { foreach (Observer o in observers) { o.Update(); } } } //具体主题类 public class ConcreteSubject : Subject { private string subjectState; /// <summary> /// 具体观察者的状态 /// </summary> public string SubjectState { get { return subjectState; } set { subjectState = value; } } } //抽象观察者类 public abstract class Observer { public abstract void Update(); } //具体观察者 public class ConcreteObserver : Observer { private string observerState; private string name; private ConcreteSubject subject; /// <summary> /// 具体观察者用一个具体主题来实现 /// </summary> public ConcreteSubject Subject { get { return subject; } set { subject = value; } } public ConcreteObserver(ConcreteSubject subject, string name) { this.subject = subject; this.name = name; } /// <summary> /// 实现抽象观察者中的更新操作 /// </summary> public override void Update() { observerState = subject.SubjectState; Console.WriteLine("The observer‘s state of {0} is {1}", name, observerState); } }

可以看到虽然已经很好的实现了观察者Observer 和主题Subject之间的分离。但是Subject的内部还是有对观察者的调用: