一:设计模式简介

每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。 ---- Christopher Alexander

软件设计领域设计模式: 设计模式描述了软件设计过程中某一类常见问题的解决方案。

面向对象的设计模式: 面向对象的设计模式描述了面向对象设计过程中,特定场景下,类与相互通信的对象之间常见的组织关系。

二: GOF 23种设计模式

历史性著作 《设计模式 : 可复用面向对象软件的基础》一书中描述了23种经典面向对象设计模式,创立了模式在软件设计中的地位。该书四位作者被人们并称Gang of four (GOF),“四人组”,该书描述的23种经典的设计模式被人们称为GOF 23种设计模式。

由于《设计模式 : 可复用面向对象软件的基础》一书确定了设计模式的地位,人们通常所说的设计模式隐含地表示“面向对象设计模式”。但并不意味“设计模式”就等于“面向对象设计模式”,也不意味着GOF 23种模式就表示所有“面向对象设计模式”。除了“面向对象设计模式”外还有其他的设计模式,除了GOF 23 种设计模式外还有更多的设计模式。

三:设计模式与面向对象

面向对象设计模式解决的是类与相互通信的对象之间的组织关系,包括他们的角色,职责,协作方式几个方面。

面向对象设计模式是“好的面向对象设计”,所谓“好的面向对象设计”是那些满足“应对变化,提高复用”的设计。

面向对象的设计模式描述的是软件设计,因此它是独立于编程语言的,但面向对象的设计模式最终实现仍然要用面向对象的编程语言来表达。

面向对象设计模式不像算法技巧,可以照搬照用,它是建立在对“面向对象”纯熟,深入的理解的基础上的经验性认识。掌握面向对象设计模式的前提是首先掌握“面向对象”。

四:从编程语言直观的了解面向对象

各种面向对象编程语言互相有别,但都能看到他们面向对象的三大机制,“封装”,“继承”,“多态”。
封装:隐藏内部实现
继承:复用现有代码
多态:改写对象行为

使用面向对象的编程语言,可以推动程序员以面向对象的思维来思考软件设计结构,从而强化面向对象的编程范式。

C#是一门支持面向对象编程的优秀语言,包括:各种级别的封装支持:单实现继承+多接口实现;抽象方法与虚方法重写。

五:OOPL并非面向对象的全部

通常面向对象的编程语言(OOPL)认识到的面向对象,并不是面向对象的全部,甚至只是浅陋的面向对象。

OOPL的三大机制“封装”,“继承”,“多态”可以表达面向对象的所有概念,但这三大机制本身并没有刻画出面向对象的核心精神。换言之,既可以用这三大机制做出“好的面向对象设计”,也可以用着三大机制做出“差的面向对象设计”。不是使用了面向对象语言就实现了面向对象的设计与开发。因此我们不能依赖编程语言的面向对象机制,来掌握面向对象。

OOPL没有回答面向对象的根本性问题——我们为什么要使用面向对象?我们应该怎样使用三大机制来实现“好的面向对象”?我们应该遵循什么样的面向对象原则 ?
任何一个严肃的面向对象的程序员,都需要系统地学习面向对象的知识,单纯从编程语言上获得的面向对象知识,不能够胜任面向对象设计与开发。

六:示例

示例场景:
我们需要设计一个人事系统,其中一个功能是对各种不同类型的员工,计算其当月工资——不同类型的员工,拥有不同的薪资计算制度。

结构化做法:

1.获得人事系统中所有可能的员工类型。

2.根据不同员工类型所对应的不同薪资制度,计算工资。

enum EmployeeType {
Engineer;
Sales;
Manager;
..........
}

//薪资计算

if(type==EmployeeType.Engineer)
{
.............
}
else if(type==EmployeeType.Sales)

{
.............
}
.............

面向对象设计做法:

1.根据不同员工类型设计不同的类,并使这些类继承自一个Employee抽象类,其中有一个抽象方法GetSalary。

2.在各自不同的员工类中,根据自己的薪资制度,重写(override)GetSalary方法。

abstract class Employee{
...
public abstract float GetSalary();

}

class Engineer:Employee{
...
public override float GetSalary(){

}
}

