2004-10-18 15:57:00 ackhqiu 阅读数 708
  • SCRUM敏捷开发视频教程

    SCRUM敏捷开发视频教程,该课程为你分享SCRUM敏捷开发,理解敏捷的本质,认识中国IT行业对敏捷的挑战,学会让敏捷落地的实用招数。 嘉宾介绍:张传波 1. 创新工场创业课程(敏捷课程)讲师 2.软件研发管理佳实践顾问(曾任华为某团队研发顾问) 3. 中国敏捷联盟《ADBOK》(敏捷开发知识体系)项目组成员 二十年软件开发、软件设计、需求分析、项目管理、部门管理、公司管理及过程改进等经验,亲历“无数”项目,涉猎建筑、通讯、互联网、电力、金融、制造业、政府等领域,熟悉软件生命周期的全部过程

    10404 人正在学习 去看看 CSDN讲师
“开-闭”原则(OCP)对可变性封装
 
The Open The Open--Closed PrincipleClosed Principle
任何系统在其生命周期中都会发生变化。如果我们希望开发出的系统不会在第一版本后就被抛弃,那么我们就必须牢牢记住这一点。
软件组成实体(类,模块,函数,等等)应该是可扩展的,但是不可修改的。
OCP OCP特征 特征
可扩展(对扩展是开放的)
模块的行为功能可以被扩展,在应用需求改变或需要满足新的应用需求时,我们可以让模块以不同的方式工作
不可更改(对更改是封闭的)
这些模块的源代码是不可改动的。任何人都不许修改模块的源代码。
关键是抽象!
模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允许修改(closed for modification)的;同时,通过从这个抽象体派生,也可扩展此模块的行为功能。
符合OCP原则的程序只通过增加代码来变化而不是通过更改现有代码来变化,因此这样的程序就不会引起象非开放―封闭(open-closed)的程序那样的连锁反应的变化。

对可变性的封装
考虑系统中什么可能会发生变化
一种可变性不应当散落在代码的很多角落里,而应当被封装到一个对象里
正确理解继承
一种可变性不应当与另一个可变性混合在一起
选择性的封闭(Strategic Closure)没有任何一个大的程序能够做到100%的封闭。一般来讲,无论模块是多么的“封闭”,都会存在一些无法对之封闭的变化。既然不可能完全封闭,因此就必须选择性地对待这个问题。也就是说,设计者必须对于他(她)设计的模块应该对何种变化封闭做出选择。

里氏替换原则(LSP)如何进行继承

Liskov替换原则替换原则
LSP
LSP The The Liskov Substitution Principle
OCP原则背后的主要机制是抽象和多态。支持抽象和多态的关键机制是继承。
LSP LSP的定义 的定义
若对于每一个类型S的对象o1,都存在一个类型T的对象o2,使得在所有针对T编写的程序P中,用o1替换o2后,程序P的行为功能不变,则S是T的子类型。
LSP原则清楚地指出,OOD中Is-A关系是就行为功能而言。行为功能(behavior)不是内在的、私有的,而是外在、公开的,是客户程序所依赖的。行为功能(behavior)才是软件所关注的问题!所有派生类的行为功能必须和客户程序对其基类所期望的保持一致。
LSP LSP和DBC DBC
DBC(Design by Contract)定义把类和其客户之间的关系看作是一个正式的协议,明确各方的权利和义务。DBC对类的要求类的方法声明为先决条件(precondition)和后续条件(postcondition)。为了让方法得以执行,先决条件必须为真。完成后,方法保证后续条件为真。DBC对派生类的要求当重新定义派生类中的例行程序时,我们只能用更弱的先决条件和更强的后续条件替换之。
LSP-结论
LSP原则是符合OCP原则应用程序的一项重要特性。仅当派生类能完全替换基类时,我们才能放心地重用那些使用基类的函数和修改派生类型。
 
依赖倒转原则(DIP)针对接口编程

