设为首页 加入收藏

TOP

我的设计模式之旅、07 观察者模式(一)
2023-07-23 13:27:08 】 浏览:85
Tags:计模式

编程旅途是漫长遥远的,在不同时刻有不同的感悟,本文会一直更新下去。

程序介绍

本程序实现观察者模式。使用C#、Go两门语言分别进行实现。程序创建一个全局游戏死亡事件通知,5个玩家、1个Boss,当任意一方死亡时,在场存活者都能收到阵亡者的消息。

观察者模式
----------游戏回合开始----------
最终BOSS 击杀 二号玩家 !
一号玩家 知道 二号玩家 阵亡了!
三号玩家 知道 二号玩家 阵亡了!
四号玩家 知道 二号玩家 阵亡了!
五号玩家 知道 二号玩家 阵亡了!
最终BOSS 知道 二号玩家 阵亡了!
----------过了一段时间----------
最终BOSS 击杀 四号玩家 !
一号玩家 知道 四号玩家 阵亡了!
三号玩家 知道 四号玩家 阵亡了!
五号玩家 知道 四号玩家 阵亡了!
最终BOSS 知道 四号玩家 阵亡了!
----------过了一段时间----------
一号玩家 击杀 最终BOSS!
一号玩家 知道 最终BOSS 阵亡了!
三号玩家 知道 最终BOSS 阵亡了!
五号玩家 知道 最终BOSS 阵亡了!

C# 程序代码

observerOriginal.cs

image-20220911023322689

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#提供的事件委托功能,声明一个函数抽象,将各个观察者的同型函数进行类化,通过事件委托机制,通知各个函数的运

首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Golang 动态脚本调研 下一篇彩虹女神跃长空,Go语言进阶之Go语..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目