class Sales:Employee{
...
public override float GetSalary(){

}
}

//显示薪资程序

Employee e =EmployeeFactory.GetEmployee(id);

MessageBox.show(e.GetSalary());

七:面向结构做法与面向对象做法对比

示例场景:

随着公司业务规模拓展,出现了更多类型的员工,比如钟点工,计件工。。。。。等等,这对人事管理系统提出了挑战--原有的程序必须改变。

结构化做法:

几乎所有涉及到员工类型的地方,都需要修改,代码需要重新编译,重新部署。

面向对象做法:

只需要添加新的类文件,定义新的员工类,继承Employee类重写GetSalary()方法,然后EmployeeFactory.GetEmployee方法中根据条件,产生新的员工类型就可以了。其他地方(显示程序,原有员工类)不需要做任何改变。

总结: 面向对象的做法在应对需求变化的时候更为灵活。

八:重新认识面向对象

从宏观层面来看,面向对象的构建方式更能适应软件变化,能将变化所带来的影响减为最小。

从微观上层来看,面向对象的方式更强调各个类的“责任”,新增员工类型不会影响原来员工类型的实现代码——这更符合真实的世界,也更能控制变化所影响的范围,毕竟Enginner类不应该为新增的“钟点工”来买单。

对象是什么?
从概念层面讲,对象是某种拥有责任的抽象。
从规格层面讲,对象是一系列可以被其他对象使用的公共接口。
从语言层面来看,对象封装了代码和数据。

九:从设计原则到设计模式

针对接口编程,而不是针对实现编程:客户无需知道所使用对象的特定类型,只需知道对象拥有客户所期望的接口。

优先使用对象组合,而不是类继承:类继承通常为“白箱复用”,对象组合通常为“黑箱复用”。继承在某种程度上破坏了封装性,子类父类耦合度高,而对象组合则只要求被组合的对象具有良好定义的接口,耦合度低。

封装变化点:使用封装来创建对象之间的分界层,让设计者可以在分界成的一侧进行修改,而不会对另一侧产生不良影响,从而实现层次间的松耦合。

使用重构得到模式:设计模式的应用不宜先入为主,一上来就使用设计模式是对设计模式最大的误用,没有一步到位的设计模式。敏捷软件开发实践提倡的”Refactoring to patterns“ 是目前公认的最好的使用设计模式的方法。

十:设计原则

单一职责原则(SRP):一个类应该仅有一个引起它变化的原因。

开放封闭原则(OCP):类模块应该是可扩展的,但是不可修改(对扩展开放,对更改封闭。)

Liskov 替换原则(LSP):子类必须能够替换它们的基类。

依赖倒置原则(DIP):高层模块不应该依赖低层模块,二者都应该依赖于抽象。抽象不应该依赖于实现细节,实现细节应该依赖于抽象。

接口隔离原则(ISP):不应该强迫客户程序依赖于它们不用的方法。