高层模块不应该依赖于低层模块。二者都应该依赖于抽象。
抽象不应该依赖于细节。细节应该依赖于抽象。
实施重点
从问题的具体细节中分离出抽象,以抽象方式对类进行耦合
不足
导致生成大量的类
假定所有的具体类都是会变化的,这也不总是正确的
DIP与设计模式
DIP以LSP为基础,是实现OCP的主要手段,是设计模式研究和应用的主要指导原则

接口隔离原则(ISP)恰当的划分角色和接口
接口的污染(Interface Contamination)一个没有经验的设计师往往想节省接口的数目,将一些功能相近或功能相关的接口合并,并将这看成是代码优化的一部分。
定义:从一个客户类的角度来讲:一个类对另外一个类的依赖性应当是建立在最小的接口上的。使用多个专门的接口比使用单一的总接口要好

合成/聚合复用原则(CARP)尽量使用合成/聚合、尽量不使用继承
定义:在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用这些对象的目的
2007-07-16 00:43:00 mydriverc 阅读数 2261
  • SCRUM敏捷开发视频教程

    SCRUM敏捷开发视频教程,该课程为你分享SCRUM敏捷开发,理解敏捷的本质,认识中国IT行业对敏捷的挑战,学会让敏捷落地的实用招数。 嘉宾介绍:张传波 1. 创新工场创业课程(敏捷课程)讲师 2.软件研发管理佳实践顾问(曾任华为某团队研发顾问) 3. 中国敏捷联盟《ADBOK》(敏捷开发知识体系)项目组成员 二十年软件开发、软件设计、需求分析、项目管理、部门管理、公司管理及过程改进等经验,亲历“无数”项目,涉猎建筑、通讯、互联网、电力、金融、制造业、政府等领域,熟悉软件生命周期的全部过程

    10404 人正在学习 去看看 CSDN讲师
面向对象分析与设计
设计模式:可复用面向对象软件的基础
敏捷软件开发:原则、模式与实践
重构:改善既有代码的设计
refactoring to patterns


学习了面向对象语言,并不一定能够变出面向对象的好程序
2016-08-21 07:52:40 csujiangyu 阅读数 370
  • SCRUM敏捷开发视频教程

    SCRUM敏捷开发视频教程,该课程为你分享SCRUM敏捷开发,理解敏捷的本质,认识中国IT行业对敏捷的挑战,学会让敏捷落地的实用招数。 嘉宾介绍:张传波 1. 创新工场创业课程(敏捷课程)讲师 2.软件研发管理佳实践顾问(曾任华为某团队研发顾问) 3. 中国敏捷联盟《ADBOK》(敏捷开发知识体系)项目组成员 二十年软件开发、软件设计、需求分析、项目管理、部门管理、公司管理及过程改进等经验,亲历“无数”项目,涉猎建筑、通讯、互联网、电力、金融、制造业、政府等领域,熟悉软件生命周期的全部过程

    10404 人正在学习 去看看 CSDN讲师

最近在重构老系统的代码,感觉有些疑惑,故重新看了《敏捷开发软件开发:原则、模式和实践》,记录一下。
面向对象设计要遵守下面几个原则:

类单一职责原则(SPR)

每个类承担的职责应该单一,实现高内聚。如果这个类承担太多,那么它变动的可能性很大,因为有太多原因导致这个类变化。就一个类而言,应该仅有一个引起它变化的原因。任何在设计类的时候,都需要考虑到这个类的职责,即这个类的边界。这提示我们,在设计系统或者模块的时候,都要考虑各自的边界。如今在微服务流行的时代,同样能看到该原则的身影。记着职责!边界!

开放-封闭原则(OCP)

对修改是封闭的,对扩展是开放的。这是面向对象设计最为核心的原则。通过封装变化,抽象出接口,就可以在不用修改原有代码的基础上,通过扩展接口,增加新功能。这需要我们预测变为,通过接口隔离变化。

Liskov替换原则(LSP)

