When you're on the way which is unknown and dangerous, just follow your mind and steer the boat.
软件模式: 设计模式、体系结构模式、分析模式、过程模式等。
ANSIIEEEStd1471一200对体系结构的定义:一个系统的基本组织,表现为系统的组件、组件之间的相互关系、组件和环境之间的相互关系以及设计和进化的原则。
黑板模式是一种常用的架构模式,应用中的多种不同数据处理逻辑相互影响和协同来完成数据分析处理。
“就好像多位不同的专家在同一黑板上交流思想,每个专家都可以获得别的专家写在黑板上的信息,同时也可以用自己的分析去更新黑板上的信息,从而影响其它专家。”
数据库模式
发布—订阅模式 (难点)
1) 一个 delegate对象一次可以搭载多个方法(methods),而不是一次一个。当我们唤起一个搭载了多个方法(methods)的delegate,所有方法以其“被搭载到delegate对象的顺序”被依次唤起。
2) 一个delegate对象所搭载的方法(methods)并不需要属于同一个类别。一个delegate对象所搭载的所有方法(methods)必须具有相同的原型和形式。然而,这些方法(methods)可以即有static也有non-static,可以由一个或多个不同类别的成员组成。
3) 一个delegate type的声明在本质上是创建了一个新的subtype instance,该 subtype 派生自 .NET library framework 的 abstract base classes Delegate 或 MulticastDelegate,它们提供一组public methods用以询访delegate对象或其搭载的方法(methods) ,与函数指针不同,委托是面向对象、类型安全并且安全的。
为了实现P与S.P, S与S.P之间的解耦,我们需要定义两个接口文件:
ISubscribe.cs
namespace TJVictor.DesignPattern.SubscribePublish { //定义订阅事件 public delegate void SubscribeHandle(string str); //定义订阅接口 public interface ISubscribe { event SubscribeHandle SubscribeEvent; } }
IPublish.cs namespace TJVictor.DesignPattern.SubscribePublish { //定义发布事件 public delegate void PublishHandle(string str); //定义发布接口 public interface IPublish { event PublishHandle PublishEvent; void Notify(string str); } }
然后我们来设计订阅器。显然订阅器要实现双向解耦,就一定要继承上面两个接口,这也是我为什么用接口不用抽象类的原因(类是单继承)。
namespace TJVictor.DesignPattern.SubscribePublish { public class SubPubComponet : ISubscribe, IPublish { private string _subName; public SubPubComponet(string subName) { this._subName = subName; PublishEvent += new PublishHandle(Notify); } #region ISubscribe Members
event SubscribeHandle subscribeEvent; event SubscribeHandle ISubscribe.SubscribeEvent { add { subscribeEvent += value; } remove { subscribeEvent -= value; } } #endregion
#region IPublish Members
public PublishHandle PublishEvent; event PublishHandle IPublish.PublishEvent { add { PublishEvent += value; } remove { PublishEvent -= value; } } #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 _subscriberName; public Subscriber(string subscriberName) { this._subscriberName = subscriberName; } public ISubscribe AddSubscribe { set { value.SubscribeEvent += Show; } } public ISubscribe RemoveSubscribe { set { value.SubscribeEvent -= Show; } } 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 _publisherName; public Publisher(string publisherName) { this._publisherName = publisherName; } private event PublishHandle PublishEvent; event PublishHandle IPublish.PublishEvent { add { PublishEvent += value; } remove { PublishEvent -= value; } } 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.PublishEvent; publisher1.PublishEvent += subPubComponet2.PublishEvent; publisher2.PublishEvent += subPubComponet2.PublishEvent; //新建两个订阅者 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
在满足对界面要求的同时,如何使软件的计算模型独立于界面的构成。
类似的结构模式
还有PAC(Presentation-Abstraction-Control)、Forward-Receiver、Publisher-Subscriber、各类可视化用户界面控件等。
Reference: 软件分析模式的形式化研究, 钟琪, 西南师范大学
分析模式是更高层次的抽象。与测试模式不同,分析模式不反应实际的软件实现,而是体现行业业务过程的概念结构。
按用途可以划分为:Accountability, Observations and measurements, Observations for Corporate finance, Referring to Objects, Inventory, Planning, trading.
Example: Party in Accountability
Reference: http://www.cnblogs.com/houleixx/archive/2009/10/20/software-engineering-process-model.html
软件过程是为了获得高质量软件所需要完成的一系列任务的框架,它规定了完成各项任务的工作步骤。通常使用生命周期模型简洁地描述软件过程。生命周期模型规定了把生命周期划分成哪些阶段及各个阶段的执行顺序,因此,也称为过程模型。常见的过程模型有瀑布模型、快速原型模型、增量模型、螺旋模型、喷泉模型等。