设计模式之观察者模式(C# | JavaScript | PHP | Python演示代码)

本文通过C#、JavaScript、PHP和Python四种编程语言,展示了观察者模式的应用,实现了一个对象状态变化时,所有依赖该对象的对象都会得到通知并自动更新的功能。示例中,发布者(被观察者)发布新闻或军事消息,订阅者(观察者)接收到消息并作出响应。代码详细解释了如何创建被观察者和观察者对象,以及如何进行注册、推送消息和响应。
摘要由CSDN通过智能技术生成

  GoF定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都能得到通知并被自动更新。

  简单理解:一个对象发生了改变,那么与它相关联的对象就会都接收到它的改变并可以做出响应。有句俗话是牵一发动全身,这里就是一动多响应,通俗地理解也就是订阅者模式,如果你订阅了某个频道,那么这个频道的内容发生了改变,你可以接收到它的新内容。

  1、C#演示代码:

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            BeObservered NewSrc1=new BeObservered("新闻频道的发布者");
            Observer customerA = new ObserverA("本省观众A");
            Observer customerB = new ObserverB("本省观众B");
            Observer customerC = new ObserverC("本省观众C");
            NewSrc1.register(customerA);
            NewSrc1.register(customerB);
            NewSrc1.PushMessage();
            BeObservered NewSrc2 = new BeObservered("军事频道的发布者");
            NewSrc2.register(customerB);
            NewSrc2.register(customerC);
            NewSrc2.PushMessage();
        }
    }

    public class BeObservered
    {
        private string Name = "";
        private ArrayList BeObserverList = new ArrayList();
        public BeObservered(string Name)
        {
            this.Name = Name;
        }
        public void register(Observer O)
        {
            this.BeObserverList.Add(O);
        }

        public void PushMessage()
        {
            foreach (Observer item in this.BeObserverList)
            {
                item.response(this);
            }
        }

        public string GetName()
        {
            return this.Name;
        }
    }

    public class Observer
    {
        public string Name { set; get; }

        public string GetName()
        {
            return this.Name;
        }
        public virtual void response(BeObservered Obj) { }
    }

    public class ObserverA: Observer
    {
        public ObserverA(string Name)
        {
            this.Name = Name;
        }
        public override void response(BeObservered Obj)
        {
            Console.WriteLine("{0}接收到来自{1}的消息",this.Name,Obj.GetName());
        }
    }

    public class ObserverB : Observer
    {
        public ObserverB(string Name)
        {
            this.Name = Name;
        }
        public override void response(BeObservered Obj)
        {
            Console.WriteLine("{0}接收到来自{1}的消息", this.Name, Obj.GetName());
        }
    }

    public class ObserverC : Observer
    {
        public ObserverC(string Name)
        {
            this.Name = Name;
        }
        public override void response(BeObservered Obj)
        {
            Console.WriteLine("{0}接收到来自{1}的消息", this.Name, Obj.GetName());
        }
    }
}

  控制台输出:

   2、JavaScript演示代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>观察者模式:消息推送</title>
	</head>
	<body>
		<div id="demo"></div>
		<script>
			function BeObserved(Name){
				this.Name=Name;
				this.ObserverList=[];
				this.register=function(Obj){
					this.ObserverList.push(Obj);
				};
				this.unregister=function(Obj){
					let Arr=[];					
					for(var i=0,len=this.ObserverList.length;i<len;i++){
						if( !(this.ObserverList[i]===Obj) ){
							Arr.push(this.ObserverList[i]);
						}
					}
					this.ObserverList=Arr;
				};				
				this.PushMessage=function(){
					for(var i=0,len=this.ObserverList.length;i<len;i++){
						this.ObserverList[i].response(this);
					}
				}				
			}
			
			function Observer(Name){
				this.Name=Name;
				this.response=function(Obj){
					PrintInfo(this.Name+"接收到来自"+Obj.Name+"的消息");
				}
			}			
			
			NewSrcA=new BeObserved("新闻频道的发布者");
			CustomerA=new Observer("本省观众A");
			CustomerA.response=function(Obj){
				PrintInfo(this.Name+"接收到来自"+Obj.Name+"的消息,接收得快一些!");
			}
			
			function PrintInfo(Str){
				document.getElementById("demo").innerHTML = document.getElementById("demo").innerHTML + Str+"<br>";
			}
			
			CustomerB=new Observer("外省观众B");
			CustomerC=new Observer("外省观众C");
			NewSrcA.register(CustomerA);
			NewSrcA.register(CustomerB);
			NewSrcA.PushMessage();

			NewSrcB=new BeObserved("军事频道的发布者");
			NewSrcB.register(CustomerA);
			NewSrcB.register(CustomerC);
			NewSrcB.PushMessage();
		</script>
	</body>