根据该原则,子类必须能够替换掉它们的基类,也就是说使用基类的方法或函数能够顺利地引用子类对象。LSP原则与单一职责原则和接口分离原则密切相关,如果一个类比子类具备更多功能,很有可能某些功能会失效,这就违反了LSP原则。为了遵循该设计原则,派生类或子类必须增强功能。

依赖倒置原则(DIP)

高层模块不应该依赖于底层模块,二者都应该依赖于抽象。抽象不依赖于细节,细节应该依赖于抽象。这也是Spring设计的核心思想。

接口隔离原则(ISP)

不应该强迫客户依赖于他们不用的方法。这个原则用来处理胖接口。给我们启发是对接口分组,分离接口,不要污染接口。

2010-11-18 15:54:00 zufeng_chen 阅读数 608
  • SCRUM敏捷开发视频教程

    SCRUM敏捷开发视频教程,该课程为你分享SCRUM敏捷开发,理解敏捷的本质,认识中国IT行业对敏捷的挑战,学会让敏捷落地的实用招数。 嘉宾介绍:张传波 1. 创新工场创业课程(敏捷课程)讲师 2.软件研发管理佳实践顾问(曾任华为某团队研发顾问) 3. 中国敏捷联盟《ADBOK》(敏捷开发知识体系)项目组成员 二十年软件开发、软件设计、需求分析、项目管理、部门管理、公司管理及过程改进等经验,亲历“无数”项目,涉猎建筑、通讯、互联网、电力、金融、制造业、政府等领域,熟悉软件生命周期的全部过程

    10404 人正在学习 去看看 CSDN讲师

敏捷软件开发-面向对象设计的11原则
"你不必严格遵守这些原则,违背它们也不会被处以宗教刑罚.
但你应当把这些原则看成警铃,若违背了其中的一条,那么警铃就会响起."

1.SRP单一职责原则[适用于类功能]
  (就一个类而言,应该仅有一个引起它变化的原因.)
  详细说明:
  如果一个类承担的职责过多,就等于把这些职责耦合在一起.
  一个职责的变化可能会削弱或者抑制这个类完成其它职责的能力.
  这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏.
  结论:
  它是所有类设计原则最简单的,也是最难正确使用的.
  我们会自然的把职责结合在一起,软件设计真正要做的内容就是发现职责并把那些职责相互分离.

2.OCP开放-封闭原则[适用于类抽象]
  (软件实体(类,模块,函数...)应该是可以扩展的,但是不可以修改.)
  详细说明:
  OCP=对于扩展是开放的,对于修改是封闭的.
  如果程序中的一处改动就会产生连锁反应,导致一系列相关模块的改动,那么设计就有臭味.
  OCP建议我们如果要对系统进行重构,就只需要添加新的代码,而不必改动已经正常运行的代码.
  结论:
  在许多方面,OCP都是面向对象设计的核心.
  尊循它可以带来巨大的好处(程序的灵活性,可重用性,可维护性).
  在代码中肆意使用OCP也不是一个好主意.
  正确的做法是:开发人员仅仅对程序中呈现频繁变化的部分做出抽象!拒绝不成熟的抽象和抽象本身一样重要!
 
3.LSP Liskov替换原则[适用于类层次]
  (子类型必须能够替换掉它们的基类型.)
  详细说明:
  Barbara Liskov在1988年说道:
  Liskov替换性质:若对每个类型S的对象O1,都存在一个类型T的对象O2,
  在所有针对类型T编写的程序P中,用O1代换O2后,程序P行为功能不变,则类型S是类型T的子对象.
  结论:
  LSP是使用OCP开放-封闭原则成为可能的主要原则之一,
  正是子类型的可替换性才能用基类类型(基类引用或者指针)的模块在无需修改的情况下就可以扩展.
  这种可替换性是开发人员可以隐式依赖的东西.
  因此,如果没有显示的强制基类类型的契约,那么代码就必须良好并明显的表达出这一点.
  术语"IS-A"不能作为子类型的定义,
  子类型的正确定义是"可替换性","可替换性"可以通过显式或者隐式的(动态绑定必须用基类类型)契约.
 
