C#面向对象设计模式纵横谈——1.面向对象设计模式与原则
一:设计模式简介
每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。 ---- 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.面向对象设计模式与原则的更多相关文章
- 面向对象设计模式纵横谈:Singelton单件模式(笔记记录)
李建忠老师讲的<面向对象设计模式纵横谈>,早就看过了,现在有了时间重新整理一下,以前的博客[赛迪网]没有了,现在搬到博客园,重新过一遍,也便于以后浏览. 设计模式从不同的角度分类会得 ...
- 第一章 引言--《设计模式-可复用面向对象软件的基础》Erich Gamma
第一章 引言 本章主要是让我们大致明白设计模式是干嘛用的,模式分类,设计模式如何解决设计问题以及几种常见的面向对象设计中软件的复用方法. 1.什么是设计模式? 个人理解概括,设计模式是对一类问题的抽象 ...
- [Head First设计模式]餐馆中的设计模式——命令模式
系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...
- 从零开始单排学设计模式「简单工厂设计模式」黑铁 III
阅读本文大概需要 2 分钟. 本篇是设计模式系列的第二篇,虽然之前也写过相应的文章,但是因为种种原因后来断掉了,而且发现之前写的内容也很渣,不够系统.所以现在打算重写,加上距离现在也有一段时间了,也算 ...
- Java设计模式学习记录-GoF设计模式概述
前言 最近要开始学习设计模式了,以前是偶尔会看看设计模式的书或是在网上翻到了某种设计模式,就顺便看看,也没有仔细的学习过.前段时间看完了JVM的知识,然后就想着JVM那么费劲的东西都看完了,说明自己学 ...
- Java基础-Java中23种设计模式之常用的设计模式
Java基础-Java中23种设计模式之常用的设计模式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.设计模式分类 设计模式是针对特定场景给出的专家级的解决方案.总的来说设 ...
- Java设计模式GOF之6大设计原则
Java设计模式GOF之6大设计原则原则 1.开闭原则(Open Close Principle) 一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 开闭原则是面向对象的可复用设计的第一块基石 ...
- S.O.L.I.D 是面向对象设计(OOD)和面向对象编程(OOP)中的几个重要编码原则
注:以下图片均来自<如何向妻子解释OOD>译文链接:http://www.cnblogs.com/niyw/archive/2011/01/25/1940603.html < ...
- 我的设计模式学习笔记------>Java设计模式总概况
设计模式(Design Pattern)的概念最早起源于建筑设计大师Alexander的<建筑的永恒方法>一书,尽管Alexander的著作是针对建筑领域的,但是他的观点实际上用用于所有的 ...
随机推荐
- jQ图片列表光标移动动画
本效果使用jQuery和CSS实现了图片列表,当鼠标移入时图片向左微动,移出则复原. 效果展示: http://hovertree.com/texiao/jquery/88/ 效果图如下: 其中的jQ ...
- css_03之文本、浮动
1.字体属性:①字体格式:font-family:取值:“microsoft yahei”/Arial……:②字体大小:font-size:取值:pt/px:③字体加粗:font-weight:取值: ...
- 十种MYSQL显错注入原理讲解(一)
开篇我要说下,在<代码审计:企业级Web代码安全架构>这本书中讲十种MYSQL显错注入,讲的很清楚. 感兴趣请去读完,若处于某种原因没读还想了解,那请继续往下. 1.count,rand, ...
- 一步步实现ABAP后台导入EXCEL到数据库【1】
在SAP的应用当中,导入.导出EXCEL文件的情况是一个常见的需求,有时候用户需要将大量数据定期导入到SAP的数据库中.这种情况下,使用导入程序在前台导入可能要花费不少的时间,如果能安排导入程序为后台 ...
- 详解java定时任务
在我们编程过程中如果需要执行一些简单的定时任务,无须做复杂的控制,我们可以考虑使用JDK中的Timer定时任务来实现.下面LZ就其原理.实例以及Timer缺陷三个方面来解析JavaTimer定时器. ...
- Javassist 通用工具之 CodeInjector
Javassist 通用工具之CodeInjector 最近在做一个APM项目,要在运行时代码修改.目前常用修改的几种工具有:ASM.BCEL.Javassist.经过对比,项目中采用了Javassi ...
- EF和MVC系列文章导航:EF Code First、DbContext、MVC
对于之前一直使用webForm服务器控件.手写ado.net操作数据库的同学,突然来了EF和MVC,好多新概念泉涌而出,的确犹如当头一棒不知所措.本系列文章可以帮助新手入门并熟练使用EF和MVC,有了 ...
- SQL优化 查询语句中,用 inner join 作为过滤条件和用where作为过滤条件的区别
前段时间遇到一个存储过程,参数之一是一个字符串,在存储过程中,把字符串拆分成一个临时表之后存为一个key值的临时表,作为其中一个查询条件, 逻辑实现上有两种处理方式 insert into #t se ...
- 前端开发必学技能之一———非关系数据库又像关系数据库的MongoDB快速入门第一步下载与安装
数据库总的来说,分为两个方向:关系数据库和非关系数据库.我们常见的MySQL.Oracle.SQLSerever以及IBMDB2都是属于关系数据库,这里的关系值得是二维表的结构,但是由于随着web的应 ...
- javascript判断数组中是否包含某个元素
//判断数组array中是否包含元素obj的函数,包含则返回true,不包含则返回false function array_contain(array, obj){ for (var i = 0; i ...