</html>

  网页里的输出:

本省观众A接收到来自新闻频道的发布者的消息,接收得快一些!
外省观众B接收到来自新闻频道的发布者的消息
本省观众A接收到来自军事频道的发布者的消息,接收得快一些!
外省观众C接收到来自军事频道的发布者的消息

  3、PHP演示代码:

<?php
	//被观察者
	class BeObserved{
			private $Name;
			private $ObserverList=[];
			public function __construct($Name){
				$this->Name=$Name;
			}
			public function GetName(){
				return $this->Name;
			}
			//注册
			public function register(Observer $Obj){
				$ObserverName=$Obj->GetName();
				$this->ObserverList[$ObserverName]=$Obj;
			}
			//卸载
			public function unregister(Observer $Obj){
				$ObserverName=$Obj->GetName();
				unset( $this->ObserverList[$ObserverName]);
			}
			//推送消息
			public function PushMessage(){
				foreach( $this->ObserverList as $Obj ){
					$Obj->response($this);
				}
			}
	}

	//观察者
	abstract class Observer{
		protected $Name;
		public function __construct($Name){
			$this->Name=$Name;
		}
		public function GetName(){
			return $this->Name;
		}
		abstract function response(BeObserved $Obj);		
	}

	//观察者A类
	class ObserverA extends Observer{
		public function response(BeObserved $Obj){
			echo $this->GetName().'接收到来自'.$Obj->GetName().'的消息<br>';
		}
	}
	//观察者B类
	class ObserverB extends Observer{
		public function response(BeObserved $Obj){
			echo $this->Name.'接收到来自'.$Obj->Name.'的消息';
		}
	}
	
	$NewsSrc=new BeObserved("新闻频道的发布者");
	$customerA=new ObserverA("本省观众A");
	$customerB=new ObserverA("外省观众B");
	$customerC=new ObserverA("外省观众C");
	$NewsSrc->register($customerA);
	$NewsSrc->register($customerB);
	$NewsSrc->PushMessage();
	echo "<br>";
	$NewsSrc=new BeObserved("军事频道的发布者");
	$NewsSrc->register($customerA);
	$NewsSrc->register($customerC);
	$NewsSrc->PushMessage();
?>

  网页里的输出:

本省观众A接收到来自新闻频道的发布者的消息
外省观众B接收到来自新闻频道的发布者的消息

本省观众A接收到来自军事频道的发布者的消息
外省观众C接收到来自军事频道的发布者的消息

  4、Pthon演示代码:

#被观察者
class BeObserved:
    def __init__(self,name):
        self.name=name
        self.set1=set()
    def getName(self):
        return self.name
    def register(self,obj):
        self.set1.add(obj)
    def unregister(self,obj):
        self.set1.remove(obj)
    def PushMessage(self):
        for item in self.set1:
            item.response(self)

#观察者
class Observer(object):
    def __init__(self,name):
        self.name=name
    def getName(self):
        return self.name
    def response(self,obj):
        pass
#观察者A
class ObserverA(Observer):
    def response(self,obj):
        print(self.name,"接收到来自",obj.getName(),"的消息")
#观察者B
class ObserverB(Observer):
    def response(self,obj):
        print(self.name,"接收到来自",obj.getName(),"的消息")
#观察者C
class ObserverC(Observer):
    def response(self,obj):
        print(self.name,"接收到来自",obj.getName(),"的消息")

customerA=ObserverA("观众A")
customerB=ObserverB("观众B")
customerC=ObserverC("观众C")

NewsSrc=BeObserved("新闻频道的发布者")
NewsSrc.register(customerA)
NewsSrc.register(customerB)
NewsSrc.register(customerC)
NewsSrc.PushMessage()
print("----取消观察者B------")
NewsSrc.unregister(customerB)
NewsSrc.PushMessage()

  输出:

观众B 接收到来自 新闻频道的发布者 的消息
观众C 接收到来自 新闻频道的发布者 的消息
观众A 接收到来自 新闻频道的发布者 的消息
----取消观察者B------
观众C 接收到来自 新闻频道的发布者 的消息
观众A 接收到来自 新闻频道的发布者 的消息

  2022年6月19日,第一次更新;

  2022年6月20日,第二次更新;C#演示代码

  2022年6月28日,第三次更新;Python演示代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值