4.DIP依赖倒置原则[适用于类层次]
  (抽象不应该依赖细节.细节应该依赖抽象.)
  详细说明:
  a.高层模块不应该依赖于低层模块,二者都应该依赖抽象(使用接口或者虚类来连接).
  b.抽象不应该依赖于细节,细节应该依赖于抽象.
  结论:
  使用传统的过程化程序设计方法所创建出来的依赖关系结构和策略是依赖于细节.
  DIP使得细节和策略都依赖于抽象,并且常常为客户定制服务接口.
  事实上,这种依赖关系的倒置是好的面向对象的程序设计的标记.
  DIP正确应用对于可重用框架是必须的,对于构建在变化面前富有弹性的代码也是非常重要的.
  由于抽象和细节被DIP彼此隔离,所以代码也非常容易维护.


5.ISP接口隔离原则[适用于类的接口]
  不应该强迫客户程序依赖于它们不用的方法.
  接口属于客户,不属于它所在的类层次结构.
  详细说明:
  分离客户就是分离接口.分离接口有2种方法:委托和多重继承
  接口隔离原则是用来处理胖接口所具有的缺点.
  如果类接口不是内聚的,就表示该类的接口是胖的,需要减肥.
  减肥的原则是接口分成多组方法,每一组方法都服务于一组不同的客户程序!
  客户程序面对的就是多个具有内聚接口的抽象基类.

  结论:
  胖类会导致它们的客户程序之间产生不正常的有害的耦合关系.
  当客户程序要求胖类进行一个改动时,会影响到所有其它户程序.
  因此,程序应该仅仅依赖于它们实际调用的方法.
  通过把胖类的接口分解为多个特定的客户程序的接口,可以实现这个目标.
  每个特定于客户程序的接口仅仅声明它自己调用的函数.
  解除了类的客户程序之间依赖关系,使它们互不依赖.
 
 
6.REP重用发布等价原则[适用于包]
  (重用的粒度就是发布的粒度)
  详细说明:
  当你重用别人一个类库时,你的期望是什么?
  当然是好的文档,可以工作的代码,规格清晰的接口!
  你希望作者会一直维护类库代码,当作者都把类库的接口和功能进行任何改变时,你希望得到通知.
  代码的作者把它们的软件组织到一个包中(dll,jar,...),所以我们重用的粒度就是包的发布粒度.
  结论:  
  一个包的重用粒度和和发布粒度一样大,由于重用性是基于包的,所以可重用的包必须包含可重用的类.
 

7.CCP共同封闭原则[适用于包]
  (包中的所有类对于同一类性质的变化应该是共同封闭的.
  一个变化若对一个包产生影响,则将对该包中的所有类产生影响,而对于其它包不造成任何影响.)
  详细说明:
  这是SRP单一职责原则对包的重新规定.这规定了一个包不应该包含多个引用包变化的原因.
  在大多数应用中,可维护性超过可重用性.
  代码更改:如果代码要更改,原意更改都集中在一个包中,而不是分布于多个包中.
  代码发布:我们也只发布更改中的包!
  结论:    
  CCP鼓励我们把可以由于同样的原因而更改的所有类共同聚集在同一个包中.

8.CRP共同重用原则[适用于包]
  (一个包中的所有类应该是共同重用的.
  如果重用了包中的一个类,那么就要重用包中的所有类.)
  详细说明:
  一个包中的所有类应该是共同重用的.
  结论:    
  如果重用了包中的一个类,那么就要重用包中的所有类.
  这个原则可以帮助我们决定哪些类应该放进同一个包中.

