编程旅途是漫长遥远的,在不同时刻有不同的感悟,本文会一直更新下去。
程序介绍
本程序实现观察者模式。使用C#、Go两门语言分别进行实现。程序创建一个全局游戏死亡事件通知,5个玩家、1个Boss,当任意一方死亡时,在场存活者都能收到阵亡者的消息。
观察者模式
----------游戏回合开始----------
最终BOSS 击杀 二号玩家 !
一号玩家 知道 二号玩家 阵亡了!
三号玩家 知道 二号玩家 阵亡了!
四号玩家 知道 二号玩家 阵亡了!
五号玩家 知道 二号玩家 阵亡了!
最终BOSS 知道 二号玩家 阵亡了!
----------过了一段时间----------
最终BOSS 击杀 四号玩家 !
一号玩家 知道 四号玩家 阵亡了!
三号玩家 知道 四号玩家 阵亡了!
五号玩家 知道 四号玩家 阵亡了!
最终BOSS 知道 四号玩家 阵亡了!
----------过了一段时间----------
一号玩家 击杀 最终BOSS!
一号玩家 知道 最终BOSS 阵亡了!
三号玩家 知道 最终BOSS 阵亡了!
五号玩家 知道 最终BOSS 阵亡了!
C# 程序代码
observerOriginal.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace observer_original
{
public abstract class Subject
{
private List<Observer> observers = new();
public void Attach(Observer o)
{
observers.Add(o);
}
public void Detach(Observer o)
{
observers.Remove(o);
}
public void Notify()
{
foreach (Observer o in observers)
{
o.Update();
}
}
}
public class DeadSubject : Subject
{
public ICharacter? DeadEntity { get; set; }
}
public abstract class Observer
{
public abstract void Update();
}
public interface ICharacter
{
public string Name { get; }
void Dead();
void Kill(ICharacter who);
}
public class Player : Observer, ICharacter
{
private readonly DeadSubject? sub;
public string Name { get; }
public Player(string name)
{
sub = null;
Name = name;
}
public Player(string name, DeadSubject subject)
{
sub = subject;
Name = name;
}
public override void Update()
{
if (sub == null) return;
Console.WriteLine($"{Name} 知道 {sub?.DeadEntity?.Name} 阵亡了!");
}
public void Dead()
{
if (sub == null) return;
sub.DeadEntity = this;
sub.Detach(this);
sub.Notify();
}
public void Kill(ICharacter who)
{
Console.WriteLine($"{Name} 击杀 {who.Name}!");
who.Dead();
}
}
public class Boss : Observer, ICharacter
{
public string Name { get; }
private DeadSubject? sub;
public Boss(string name)
{
sub = null;
Name = name;
}
public Boss(string name, DeadSubject subject)
{
sub = subject;
Name = name;
}
public override void Update()
{
if (sub == null) return;
Console.WriteLine($"{Name} 知道 {sub?.DeadEntity?.Name} 阵亡了!");
}
public void Dead()
{
if (sub == null) return;
sub.DeadEntity = this;
sub.Detach(this);
sub.Notify();
}
public void Kill(ICharacter who)
{
Console.WriteLine($"{Name} 击杀 {who.Name} !");
who.Dead();
}
}
static class ObserverOriginal
{
public static void Start()
{
Console.WriteLine("观察者模式");
DeadSubject sub = new DeadSubject();
Boss boss = new Boss("最终BOSS", sub);
Player p1 = new Player("一号玩家", sub);
Player p2 = new Player("二号玩家", sub);
Player p3 = new Player("三号玩家", sub);
Player p4 = new Player("四号玩家", sub);
Player p5 = new Player("五号玩家", sub);
sub.Attach(boss);
sub.Attach(p1);
sub.Attach(p2);
sub.Attach(p3);
sub.Attach(p4);
sub.Attach(p5);
Console.WriteLine("----------游戏回合开始----------");
boss.Kill(p2);
Console.WriteLine("----------过了一段时间----------");
boss.Kill(p4);
Console.WriteLine("----------过了一段时间----------");
p1.Kill(boss);
}
}
}
observerDelegate.cs
为什么使用事件委托
当观察者对象没有实现观察者接口的方法,而是各持一词,比如窗体的各个空间,方法已经写死无法添加,按原有设计通知者无法进行做到通知。这时候可以使用C#提供的事件委托功能,声明一个函数抽象,将各个观察者的同型函数进行类化,通过事件委托机制,通知各个函数的运