为什么没有一个订阅号没有超链接店铺的subscriber

1629人阅读
Java EE(56)
、订阅者(
)开发流程(
方法中监听发布者发出的消息队列,并做相应处理。
的基础上创建一个
,同时设置是否支持事务和
用于接收发布者发出的消息,
用于向发布者发送消息,实现双方的交互。
接收处理消息:
方法中,对收到的消息进行处理,可直接简单在本地显示消息,或者根据消息内容不同处理对应的业务逻辑(比如:数据库更新、文件操作等
等),并且可以使用
对象将处理结果返回给发布者。
、发布者(
)开发流程(
方法中接收订阅者的反馈消息。
的基础上创建一个
,同时设置是否支持事务和
用于向订阅者发布消息,
用于接收订阅者反馈的消息。这
与订阅者开发流程中的
是一一对应的。
,同时监听订阅者反馈的消息。
所有订阅者发送消息,并接收反馈消息:
示例代码中,一共重复
每轮先向所有订阅者发送
然后堵塞线程,开始等待;
方法,接收到订阅者反馈的&
&类信息后,才
反馈信息并解除线程堵塞,进入下一轮。
同时运行多个订阅者测试查看此模式效果
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1149320次
积分:13626
积分:13626
排名:第707名
原创:230篇
转载:235篇
评论:147条
我的微信公众号:internet-sky
(2)(3)(3)(2)(3)(1)(2)(6)(3)(3)(1)(3)(1)(4)(2)(1)(1)(2)(1)(1)(4)(2)(4)(2)(1)(1)(2)(5)(3)(7)(4)(18)(8)(8)(24)(1)(5)(7)(7)(1)(1)(1)(2)(2)(2)(4)(4)(1)(2)(14)(1)(20)(4)(2)(1)(3)(3)(2)(8)(11)(2)(6)(1)(19)(6)(2)(8)(49)(30)(30)(11)(10)(34)(3)(3)(4)(5)(1)Symfony 中 event 的 Listener 和 Subscriber 的区别是什么? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
已注册用户请 &
Sponsored by
寻找中国最优秀的程序员加入我们,一起来改变这个可爱的星球
Promoted by
Symfony 中 event 的 Listener 和 Subscriber 的区别是什么?
· 147 天前 · 572 次点击
文档地址:
讲两者区别的时候:
Listeners or Subscribers
Listeners and subscribers can be used in the same application indistinctly. The decision to use either of them is usually a matter of personal taste. However, there are some minor advantages for each of them:
Subscribers are easier to reuse because the knowledge of the events is kept in the class rather than in the service definition. This is the reason why Symfony uses su
Listeners are more flexible because bundles can enable or disable each of them conditionally depending on some configuration value.
看 Symfony 的源码:
HttpKernel -& handleRaw 中,当往 requestStack 中 push 完一个 Request 之后,会通过 EventDispatcherInterface::dispatch('kernel.request', new GetResponseEvent()),来触发所有监听 kernel.request 的 Listener 。
这里有一些疑问,首先 GetResponseEvent 事件对象是事件源( HttpKernel )需要触发 kernel.request 这个事件的时候自己创建的,那监听 kernel.request 的 Listeners 是什么时候注册进去的?那 EventDispatcher 扮演了什么角色?另外发现 HttpKernel 中的 eventListener 是实现的 EventSubscriberInterface 接口,这个 Subscriber 不是订阅者的意思吗?那 Listener 实现 Subscriber ,是说明这两者是同一个概念?
后来搜了设计模式,发现还有观察者模式
事件源 /事件 /事件监听 /事件分发,发布 /订阅,观察者,这些概念之间是个什么关系?发现网上各种解释都有,都是一家之言,有的甚至还产生混淆。。。
6 回复 &| &直到
22:25:46 +08:00
& &147 天前
& &147 天前
我不太会组织这些技术含义,只说说我自己的理解,希望能帮到你!
```
$event = new GetResponseEvent($this, $request, $type);
$this-&dispatcher-&dispatch(KernelEvents::REQUEST, $event);
```
EventDispatcher ,即调度器, dispatch 为动词,是指去调度(触发)某个事件,这个类似于 jQuery 的 trigger 和 angular 中的 $broadcast($emit)。
在这里 KernelEvents::REQUEST 为事件名称,$event 是事件实体对象(当前事件的相关参数,也可以使用 Symfony\Component\EventDispatcher\GenericEvent 方法),说直白一点,就是当发生 KernelEvents::REQUEST 的时候,去做一个件事情,并把 $event 当作参数传递过去,但是你会发现只是定义了事件,并没有说去做的事情是什么!
EventDispatcher 中还有一个方法, EventDispatcher::addListener($eventName, $listener, $priority = 0):
这个 addListener (监听器)就是用来指定前面所说的:告诉事件调度器,在某个事件发生时去做什么,第二个参数就是事件处理,举个例子:
```
$this-&dispatcher-&addListener(KernelEvents::REQUEST, function(GetResponseEvent $event) {
$request = $event-&getRequest();
var_dump($request-&getClientIp());
我监听了 KernelEvents::REQUEST 事件,来获取当前请求对象中的 IP 地址,可以看到,在事件处理中的 $event 就是事件发生时,传传递过来的 GetResponseEvent 事件实体!
subscriber 与 listener 相同的,在 EventDispatcher::addSubscriber 内部去掉用了 addListener 方法,看源码:
subscriber 与 listener 的不同点在于,前者在定义阶段就指定了由谁来负责处理事件,而后者是在事件中去决定需要去捕获哪些事件(也就是 EventSubscriberInterface::getSubscribedEvents 方法),后者更灵活, Symfony 内部代码都是使用的 subscriber !
& &147 天前
@ 最后一句写反了,应该是
listener 与 subscriber 的不同点在于,前者在定义阶段就指定了由谁来负责处理事件,而后者是在事件中去决定需要去捕获哪些事件(也就是 EventSubscriberInterface::getSubscribedEvents 方法),后者更灵活, Symfony 内部代码都是使用的 subscriber !
& &146 天前
好久没看到一个有营养的话题了。
& &145 天前
@ 谢谢耐心的讲解,其实 listener 的原理是明白的,主要是 subscriber ,“而后者是在事件中去决定需要去捕获哪些事件”,这句中的前一个“事件”是不是指的 Subscriber ?指的是在 Subscriber 中获取需要监听的事件吗?
是这样:首先往 Manager 中注册监听 name 事件的 N 个 Listener callable ,当事件源需要触发事件的时候,就调用 dispatch('name', new SomeEvent()) 来让 Manager 来挨个调用跟 name 关联的 Listener ,并把 SomeEvent 传递给这些 Listener , Listener 处理完会把它处理过的 SomeEvent 返回回来,事件源拿到处理过的 SomeEvent 继续处理。
Symfony 中的 Listener 其实是实现了 EventSubscriberInterface 的,它会强制实现 getSubscribedEvents(),这个方法返回的就是当前 Listener 自己的每个 callable function 可以处理的 Event (意思是这个 Listener 其实是可以处理多个 name Event 的?),这里还有一个问题:既然 Subscriber 自己是知道自己可以处理哪些事件,并且知道调用自己的什么方法去处理,那是不是 Subscriber 是不需要提前注册的?如果这样的话,岂不是每次触发事件 Manager 需要把所有的 Subscriber 遍历一遍调用 getSubscribedEvents() 才能找到对应的 callable ?
& &142 天前
1 ,可以处理多个事件,即使是同一个 name ,也可以多次触发。
2 ,当然需要注册,在注册 Subscriber 的时候,内部才会调用 addListener ,否则只是一个 callable 对象,没有和 eventName 绑定关系。
最终这些 event 是以 eventName 为 key 存储在 EventDispatcher::listeners 属性上的二维数组,寻找指定 eventName 不需要遍历,但触发时需要遍历!
如果你仔细看过源码,你会发现第一个 callable 是不允许有返回值的(因为同一个事件可能会有多个 callable 被触发),因此我还专门自己写了个类似功能的事件管理。
另外,这个组件相对不那么复杂,你可以使用 Composer 安装一下一步一步打印看看!
& · & 1670 人在线 & 最高记录 2399 & · &
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.7.5 · 55ms · UTC 10:22 · PVG 18:22 · LAX 02:22 · JFK 05:22? Do have faith in what you're doing.37418人阅读
设计模式(5)
&&&&& 订阅发布模式定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象。这个主题对象在自身状态变化时,会通知所有订阅者对象,使它们能够自动更新自己的状态。
&&&&&& 将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相应对象间的一致性,这样会给维护、扩展和重用都带来不便。当一个对象的改变需要同时改变其他对象,而且它不知道具体有多少对象需要改变时,就可以使用订阅发布模式了。
&&&&&& 一个抽象模型有两个方面,其中一方面依赖于另一方面,这时订阅发布模式可以将这两者封装在独立的对象中,使它们各自独立地改变和复用。订阅发布模式所做的工作其实就是在解耦合。让耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化。
在我们日常写程序时,经常遇到下面这种情况:
public void 有告警信息产生() { &&& 刷新界面(); &&& 更新数据库(); &&& 给管理员发Mail(); &&& &&&&&&&&&&&& }
当有告警信息产生时,依次要去执行:刷新界面()、更新数据库()、给管理员发Mail()等操作。表面上看代码写得很工整,其实这里面问题多多:
首先,这完全是面向过程开发,根本不适合大型项目。
第二,代码维护量太大。设想一下,如果产生告警后要执行10多个操作,那这将是个多么大,多少复杂的类呀,时间一长,可能连开发者自己都不知道如何去维护了。
第三,扩展性差。如果产生告警后,要增加一个声音提示()功能,怎么办呢?没错,只能加在有告警信息产生()这个函数中,这样一来,就违反了&开放-关闭原则&。而且修改了原有的函数,那么在测试时,除了要测新增功能外,还要做原功能的回归测试;在一个大型项目中,做一次回归测试可能要花费大约两周左右的时间,而且前提是新增功能没有影响原来功能及产生新的bug。
那么如何把有告警信息产生()函数同其他函数进行解耦合呢?别着急,下面就介绍今天的主角----订阅发布模式。见下图:
上面的流程就是对有告警信息产生()这个函数的描述。我们要做的,就是把产生告警和它需要通知的事件进行解耦,让它们之间没有相互依赖的关系,解耦合图如下:
事件触发者被抽象出来,称为消息发布者,即图中的P。事件接受都被抽象出来,称为消息订阅者,即图中的S。P与S之间通过S.P(即订阅器)连接。这样就实现了P与S的解耦。首先,P就把消息发送到指定的订阅器上,从始至终,它并不知道也不关心要把消息发向哪个S。S如果想接收消息,就要向订阅器进行订阅,订阅成功后,S就可以接收来自S.P的消息了,从始至终,S并不知道也不关心消息来源于哪个具体的P。同理,S还可以向S.P进行退订操作,成功退订后,S就无法接收到来自指定S.P的消息了。这样就完美的解决了P与S之间的解耦。
等等,好像还有一个问题。从图上看,虽然P与S之间完成了解耦,但是P与S.P,S与S.P之间不就又耦合上了吗?其实这个问题好解决,想想我们上篇的是怎么解耦的?对,就接口。这里我们同样使用接口来解决P与S.P和S与S.P之间的解耦,同时,使用delegate来解决多订阅多发布的机制。
下面给出实现代码。由于订阅发布模式涉及P, S.P和S三部份内容,所以代码比较多,也比较长。请大家耐心阅读。
首先,为了实现P与S.P, S与S.P之间的解耦,我们需要定义两个接口文件
ISubscribe.csnamespace TJVictor.DesignPattern.SubscribePublish{&&& //定义订阅事件&&& public delegate void SubscribeHandle(string str);&&& //定义订阅接口&&& public interface ISubscribe&&& {&&&&&&& event SubscribeHandle SubscribeE&&& }}
IPublishnamespace TJVictor.DesignPattern.SubscribePublish{&&& //定义发布事件&&& public delegate void PublishHandle(string str);&&& //定义发布接口&&& public interface IPublish&&& {&&&&&&& event PublishHandle PublishE
&&&&&&& void Notify(string str);&&& }}
然后我们来设计订阅器。显然订阅器要实现双向解耦,就一定要继承上面两个接口,这也是我为什么用接口不用抽象类的原因(类是单继承)。
namespace TJVictor.DesignPattern.SubscribePublish{&&& public class SubPubComponet : ISubscribe, IPublish&&& {&&&&&&& private string _subN&&&&&&& public SubPubComponet(string subName)&&&&&&& {&&&&&&&&&&& this._subName = subN&&&&&&&&&&& PublishEvent += new PublishHandle(Notify);&&&&&&& }
&&&&&&& #region ISubscribe Members&&&&&&& event SubscribeHandle subscribeE&&&&&&& event SubscribeHandle ISubscribe.SubscribeEvent&&&&&&& {&&&&&&&&&&& add { subscribeEvent += }&&&&&&&&&&& remove { subscribeEvent -= }&&&&&&& }&&&&&&& #endregion
&&&&&&& #region IPublish Members&&&&&&& public PublishHandle PublishE
&&&&&&& event PublishHandle IPublish.PublishEvent&&&&&&& {&&&&&&&&&&& add { PublishEvent += }&&&&&&&&&&& remove { PublishEvent -= }&&&&&&& }&&&&&&& #endregion
&&&&&&& public void Notify(string str)&&&&&&& {&&&&&&&&&&& if (subscribeEvent != null)&&&&&&&&&&&&&&& subscribeEvent.Invoke(string.Format("消息来源{0}:消息内容:{1}", _subName, str));&&&&&&& }&&& }}
接下来是设计订阅者S。S类中使用了ISubscribe来与S.P进行解耦。代码如下:
namespace TJVictor.DesignPattern.SubscribePublish{&&& public class Subscriber&&& {&&&&&&& private string _subscriberN
&&&&&&& public Subscriber(string subscriberName)&&&&&&& {&&&&&&&&&&& this._subscriberName = subscriberN&&&&&&& }
&&&&&&& public ISubscribe AddSubscribe { set { value.SubscribeEvent += S } }&&&&&&& public ISubscribe RemoveSubscribe { set { value.SubscribeEvent -= S } }
&&&&&&& private void Show(string str)&&&&&&& {&&&&&&&&&&& Console.WriteLine(string.Format("我是{0},我收到订阅的消息是:{1}", _subscriberName, str));&&&&&&& }&&& }}
最后是发布者P,继承IPublish来对S.P发布消息通知。
namespace TJVictor.DesignPattern.SubscribePublish{&&& public class Publisher:IPublish&&& {&&&&&&& private string _publisherN
&&&&&&& public Publisher(string publisherName)&&&&&&& {&&&&&&&&&&& this._publisherName = publisherN&&&&&&& }
&&&&&&& private event PublishHandle PublishE&&&&&&& event PublishHandle IPublish.PublishEvent&&&&&&& {&&&&&&&&&&& add { PublishEvent += }&&&&&&&&&&& remove { PublishEvent -= }&&&&&&& }
&&&&&&& public void Notify(string str)&&&&&&& {&&&&&&&&&&& if (PublishEvent != null)&&&&&&&&&&&&&&& PublishEvent.Invoke(string.Format("我是{0},我发布{1}消息", _publisherName, str));&&&&&&& }&&& }}
至此,一个简单的订阅发布模式已经完成了。下面是调用代码及运行结果。调用代码模拟了图2中的订阅发布关系,大家可以从代码,运行结果和示例图三方面对照着看。
#region TJVictor.DesignPattern.SubscribePublish//新建两个订阅器SubPubComponet subPubComponet1 = new SubPubComponet("订阅器1");SubPubComponet subPubComponet2 = new SubPubComponet("订阅器2");//新建两个发布者IPublish publisher1 = new Publisher("TJVictor1");IPublish publisher2 = new Publisher("TJVictor2");//与订阅器关联publisher1.PublishEvent += subPubComponet1.PublishEpublisher1.PublishEvent += subPubComponet2.PublishEpublisher2.PublishEvent += subPubComponet2.PublishE//新建两个订阅者Subscriber s1 = new Subscriber("订阅人1");Subscriber s2 = new Subscriber("订阅人2");//进行订阅s1.AddSubscribe = subPubComponet1;s1.AddSubscribe = subPubComponet2;s2.AddSubscribe = subPubComponet2;//发布者发布消息publisher1.Notify("博客1");publisher2.Notify("博客2");//发送结束符号Console.WriteLine("".PadRight(50,'-'));//s1取消对订阅器2的订阅s1.RemoveSubscribe = subPubComponet2;//发布者发布消息publisher1.Notify("博客1");publisher2.Notify("博客2");//发送结束符号Console.WriteLine("".PadRight(50, '-'));#endregion
#region Console.ReadLine();Console.ReadLine();#endregion
&运行结果图:
如需转载,请注明本文原创自CSDN TJVictor专栏:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1671709次
积分:14676
积分:14676
排名:第615名
原创:151篇
转载:27篇
译文:16篇
评论:863条
(1)(1)(1)(7)(1)(1)(1)(2)(1)(7)(4)(19)(6)(7)(5)(16)(7)(23)(10)(7)(11)(2)(1)(2)(1)(1)(3)(3)(12)(12)(11)(2)(1)(5)(1)设计模式(6)
转载自:http://blog.csdn.net/tjvictor/article/details/5223309
订阅发布模式定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象。这个主题对象在自身状态变化时,会通知所有订阅者对象,使它们能够自动更新自己的状态。
&&&&&& 将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相应对象间的一致性,这样会给维护、扩展和重用都带来不便。当一个对象的改变需要同时改变其他对象,而且它不知道具体有多少对象需要改变时,就可以使用订阅发布模式了。
&&&&&& 一个抽象模型有两个方面,其中一方面依赖于另一方面,这时订阅发布模式可以将这两者封装在独立的对象中,使它们各自独立地改变和复用。订阅发布模式所做的工作其实就是在解耦合。让耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化。
在我们日常写程序时,经常遇到下面这种情况:
public void 有告警信息产生()&
&&& 刷新界面();&
&&& 更新数据库();&
&&& 给管理员发Mail();&
&&& ………………………………&
当有告警信息产生时,依次要去执行:刷新界面()、更新数据库()、给管理员发Mail()等操作。表面上看代码写得很工整,其实这里面问题多多:
首先,这完全是面向过程开发,根本不适合大型项目。第二,代码维护量太大。设想一下,如果产生告警后要执行10多个操作,那这将是个多么大,多少复杂的类呀,时间一长,可能连开发者自己都不知道如何去维护了。第三,扩展性差。如果产生告警后,要增加一个声音提示()功能,怎么办呢?没错,只能加在有告警信息产生()这个函数中,这样一来,就违反了“开放-关闭原则”。而且修改了原有的函数,那么在测试时,除了要测新增功能外,还要做原功能的回归测试;在一个大型项目中,做一次回归测试可能要花费大约两周左右的时间,而且前提是新增功能没有影响原来功能及产生新的bug。
那么如何把有告警信息产生()函数同其他函数进行解耦合呢?别着急,下面就介绍今天的主角----订阅发布模式。见下图:
上面的流程就是对有告警信息产生()这个函数的描述。我们要做的,就是把产生告警和它需要通知的事件进行解耦,让它们之间没有相互依赖的关系,解耦合图如下:
事件触发者被抽象出来,称为消息发布者,即图中的P。事件接受都被抽象出来,称为消息订阅者,即图中的S。P与S之间通过S.P(即订阅器)连接。这样就实现了P与S的解耦。首先,P就把消息发送到指定的订阅器上,从始至终,它并不知道也不关心要把消息发向哪个S。S如果想接收消息,就要向订阅器进行订阅,订阅成功后,S就可以接收来自S.P的消息了,从始至终,S并不知道也不关心消息来源于哪个具体的P。同理,S还可以向S.P进行退订操作,成功退订后,S就无法接收到来自指定S.P的消息了。这样就完美的解决了P与S之间的解耦。
等等,好像还有一个问题。从图上看,虽然P与S之间完成了解耦,但是P与S.P,S与S.P之间不就又耦合上了吗?其实这个问题好解决,想想我们上篇的是怎么解耦的?对,就接口。这里我们同样使用接口来解决P与S.P和S与S.P之间的解耦,同时,使用delegate来解决多订阅多发布的机制。
下面给出实现代码。由于订阅发布模式涉及P, S.P和S三部份内容,所以代码比较多,也比较长。请大家耐心阅读。
首先,为了实现P与S.P, S与S.P之间的解耦,我们需要定义两个接口文件
ISubscribe.cs
namespace TJVictor.DesignPattern.SubscribePublish
&&& //定义订阅事件
&&& public delegate void SubscribeHandle(string str);
&&& //定义订阅接口
&&& public interface ISubscribe
&&&&&&& event SubscribeHandle SubscribeE
namespace TJVictor.DesignPattern.SubscribePublish
&&& //定义发布事件
&&& public delegate void PublishHandle(string str);
&&& //定义发布接口
&&& public interface IPublish
&&&&&&& event PublishHandle PublishE
&&&&&&& void Notify(string str);
然后我们来设计订阅器。显然订阅器要实现双向解耦,就一定要继承上面两个接口,这也是我为什么用接口不用抽象类的原因(类是单继承)。
namespace TJVictor.DesignPattern.SubscribePublish
&&& public class SubPubComponet : ISubscribe, IPublish
&&&&&&& private string _subN
&&&&&&& public SubPubComponet(string subName)
&&&&&&&&&&& this._subName = subN
&&&&&&&&&&& PublishEvent += new PublishHandle(Notify);
&&&&&&& #region ISubscribe Members
&&&&&&& event SubscribeHandle subscribeE
&&&&&&& event SubscribeHandle ISubscribe.SubscribeEvent
&&&&&&&&&&& add { subscribeEvent += }
&&&&&&&&&&& remove { subscribeEvent -= }
&&&&&&& #endregion
&&&&&&& #region IPublish Members
&&&&&&& public PublishHandle PublishE
&&&&&&& event PublishHandle IPublish.PublishEvent
&&&&&&&&&&& add { PublishEvent += }
&&&&&&&&&&& remove { PublishEvent -= }
&&&&&&& #endregion
&&&&&&& public void Notify(string str)
&&&&&&&&&&& if (subscribeEvent != null)
&&&&&&&&&&&&&&& subscribeEvent.Invoke(string.Format(&消息来源{0}:消息内容:{1}&, _subName, str));
接下来是设计订阅者S。S类中使用了ISubscribe来与S.P进行解耦。代码如下:
namespace TJVictor.DesignPattern.SubscribePublish
&&& public class Subscriber
&&&&&&& private string _subscriberN
&&&&&&& public Subscriber(string subscriberName)
&&&&&&&&&&& this._subscriberName = subscriberN
&&&&&&& public ISubscribe AddSubscribe { set { value.SubscribeEvent += S } }
&&&&&&& public ISubscribe RemoveSubscribe { set { value.SubscribeEvent -= S } }
&&&&&&& private void Show(string str)
&&&&&&&&&&& Console.WriteLine(string.Format(&我是{0},我收到订阅的消息是:{1}&, _subscriberName, str));
最后是发布者P,继承IPublish来对S.P发布消息通知。
namespace TJVictor.DesignPattern.SubscribePublish
&&& public class Publisher:IPublish
&&&&&&& private string _publisherN
&&&&&&& public Publisher(string publisherName)
&&&&&&&&&&& this._publisherName = publisherN
&&&&&&& private event PublishHandle PublishE
&&&&&&& event PublishHandle IPublish.PublishEvent
&&&&&&&&&&& add { PublishEvent += }
&&&&&&&&&&& remove { PublishEvent -= }
&&&&&&& public void Notify(string str)
&&&&&&&&&&& if (PublishEvent != null)
&&&&&&&&&&&&&&& PublishEvent.Invoke(string.Format(&我是{0},我发布{1}消息&, _publisherName, str));
至此,一个简单的订阅发布模式已经完成了。下面是调用代码及运行结果。调用代码模拟了图2中的订阅发布关系,大家可以从代码,运行结果和示例图三方面对照着看。
#region TJVictor.DesignPattern.SubscribePublish
//新建两个订阅器
SubPubComponet subPubComponet1 = new SubPubComponet(&订阅器1&);
SubPubComponet subPubComponet2 = new SubPubComponet(&订阅器2&);
//新建两个发布者
IPublish publisher1 = new Publisher(&TJVictor1&);
IPublish publisher2 = new Publisher(&TJVictor2&);
//与订阅器关联
publisher1.PublishEvent += subPubComponet1.PublishE
publisher1.PublishEvent += subPubComponet2.PublishE
publisher2.PublishEvent += subPubComponet2.PublishE
//新建两个订阅者
Subscriber s1 = new Subscriber(&订阅人1&);
Subscriber s2 = new Subscriber(&订阅人2&);
//进行订阅
s1.AddSubscribe = subPubComponet1;
s1.AddSubscribe = subPubComponet2;
s2.AddSubscribe = subPubComponet2;
//发布者发布消息
publisher1.Notify(&博客1&);
publisher2.Notify(&博客2&);
//发送结束符号
Console.WriteLine(&&.PadRight(50,'-'));
//s1取消对订阅器2的订阅
s1.RemoveSubscribe = subPubComponet2;
//发布者发布消息
publisher1.Notify(&博客1&);
publisher2.Notify(&博客2&);
//发送结束符号
Console.WriteLine(&&.PadRight(50, '-'));
#endregion
#region Console.ReadLine();
Console.ReadLine();
#endregion
&运行结果图:
如需转载,请注明本文原创自CSDN TJVictor专栏:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:672312次
积分:10672
积分:10672
排名:第1185名
原创:157篇
转载:1074篇
评论:138条
微信扫描关注我!
阅读:4087
阅读:3800
文章:21篇
阅读:11571
(6)(5)(8)(2)(22)(16)(17)(14)(9)(42)(29)(46)(86)(54)(71)(3)(20)(53)(17)(33)(32)(38)(86)(104)(58)(82)(138)(82)(7)(32)(35)

我要回帖

更多关于 订阅号有没有支付功能 的文章

 

随机推荐