9.ADP无环依赖原则[适用于包]
  (在包的依赖关系图中不允许存在环.)
  详细说明:
  如果开发环境中有许多开发人员都在更改相同的源代码文件集合的情况,
  因为有人比你走的晚,且改了你所依赖一些东西(类或者方法),第二天来上班,
  你昨天完成的功能,今天不能正常工作,那么就会发生"晨后综合症"!
  针对此问题有两个解决方案:"每周构建"和"消除依赖环"  
  每周构建:应用于中等规模的项目中,它的工作方式为:每周1-4,开发人员各自工作在私人的代码空间,周5-6联合调试!
  消除依赖环:通过把开发环境划分成可发布的包,可以解决依赖环.
  结论:
  解决包之间的依赖环有两个主要方法:
  1.使用依赖倒置原则,在类和依赖类之前添加一个依赖的接口或者抽象类,解除依赖环.
  2.添加新类,把类和依赖类之间的依赖移到一个新的类,解除依赖环.


10.SDP稳定依赖原则[适用于包]
  (朝着稳定的方向进行依赖.)
  详细说明:
  设计不是完全固定的,要使设计可维护,某种程序的易变性是必要的.
  使用这个原则,我们可以创建对某些变化类型敏感的包.

  其它的包不要依赖这个要变的包.
  软件包就可以分为稳定包和可变包!
  如何识别稳定包和可变包?如果许多其它的包都依赖此包,那么它就是稳定包,否则就是可变包!
  把包放在不同的位置,它的稳定性是不同的.
  如何计算一个包的不稳定性?(输入耦合度Ca,输出耦合度Ce)
  不稳定值=Ce/(Ca+ce),此值越低越稳定!
  结论:
  把可变包不稳定值降低的方法是:为它加上一个抽象外衣(interface/抽象类),其它包调用抽象外衣!
  可变包为抽象外衣的实现!


11.SAP稳定抽象原则[适用于包]
  (包的抽象程序应该和其它稳定程序一致.)
  详细说明:   
  此原则把包的稳定性和抽象性联系到一起.
  一个稳定的包应该是抽象的,这样它的稳定性就不会使其无法扩展;
  一个不稳定的包应该具体的, 这样它的不稳定性使代码易于修改.

  结论:
  它指出一个包有时候应该达到部分是可抽象的,部分是不稳定的原则

2016-12-16 16:18:37 xxf159797 阅读数 403
  • SCRUM敏捷开发视频教程

    SCRUM敏捷开发视频教程,该课程为你分享SCRUM敏捷开发,理解敏捷的本质,认识中国IT行业对敏捷的挑战,学会让敏捷落地的实用招数。 嘉宾介绍:张传波 1. 创新工场创业课程(敏捷课程)讲师 2.软件研发管理佳实践顾问(曾任华为某团队研发顾问) 3. 中国敏捷联盟《ADBOK》(敏捷开发知识体系)项目组成员 二十年软件开发、软件设计、需求分析、项目管理、部门管理、公司管理及过程改进等经验,亲历“无数”项目,涉猎建筑、通讯、互联网、电力、金融、制造业、政府等领域,熟悉软件生命周期的全部过程

    10404 人正在学习 去看看 CSDN讲师

 一、简介:

S.O.L.I.D五大原则能帮助我们成为更优秀的开发人员。

S.O.L.I.D 是面向对象设计(OOD)的头五大基本原则的首字母缩写,

由俗称「鲍勃大叔」的 Robert C. Martin 提出。

这些原则,结合在一起能够方便程序员开发易于维护和扩展的软件,也让开发人员轻松避免代码异味,易于重构代码,也是敏捷或自适应软件开发的一部分。

二、面向对象的五大原则:

单一职责原则SRP:Single Responsibility Principle
开放封闭原则OCP:Open-Close Principle
Liskov替换原则LSP:Liskov Substitution Principle
依赖倒置原则DIP:Dependency Invertion Principle
接口隔离原则ISP:Interface Separate Principle

