《设计模式》系列序——写给未来的自己

This is post 1 of 10 in the series “Design Patterns” 《设计模式》系列序——写给未来的自己 工厂方法模式(Factory Method)-创建型模式第一篇 抽象工厂模式(Abstract Factory Pattern)-创建型模式第二篇 单例模式(Singleton Pattern)-创建型模式第三篇 建造者模式(Builder Pattern)-创建型模式第四篇 原型模式(Prototype Pattern)-创建型模式第五篇 装饰者模式 (Decorator Pattern)-结构型模式第一篇 组合模式 (Composite Pattern)-结构型模式第二篇 适配器模式 (Adapter Pattern)-结构型模式第三篇 代理模式 (Proxy Pattern)-结构型模式第四篇 老骥伏枥,志在千里;烈士暮年,壮心不已。 起伏间,已然离开软件行业八月有余,斯余生不知是否仍有机遇重返程序员行列,遂作《设计模式》系列以祭之。 在上世纪的经典设计模式著作《设计模式 可复用面向对象软件的基础》中将设计模式进行了3个层面的划分,它们分别是创建型设计模式(Creational patterns)、结构型设计模式(Structural patterns)和行为型设计模式(Behavioral patterns),在本系列中我也将按照这种方式去划分。至于为什么选择设计模式去纪念过去十年的编程岁月,下面是鄙人一些心得体会,与大家分享: 天下武学,万变不离其宗,宗于何处?大道三千,殊途同归,归于何处?所谓模式,是对过往的继承和沉淀,从而得出的一些规律性经验。软件设计模式,也同样是前贤们在处理各种问题时所发现的一些共同的东西,这些是宝贵的经验,这些经验可以用来解决很多看起来似乎很复杂的问题,使系统变得更加健壮、易维护、可扩展。并且有意思的是这些模式不仅仅只体现在软件世界中,也是对现实世界的总结与抽象。比如中介者模式,它就像是对现实世界中中介类问题的一个抽象,你需要货,我有货,你不知道我有货,我不知道你需要货,但中介者知道我有货,也知道你需要货,中介者掌握着资源与手段,它从而肩负起你我之间沟通的能力,而你我或许永远也不知道对方。 软件工程里有一个非常重要的思想叫做面向对象思想,从而扩散出很多理论和方法,比如面向对象分析OOA,面向对象设计OOD,面向对象编程OOP,然而在这世间万物中,面向对象又何止仅仅存在于软件世界,面向对象存在于真实世界的每个角落。在面向对象的世界里,万物皆为对象,对象又由二种东西来组成:属性和行为。比如鸟儿有嘴巴,所以可以吃虫,鸟儿就是对象,嘴巴就是属性,吃虫就是行为。而在设计模式的每一个角落,无不充斥着面向对象思想,没有面向对象,就不会产生设计模式。 设计模式+面向对象,是最易学的,也是最难学的。在写这篇文章的时候,我接触它们也已10年,10年前我说它们就是这样,10年后我还是说它们就是这样,对于我自己来说似乎没有看到自己的成长,我非常希望能够通过书写这一系列文章,从而发现另一个自己。 下面来列一下本系列的文章大纲,总计约23篇设计模式文章,我应当每月会更新一篇,也就总计需要两年时间,希望在那最终完成时,自己还能保持着这份程序员的热情。 创建型模式,共有五篇。 工厂方法 (Factory Method) 抽象工厂 (Abstract Factory) 单例模式 (Singleton… Continue reading 《设计模式》系列序——写给未来的自己

MVVM模式

MVVM概述 MVVM是Model-View-ViewModel的简写。 微软的WPF带来了新的技术体验,如Sliverlight、音频、视频、3D、动画……,这导致了软件UI层更加细节化、可定制化。同时,在技术层面,WPF也带来了 诸如Binding、Dependency Property、Routed Events、Command、DataTemplate、ControlTemplate等新特性。MVVM(Model-View-ViewModel)框架的由来便是MVP(Model-View-Presenter)模式与WPF结合的应用方式时发展演变过来的一种新型架构框架。它立足于原有MVP框架并且把WPF的新特性揉合进去,以应对客户日益复杂的需求变化。 MVVM 功能图 实例解析 WPF的数据绑定与Presentation Model相结合是非常好的做法,使得开发人员可以将View和逻辑分离出来,但这种数据绑定技术非常简单实用,也是WPF所特有的,所以我们又称之为Model-View-ViewModel(MVVM)。这种模式跟经典的MVP(Model-View-Presenter)模式很相似,除了你需要一个为View量身定制的model,这个model就是ViewModel。ViewModel包含所有由UI特定的接口和属性,并由一个 ViewModel 的视图的绑定属性,并可获得二者之间的松散耦合,所以需要在ViewModel 直接更新视图中编写相应代码。数据绑定系统还支持提供了标准化的方式传输到视图的验证错误的输入的验证。 在视图(View)部分,通常也就是一个Aspx页面。在以前设计模式中由于没有清晰的职责划分,UI 层经常成为逻辑层的全能代理,而后者实际上属于应用程序的其他层。MVP 里的M 其实和MVC里的M是一个,都是封装了核心数据、逻辑和功能的计算关系的模型,而V是视图(窗体),P就是封装了窗体中的所有操作、响应用户的输入输出、事件等,与MVC里的C差不多,区别是MVC是系统级架构的,而MVP是用在某个特定页面上的,也就是说MVP的灵活性要远远大于MVC,实现起来也极为简单。 我们再从IView这个interface层来解析,它可以帮助我们把各类UI与逻辑层解耦,同时可以从UI层进入自动化测试(Unit/Automatic Test)并提供了入口,在以前可以由WinForm/Web Form/MFC等编写的UI是通过事件Windows消息与IView层沟通的。WPF与IView层的沟通,最佳的手段是使用Binding,当然,也可以使用事件;Presenter层要实现IView,多态机制可以保证运行时UI层显示恰当的数据。比如Binding,在程序中,你可能看到Binding的Source是某个interface类型的变量,实际上,这个interface变量引用着的对象才是真正的数据源。 MVC模式大家都已经非常熟悉了,在这里我就不赘述,这些模式也是依次进化而形成MVC—>MVP—>MVVM。有一句话说的好:当物体受到接力的时候,凡是有界面的地方就是最容易被撕下来的地方。因此,IView作为公共视图接口约束(契约)的一层意思;View则能传达解耦的一层意思。 设计模式 因为WPF技术出现,从而使MVP设计模式有所改进,MVVM 模式便是使用的是数据绑定基础架构。它们可以轻松构建UI的必要元素。 可以参考The Composite Application Guidance for WPF(prism) View绑定到ViewModel,然后执行一些命令在向它请求一个动作。而反过来,ViewModel跟Model通讯,告诉它更新来响应UI。这样便使得为应用构建UI非常的容易。往一个应用程序上贴一个界面越容易,外观设计师就越容易使用Blend来创建一个漂亮的界面。同时,当UI和功能越来越松耦合的时候,功能的可测试性就越来越强。 在MVP模式中,为了让UI层能够从逻辑层上分离下来,设计师们在UI层与逻辑层之间加了一层interface。无论是UI开发人员还是数据开发人员,都要尊重这个契约、按照它进行设计和开发。这样,理想状态下无论是Web UI还是Window UI就都可以使用同一套数据逻辑了。借鉴MVP的IView层,养成习惯。View Model听起来比Presenter要贴切得多;会把一些跟事件、命令相关的东西放在MVC的’C’,或者是MVVM的’Vm’ MVVM优点 MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大有点: 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的”View”上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。  独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,使用Expression Blend可以很容易设计界面并生成xaml代码。 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。 MVVM控件 使用MVVM来开发用户控件[1]。由于用户控件在大部分情况下不涉及到数据的持久化,所以如果将M纯粹理解为DomainModel的话,使用MVVM模式来进行自定义控件开发实际上可以省略掉M,变成了VVM。

浅谈javascript继承的设计思想

我一直很难理解Javascript语言的继承机制。 它没有”子类”和”父类”的概念,也没有”类”(class)和”实例”(instance)的区分,全靠一种很奇特的”原型链”(prototype chain)模式,来实现继承。 我花了很多时间,学习这个部分,还做了很多笔记。但是都属于强行记忆,无法从根本上理解。 直到昨天,我读到法国程序员Vjeux的解释,才恍然大悟,完全明白了Javascript为什么这样设计。 下面,我尝试用自己的语言,来解释它的设计思想。彻底说明白prototype对象到底是怎么回事。其实根本就没那么复杂,真相非常简单。

设计模式:抽象工厂模式(Abstract Factory)

概述 在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时由于需求的变化,往往存在着更多系列对象的创建工作。如何应对这种变化?如何绕过常规的对象的创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?这就是我们要说的抽象工厂模式。 意图 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 模型图 逻辑模型:

设计模式:单件模式(Singleton Pattern)

概述 Singleton模式要求一个类有且仅有一个实例,并且提供了一个全局的访问点。这就提出了一个问题:如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?客户程序在调用某一个类时,它是不会考虑这个类是否只能有一个实例等问题的,所以,这应该是类设计者的责任,而不是类使用者的责任。 从另一个角度来说,Singleton模式其实也是一种职责型模式。因为我们创建了一个对象,这个对象扮演了独一无二的角色,在这个单独的对象实例中,它集中了它所属类的所有权力,同时它也肩负了行使这种权力的职责! 意图 保证一个类仅有一个实例,并提供一个访问它的全局访问点。 模型图 逻辑模型图: 物理模型图: 生活中的例子 美国总统的职位是Singleton,美国宪法规定了总统的选举,任期以及继任的顺序。这样,在任何时刻只能由一个现任的总统。无论现任总统的身份为何,其头衔”美利坚合众国总统”是访问这个职位的人的一个全局的访问点。 五种实现 1.简单实现 public sealed class Singleton { static Singleton instance=null; Singleton() { } public static Singleton Instance { get { if (instance==null) { instance = new Singleton(); } return instance; } } } 这种方式的实现对于线程来说并不是安全的,因为在多线程的环境下有可能得到Singleton类的多个实例。如果同时有两个线程去判断(instance == null),并且得到的结果为真,这时两个线程都会创建类Singleton的实例,这样就违背了Singleton模式的原则。实际上在上述代码中,有可能在计算出表达式的值之前,对象实例已经被创建,但是内存模型并不能保证对象实例在第二个线程创建之前被发现。 该实现方式主要有两个优点: 由于实例是在 Instance 属性方法内部创建的,因此类可以使用附加功能(例如,对子类进行实例化),即使它可能引入不想要的依赖性。 直到对象要求产生一个实例才执行实例化;这种方法称为“惰性实例化”。惰性实例化避免了在应用程序启动时实例化不必要的 singleton。 2.安全的线程 public sealed class Singleton {… Continue reading 设计模式:单件模式(Singleton Pattern)