C# 委托和事件 与 观察者模式(发布

时间:2021-10-29 20:09:00

使用面向对象的思想 用c#控制台代码模拟猫抓老鼠

我们先来分析一下猫抓老鼠的过程

1.猫叫了

2.所有老鼠听到叫声,知道是哪只猫来了

3.老鼠们逃跑,边逃边喊:"xx猫来了,快跑啊!我是老鼠xxx"

一  双向耦合的代码

首先需要一个猫类Cat 一个老鼠类Rat 和一个测试类Program

老鼠类的代码如下

//老鼠类 public class Rat { public string Name { get; set; } //老鼠的名字 public Cat MyCat { get; set; } //老鼠遇到的猫 //老鼠逃跑的方法 public void Run() { Console.WriteLine(MyCat.Name + "猫来了,大家快跑!!我是" + Name); //打印出信息 包含了猫的名字和老鼠本身的名字 } //带参和无参构造 public Rat() { } public Rat(string name, Cat cat) { this.Name = name; this.MyCat = cat; } }

要让猫叫的时候依次打印出老鼠的逃跑方法,需要在Cat类里添加一个存放Rat对象的集合

Cat类的代码如下

public class Cat { public string Name { get; set; } //猫的名字 List<Rat> list = new List<Rat>(); //存放Rat对象的集合 //为集合增加老鼠 public void Add(Rat rat) { list.Add(rat); } //移除 public void Remove(Rat rat) { list.Remove(rat); } //猫叫的方法 public void Shout() { Console.WriteLine("喵喵喵!"); //如果集合非空,循环执行每只老鼠的Run()方法 if (list != null) { foreach (Rat item in list) { item.Run(); } } } public Cat() { } public Cat(string name) { this.Name = name; } }

在Main方法中,我们需要构建几个Rat对象和一个Cat对象,将Rat对象添加到Cat对象的集合中,调用Cat对象的Shout方法

代码如下

static void Main(string[] args) { //构建一个Cat对象和两个Rat对象 老鼠遇到的猫是构建的cat Cat cat = new Cat("Tom"); Rat rat1 = new Rat("Jerry", cat); Rat rat2 = new Rat("TaoQi", cat); //调用猫类的Add方法添加老鼠对象 cat.Add(rat1); cat.Add(rat2); //调用猫的Shout方法 cat.Shout(); Console.ReadKey(); }

运行结果如下


这样的代码缺陷很明显,Cat类和Rat类紧密耦合

猫可能不止要抓老鼠 还要抓小鸟

当然不止是猫会抓 也可能狗拿耗子多管闲事

于是我们可以把猫和狗提出来 继承自一个抽象类Pet

抓捕的小动物老鼠和小鸟没有什么关系 但是都能(逃)跑

先不去管小鸟是飞,我们把它们称作 可以跑的 都实现一个IRunable接口

二  观察者 模式(发布-订阅模式)

修改后的代码如下

新增抽象类Pet ,猫类继承自Pet   (猫类的代码变化不大 略去不写

public abstract class Pet { public List<IRunable> list = new List<IRunable>(); public void Add(IRunable i) { list.Add(i); } public void Remove(IRunable i) { list.Remove(i); } public abstract void Shout(); }

接口IRubable 里面定义一个Run方法

public interface IRunable
{
void Run();
}

老鼠Rat和鸟Bird两个类都实现了这个接口

以Bird为例 代码如下