在面向对象设计中,如何通过很小的设计改变就可以应对设计需求的变化,这是令设计者极为关注的问题。为此不少OO先驱提出了很多有关面向对象的设计原则用于指导OO的设计和开发。下面是几条与类设计相关的设计原则。


三、详细说明五大原则:

1.单一职责(the Single ResponsibilityPrinciple SRP)

系统中的每一个对象都应该只有一个单独的职责,而所有对象所关注的就是自身职责的完成。

每一个职责都是一个设计的变因,需求变化的时候,需求变化反映为类职责的变化。当你系统里面的对象都只有一个变化的原因的时候,你就已经很好的遵循了SRP原则。

单一职责可以是类级别的单一,也可以是行为上的单一

 

2.开闭原则(the OpenClosed Principle OCP)

  一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。因此在进行面向对象设计时要尽量考虑接口封装机制、抽象机制和多态技术。该原则同样适合于非面向对象设计的方法,是软件工程 设计方法的重要原则之一。
我们以收音机的例子为例,讲述面向对象的开闭原则。我们收听节目时需要打开收音机电源,对准电台频率和进行音量调节。但是对于不同的收音机,实现这三个步骤的细节往往有所不同。比如自动收缩电台的收音机和按钮式收缩在操作细节上并不相同。因此,我们不太可能针对每种不同类型的收音机通过一个收音机类来实现(通过重载)这些不同的操作方式。但是我们可以定义一个收音机接口,提供开机、关机、增加频率、降低频率、增加音量、降低音量六个抽象方法。不同的收音机继承并实现这六个抽象方法。这样新增收音机类型不会影响其它原有的收音机类型,收音机类型扩展极为方便。此外,已存在的收音机类型在修改其操作方法时也不会影响到其它类型的收音机。

 

3. 替换原则(the Liskov Substitution Principle LSP)

在项目中所有使用子类的地方都可用父类替换,但在调用方法的时候 ,即呈现面向对象编程的多态性。即替换原则,它是非常重要的原则,这个原则是Liskov于1987年提出的

严格的定义:如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都换成o2时,程序P的行为没有变化,那么类型T2是类型T1的子类型。 
通俗的定义:所有引用基类的地方必须能透明地使用其子类的对象。
更通俗的定义:子类可以扩展父类的功能,但不能改变父类原有的功能。

里氏替换原则包含以下4层含义:

1.子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法。

2.子类中可以增加自己特有的方法。

3.当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。


4.当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

运用替换原则时,我们尽量把类B设计为抽象类或者接口,让C类继承类B(接口B)并实现操作A和操作B,运行时,类C实例替换B,这样我们即可进行新类的扩展(继承类B或接口B),同时无须对类A进行修改。

违反里氏代换原则意味着违反了开闭原则,反之未必。里氏代换原则是使代码符合开闭原则的一个重要保证。

 

5.依赖原则 (theDependency Inversion Principle DIP)

  在进行业务设计时,与特定业务有关的依赖关系应该尽量依赖接口和抽象类,而不是依赖于具体类。具体类只负责相关业务的实现,修改具体类不影响与特定业务有关的依赖关系。

  在结构化设计中,我们可以看到底层的模块是对高层抽象模块的实现(高层抽象模块通过调用底层模块),这说明,抽象的模块要依赖具体实现相关的模块,底层模块的具体实现发生变动时将会严重影响高层抽象的模块,显然这是结构化方法的一个"硬伤"。

  面向对象方法的依赖关系刚好相反,具体实现类依赖于抽象类和接口(见图-3)。

为此,我们在进行业务设计时,应尽量在接口或抽象类中定义业务方法的原型,并通过具体的实现类(子类)来实现该业务方法,业务方法内容的修改将不会影响到运行时业务方法的调用。

高层组件不同应该依赖于底层组件,两者应该依赖于抽象

抽象不应该依赖于细节,而细节应该以来与抽象


面向对象思想

阅读数 13

什么是敏捷开发?

阅读数 6983

没有更多推荐了,返回首页