C#面向对象设计模式纵横谈——1.面向对象设计模式与原则的更多相关文章

  1. 面向对象设计模式纵横谈:Singelton单件模式(笔记记录)

       李建忠老师讲的<面向对象设计模式纵横谈>,早就看过了,现在有了时间重新整理一下,以前的博客[赛迪网]没有了,现在搬到博客园,重新过一遍,也便于以后浏览. 设计模式从不同的角度分类会得 ...

  2. 第一章 引言--《设计模式-可复用面向对象软件的基础》Erich Gamma

    第一章 引言 本章主要是让我们大致明白设计模式是干嘛用的,模式分类,设计模式如何解决设计问题以及几种常见的面向对象设计中软件的复用方法. 1.什么是设计模式? 个人理解概括,设计模式是对一类问题的抽象 ...

  3. [Head First设计模式]餐馆中的设计模式——命令模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  4. 从零开始单排学设计模式「简单工厂设计模式」黑铁 III

    阅读本文大概需要 2 分钟. 本篇是设计模式系列的第二篇,虽然之前也写过相应的文章,但是因为种种原因后来断掉了,而且发现之前写的内容也很渣,不够系统.所以现在打算重写,加上距离现在也有一段时间了,也算 ...

  5. Java设计模式学习记录-GoF设计模式概述

    前言 最近要开始学习设计模式了,以前是偶尔会看看设计模式的书或是在网上翻到了某种设计模式,就顺便看看,也没有仔细的学习过.前段时间看完了JVM的知识,然后就想着JVM那么费劲的东西都看完了,说明自己学 ...

  6. Java基础-Java中23种设计模式之常用的设计模式

    Java基础-Java中23种设计模式之常用的设计模式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   一.设计模式分类 设计模式是针对特定场景给出的专家级的解决方案.总的来说设 ...

  7. Java设计模式GOF之6大设计原则

    Java设计模式GOF之6大设计原则原则 1.开闭原则(Open Close Principle) 一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 开闭原则是面向对象的可复用设计的第一块基石 ...

  8. S.O.L.I.D 是面向对象设计(OOD)和面向对象编程(OOP)中的几个重要编码原则

    注:以下图片均来自<如何向妻子解释OOD>译文链接:http://www.cnblogs.com/niyw/archive/2011/01/25/1940603.html      < ...

  9. 我的设计模式学习笔记------>Java设计模式总概况

    设计模式(Design Pattern)的概念最早起源于建筑设计大师Alexander的<建筑的永恒方法>一书,尽管Alexander的著作是针对建筑领域的,但是他的观点实际上用用于所有的 ...

随机推荐

  1. Aix/Linux下自动备份oracle数据库

    曾经有个同事,来回操作开发和生产的数据库,结果误删了生产的数据库,那种心情我想不是一般人能理解的,虽然说oracle可以有方法还原,但并不是彻底的. 所以,在工作中,不管是开发还是维护,备份数据库是非 ...

  2. python爬虫成长之路(一):抓取证券之星的股票数据

    获取数据是数据分析中必不可少的一部分,而网络爬虫是是获取数据的一个重要渠道之一.鉴于此,我拾起了Python这把利器,开启了网络爬虫之路. 本篇使用的版本为python3.5,意在抓取证券之星上当天所 ...

  3. Struts2入门(四)——数据输入验证

    一.前言 1.1.什么是输入验证?为什么需要输入验证? 在上一篇文章中,我们学习了数据类型转换,我们提到了表示层数据处理的两个方法,也提到了用户输入数据需要进行类型转换才能得到我们想要的数据,那么,我 ...

  4. mysql主从之slave-skip-errors和sql_slave_skip_counter

    一般来说,为了保险起见,在主从库维护中,有时候需要跳过某个无法执行的命令,需要在slave处于stop状态下,执行 set global sql_slave_skip_counter=1以跳过命令.但 ...

  5. js判断窗体或容器滚动条到底部

    NO1---jquery判断窗体滚动条到底部 $(window).scroll(function () {if ($(window).scrollTop() >= $(document).hei ...

  6. ES6(let 和 const)

    一项新技术的出现肯定是为了解决一些问题,那么ES6的出现主要是解决了哪些问题?它的出现给我们带来了什么便利?当它没有出现的时候,某些问题怎么处理?ES6的方法和以前的方法比较又有什么不同呢?根据提出的 ...

  7. webstorm官网最新版激活:

    2016.2.3版本的破解方式:目前最新的就是2.3版本,在打开的License Activation窗口中选择"activation code",在输入框输入下面的注册码:3B4 ...

  8. 蓝牙协议中的SBC编码

    一.从信息的传输说起  上图是一个典型的蓝牙耳机应用场景.手机上的音频信息经过编码以后通过蓝牙协议被蓝牙耳机接收,经过解码以后,蓝牙耳机成功获取手机上的音频信息,然后再转化为振动被人耳识别.这是一个 ...

  9. System.Json 使用注意

    在xamarin中对json字符串进行解析,使用System.Json时出现怪问题: json-string = { "ret" : "OK" } 使用如下代码 ...

  10. 做一个java项目要经过那些正规的步骤

    理论上应该是: 一.立项 1.项目的功能的范围.实现技术方法和细节 2.需要多少人,需要的开发周期(根据客户的需求) 3.分析成本和风险 4.有相应的利润,可以立项 二.需求调研: 三.需求评审.确定 ...