23种设计模式!
策略模式抽象工厂模式工厂方法模式代理模式桥接模式原型模式模板方法模式备忘录模式命令模式状态模式组合模式解释器模式适配器模式迭代器模式单例模式观察者模式访问者模式中介者模式装饰模式外观模式亨元模式职责链模式亨元模式备忘录模式
问你怕未?
虽然有这么多种模式,但基础是面向对象。其中有两样东西是屡用不爽:
一、多态
主要表现在 将子类对象赋给父类使用,或者是实现了接口的对象赋给接口进行使用。
这个父类,通常是抽象类,声明了一些抽象函数或虚函数,子类实现了这些函数。子类对象赋给父类(抽象类不能创建实例,但可以将子类实例赋给它)之后,以父类的形式进行调用,实际执行的是子类里面的代码,是为多态。因为父类(或接口)志在规定需要有那些函数而不求实现,也就是统一了口径,调用的时候,视情况挑选子类对象赋给它来使用,对于外部来讲,它只需要知道父类(或接口)就行了,从而屏蔽了许多细节,即使更换了子类对象,调用方也无须更改。
大概,这就是为什么要针对接口来编程的原因吧。
示例:
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace example{ class Program { abstract class Animal { public abstract void Shout(); } class Dog : Animal { public override void Shout() { Console.WriteLine("汪汪"); } } class Cat : Animal { public override void Shout() { Console.WriteLine("喵喵"); } } class Mouse : Animal { public override void Shout() { Console.WriteLine("吱吱"); } } static void Main(string[] args) { IListlist = new List (); list.Add(new Dog()); list.Add(new Cat()); list.Add(new Mouse()); foreach (Animal animal in list) { animal.Shout();//一切都以父类Animal之名进行调用 } Console.Read(); } }}
这部分涉及到设计模式里面的 里氏代换原则、依赖倒转原则。
二、聚合/合成
人人皆知,面向对象的三个特性是封装、继承和多态。多态上面讲了,封装,屏蔽细节,是类内部的事情,不用多言;继承,更加容易接受。面向过程的编码,提高了代码的重用,非常符合人们的直观思维,而面向对象的继承,跟面向过程代码重用的思路是一致的,子类可以直接使用父类的公开、保护属性、方法,真爽!所以就我自己而言,面向对象的特性中,继承是用得最多的,都成了下意识的动作了。
可是,继承有造成失控的危险,一层层地继承下来,东西会越来越多。我之前就是这样,比如搞了一些ASP.NET的页面类,继承了System.Web.UI.Page,然后自己又加了很多东西,有基类,有子类,层层继承,最后的页面对象,编码时,键入“.”,代码自动提示的列表里,N多东西,暴露了很多细节,原因是里面有太多的protected级别的方法、属性。后来我将这部分逻辑封装在一个独立类里面,然后在页面基类创建该类的实例,只访问其public的东西,则后面的页面使用页面类时,就只有很少的一些东西供调用了,逻辑、封装都好了很多。
继承是垂直的,而聚合/合成是横向的,我们应该尽量使用聚合/合成,是为 合成/聚合复用原则
虽然我开发生涯已有十几年,但惭愧得很,设计模式只是近期才接触。未接触之前,心里多少有点不服气,人言世无仲尼,万古如长夜。难道设计模式也这么牛,没有了它,我们就不会编程了吗?难道我们以前都在打酱油?
学习了以后,才知道自己水平真是差太远了,对面向对象的理解,仅仅皮毛而已。从此在工作中,时刻考虑着该用什么设计模式,或者这些代码是是什么设计模式,进入修炼设计模式的第二层境界:过度设计阶段。
离无招胜有招,随意使用的境界还远得很。