第6章 面向对象设计原则
面向对象设计原则
面向对象设计的原则正如牛顿三大定律在经典力学中的位置一样,“开-闭”原则(Open-Closed Principle)是面向对象的可复用设计(Object Oriented Design或OOD)的基石。
其他设计原则(里氏代换原则、依赖倒转原则、合成/聚合复用原则、迪米特法则、接口隔离原则)是实现“开-闭”原则的手段和工具。
一、“开-闭”原则(Open-Closed Principle,OCP)1.1“开-闭”原则的定义及优点1)定义:一个软件实体应当对扩展开放,对修改关闭( Software entities should be open for extension,but closed for modification.)。
即在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展。
2)满足“开-闭”原则的系统的优点a)通过扩展已有的软件系统,可以提供新的行为,以满足对软件的新需求,使变化中的软件系统有一定的适应性和灵活性。
b)已有的软件模块,特别是最重要的抽象层模块不能再修改,这就使变化中的软件系统有一定的稳定性和延续性。
c)这样的系统同时满足了可复用性与可维护性。
1.2如何实现“开-闭”原则在面向对象设计中,不允许更改的是系统的抽象层,而允许扩展的是系统的实现层。
换言之,定义一个一劳永逸的抽象设计层,允许尽可能多的行为在实现层被实现。
解决问题关键在于抽象化,抽象化是面向对象设计的第一个核心本质。
对一个事物抽象化,实质上是在概括归纳总结它的本质。
抽象让我们抓住最最重要的东西,从更高一层去思考。
这降低了思考的复杂度,我们不用同时考虑那么多的东西。
换言之,我们封装了事物的本质,看不到任何细节。
在面向对象编程中,通过抽象类及接口,规定了具体类的特征作为抽象层,相对稳定,不需更改,从而满足“对修改关闭”;而从抽象类导出的具体类可以改变系统的行为,从而满足“对扩展开放”。
对实体进行扩展时,不必改动软件的源代码或者二进制代码。
面向对象设计的基本原则和实践建议
面向对象设计的基本原则:1 层次化抽象原则,按照问题域逻辑关系来识别类;2 责任均衡分配原则,避免出现God类和Idiot类;3 简单化原则,一个方法尽量只处理一种情况,把问题要求进行的处理进行划分,识别出多种不同情况;4 封装原则,一个类的属性都不可以让外部直接访问;5 局部化原则,类之间不要冗余存储相同的数据,方法之间不能够出现控制耦合;6 完整性原则,一个类需要提供针对相应数据进行处理的完整方法集。
完整是个相对概念,一般来说是相对于问题域需求。
7 重用原则(共性抽取原则),把不同类之间具有的共性数据或处理抽象成继承关系,避免冗余;8 显式表达原则,显式表达所有想要表达的数据或逻辑,不使用数组存储位置或者常量来隐含表示某个特定状态或数据;9 信任原则,一个方法被调用时,调用者需要检查和确保方法的基本要求能够被满足,获得调用结果后需要按照约定的多种情况分别进行处理;10 懂我原则,所有类、对象、变量、方法等的命名做到“顾名思义”。
面向对象设计实践建议:(1) 首先问题结构分析和抽象表达:识别出几个关键类及其关系,这时候和具体的数据表示和结构都没有关系;(2) 根据问题要满足的功能,定义每个类外部可访问的行为,不涉及类的内部行为和数据,并规划这些类如何协同来完成系统功能,逐层分解。
(3) 对每个类,定义它应该保存的属性及类型,和相应的数据控制行为(外部可见),从而满足对外部可见行为的实现;(4) 系统输入和输出的处理。
分析输入和输出的层次性和模式特征。
如果如层次性,则按照相应模式分层进行处理。
顶层一般可交给主类进行处理;往下各个层次应该交给对输入分析结果感兴趣的类去处理,减少信息耦合度。
(5) 检查得到的设计结果是否出现违背相关原则的问题。
面向对象设计六大原则
面向对象设计六大原则面向对象设计的原则是面向对象思想的提炼,它比面向对象思想的核心要素更具可操作性,但与设计模式相比,却又更加的抽象,是设计精神要义的抽象概括。
形象地将,面向对象思想像法理的精神,设计原则则相对于基本宪法,而设计模式就好比各式各样的具体法律条文了。
面向对象设计原则有6个:开放封闭原则,单一职责原则,依赖倒置原则,Liskov替换原则,迪米特法则和接口隔离原则或合成/聚合复用原则(不同资料略有不同,这里对7个都做了整理)。
1单一职责原则(Single Responsibility Principle SRP)There should never be more than one reason for a class to change.什么意思呢?所谓单一职责原则就是一个类只负责一个职责,只有一个引起变化的原因。
如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化会削弱或抑制这个类完成其他职责的能力,这个耦合会导致脆弱的设计。
软件设计真正要做的许多内容,就是发现职责并把这些职责相互分离;如果能够想到多于一个动机去改变一个类,那么这个类就具有多于一个职责,就应该考虑类的分离。
以调制解调器为例如下图:从上述类图里面我们发现有四个方法Dial(拨通电话),Hangup(挂电话),Receive(收到信息),Send(发送信息),经过分析不难判断出,实际上Dial(拨通电话)和Hangup(挂电话)是属于连接的范畴,而Receive(收到信息)和Send(发送信息)是属于数据传送的范畴。
这里类包括两个职责,显然违反了SRP。
这样做有潜在的隐患,如果要改变连接的方式,势必要修改Modem,而修改Modem 类的结果导致凡事依赖Modem类可能都需要修改,这样就需要重新编译和部署,不管数据传输这部分是否需要修改。
因此要重构Modem类,从中抽象出两个接口,一个专门负责连接,另一个专门负责数据传送。
面向对象程序设计中的设计原则
面向对象程序设计中的设计原则在面向对象程序设计中,设计原则是非常重要的概念,它是实现高质量、可维护、可扩展的软件的基础。
本文将深入探讨面向对象程序设计中的六大设计原则:单一职责原则、开放封闭原则、里氏替换原则、依赖倒置原则、接口隔离原则和迪米特原则,并谈谈它们的应用。
单一职责原则单一职责原则(Single Responsibility Principle,SRP)说的是一个类应该只有一个引起它变化的原因,或者说一个类应该只有一个职责。
这样有助于保持类的简洁性、提高可维护性和可扩展性。
例如,一个类可能负责读取和写入文件,但如果在这个类中还包含了其他的职责,比如文件格式转换、错误处理等,那么这个类就不符合单一职责原则了。
因此,最好将这些职责分离出去,让每个类只负责自己特定的职责。
开放封闭原则开放封闭原则(Open-Closed Principle,OCP)思想是,一个软件实体应该对扩展开放,对修改关闭。
这样,对现有的代码进行修改时,不会对它的其他部分造成影响。
实现开放封闭原则的方法是利用抽象,将可变部分封装起来,使得不同的实现可以互相替换,而不需要修改其他代码。
这样,在软件变化时,只需要增加新的代码即可。
里氏替换原则里氏替换原则(Liskov Substitution Principle,LSP)是指,子类应该能够替换其父类并保持程序的正确性。
即,继承层次结构中的子类应该可以替换掉其父类并且其行为是相同的。
应该避免在子类中重写父类的实现,而是通过添加新的方法或属性来扩展功能。
这样可以保证在子类替换父类时,不会产生任何不可预知的结果。
依赖倒置原则依赖倒置原则(Dependency Inversion Principle,DIP)是指,高层模块不应直接依赖低层模块,而应该依赖它们的抽象。
它也是通过使用抽象来实现开放封闭原则的重要手段。
通过将高层模块与低层模块解耦,依赖倒置原则使系统更加灵活、可扩展、易于维护。
面向对象程序设计的理念和原则
面向对象程序设计的理念和原则一、导言面向对象程序设计(OOP)是软件开发过程中的一种常见的编程范式,从它的名字就可以看出,它更关注对象而不是过程。
本文将深入探讨面向对象程序设计的理念和原则,帮助读者更好地理解该范式。
二、什么是面向对象程序设计?面向对象程序设计是一种编程思想,其核心理念是将问题看作“对象”,对象可以是现实世界的事物,也可以是一个数据结构,还可以是一个函数等。
对于一种对象,它具有属性和方法,属性是该对象的状态特征,而方法则是该对象所能执行的操作。
封装、继承和多态是面向对象程序设计的基本特征,我们将在下面的章节中进行详细讲解。
三、封装封装是面向对象程序设计的重要特征之一,其核心理念是将数据和方法封装到一个独立的对象中,从而保证数据的隐私性和安全性。
封装使得对象之间的交互更加安全和简单,因为外部用户只需要使用对象提供的公共接口(也就是方法)即可完成访问和修改,而无需了解对象内部的具体实现细节。
封装可以有效地维护代码的可扩展性和可维护性,减少代码的耦合度。
四、继承继承是面向对象程序设计的另一个重要特征,其核心理念是在已有的类的基础上,通过继承可以创建新类,新类可以继承父类的属性和方法,同时可以添加新的属性和方法,从而使得代码的可重用性更加高效。
在继承中,父类称为基类或超类,而子类称为派生类。
继承可以有效地减少代码的冗余性,提高代码的复用度。
五、多态多态是面向对象程序设计的第三个重要特征,其核心理念是相同的消息可以引起不同对象的不同行为,也就是不同的对象可以对同一项操作做出不同的响应。
多态十分灵活,可以极大地简化程序设计的过程,提高代码的灵活性和可扩展性。
它还可以实现代码的动态绑定和运行时的类型检查,从而使得代码更加健壮和可靠。
六、面向对象程序设计的原则除了上面的三个特征之外,面向对象程序设计还有一些重要的原则,它们可以有效地减少程序设计中的错误和缺陷,提高代码的质量和可读性。
下面我们就来介绍其中几个常见的原则:1.单一职责原则(SRP)单一职责原则是指一个类只负责一种功能,也就是每个类都应该只有一个引起它变化的原因。
面向对象设计的基本原则和模式
面向对象设计的基本原则和模式面向对象设计是一种软件开发的方法论,它将现实世界中的事物抽象成对象,然后通过对象之间的交互来完成软件系统的设计和开发。
面向对象设计的基本原则和模式是其核心,它们是设计和开发高质量、可维护、可扩展软件系统的基石。
本文将会首先介绍面向对象设计的基本原则,然后再介绍面向对象设计的基本模式。
一、面向对象设计的基本原则面向对象设计的基本原则是一些通用的、普遍适用的软件设计规则,它们有助于设计出高质量、可维护、可扩展的软件系统。
下面是面向对象设计的基本原则:1.单一责任原则(SRP)单一责任原则是面向对象设计的一个基本原则,它规定一个类应该只有一个引起它变化的原因。
换句话说,一个类应该只有一个职责。
这样可以降低类的复杂度,使得类更容易理解、维护和重用。
2.开放-封闭原则(OCP)开放-封闭原则是指一个软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。
这意味着当需要改变一个软件实体的行为时,不应该修改它的源代码,而是应该通过扩展它来实现。
3.里氏替换原则(LSP)里氏替换原则是指一个子类型(派生类)必须能够替换掉它的父类型(基类)而不影响系统的功能性和可靠性。
这意味着一个接口实现的任何地方都可以被子类型替换。
4.依赖倒置原则(DIP)依赖倒置原则是指高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
具体来说就是,抽象不应该依赖于细节,而细节应该依赖于抽象。
5.接口隔离原则(ISP)接口隔离原则是指一个类不应该依赖它不需要的接口,换句话说,一个类应该尽可能多地使用它所需要的接口,而不是多余的接口。
6.迪米特原则(LoD)迪米特原则是指一个对象应该尽可能少地了解其他对象,它应该只与其直接的朋友通信。
这可以降低对象之间的耦合度,使得系统更易于维护和扩展。
以上就是面向对象设计的基本原则,它们是设计和开发高质量、可维护、可扩展软件系统的重要指导。
下面我们将介绍面向对象设计的基本模式。
设计模式:面向对象设计的六大原则(绝对详细)
设计模式:⾯向对象设计的六⼤原则(绝对详细)⽬录前⾔很久没有写博客了,⼀直给⾃⼰找借⼝说太忙了,过⼏天有空再写,⼏天之后⼜⼏天,时间就这么快速的消逝。
说到底就是⾃⼰太懒了,不下点决⼼真是不⾏。
我决定逼⾃⼰⼀把,从今天开始学习设计模式系列,并写成博⽂记录下来,做不到的话,就罚⾃⼰⼀个⽉不玩游戏 (作孽啊。
)六⼤原则⾔归正传,这是我学习设计模式系列的第⼀篇⽂章,本⽂主要讲的是⾯向对象设计应该遵循的六⼤原则,掌握这些原则能帮助我们更好的理解⾯向对象的概念,也能更好的理解设计模式。
这六⼤原则分别是:单⼀职责原则——SRP开闭原则——OCP⾥式替换原则——LSP依赖倒置原则——DIP接⼝隔离原则——ISP迪⽶特原则——LOD单⼀职责原则单⼀职责原则,Single Responsibility Principle,简称SRP。
其定义是应该有且仅有⼀个类引起类的变更,这话的意思就是⼀个类只担负⼀个职责。
举个例⼦,在创业公司⾥,由于⼈⼒成本控制和流程不够规范的原因,往往⼀个⼈需要担任N个职责,⼀个⼯程师可能不仅要出需求,还要写代码,甚⾄要⾯谈客户,光背的锅就好⼏种,简单⽤代码表达⼤概如此:public class Engineer {public void makeDemand(){}public void writeCode(){}public void meetClient(){}}代码看上去好像没什么问题,因为我们平时就是这么写的啊,但是细读⼀下就能发现,这种写法很明显不符合单⼀职责的原则,因为引起类的变化不只有⼀个,⾄少有三个⽅法都可以引起类的变化,⽐如有天因为业务需要,出需求的⽅法需要加个功能 (⽐如需求的成本分析),或者是见客户也需要个参数之类的,那样⼀来类的变化就会有多种可能性了,其他引⽤该类的类也需要相应的变化,如果引⽤类的数⽬很多的话,代码维护的成本可想⽽知会有多⾼。
所以我们需要把这些⽅法拆分成独⽴的职责,可以让⼀个类只负责⼀个⽅法,每个类只专⼼处理⾃⼰的⽅法即可。
简述面向对象设计的原则。
简述面向对象设计的原则。
面向对象设计(简称OOD)是一种软件设计方法论,它基于建模和模块化方法,将一个复杂的系统分解成一系列用于交互的简单的对象。
它的目的是使设计过程变得更加容易,从而使维护和更新更容易。
面向对象设计遵循一些基本原则,包括:一、(单一职责原则)每个对象应只负责一项功能,以及它应该完成指定任务的所有职责,而不会担负任何其他任务。
例如,在一个购物系统中,顾客对象只应负责处理客户订单,而不应该负责订单处理系统的管理。
这样做的目的是减少代码重复,降低系统整体耦合度,并降低系统的复杂性,从而使系统变得更加可维护和可扩展。
二、(开放-封闭原则)软件实体(如类、模块、函数)应该是可以扩展的,但是不可修改。
也就是说,软件实体对拓展应该是开放的,对修改是封闭的。
这样做可以使得新功能更容易添加,而不需要更改已有的功能。
三、(里氏替换原则)子类必须能替换他们的父类。
也就是说,子类的行为要与父类的行为保持一致,以便它能够替换父类而不会破坏原有的系统结构。
这种关系称为“is-a”关系,因为它表明子类和父类有一定的关系,而且子类是其父类的一个实例。
这样做的好处是,当要拓展功能时,只需要创建新的子类,而不需要修改父类,从而减少了系统的复杂性。
四、(接口隔离原则)客户端不应该依赖于它不需要的接口。
也就是说,对接口的依赖应该尽可能的小,客户端只应该依赖于它需要的接口。
这样做的好处在于,当有要求变更或拓展新功能时,只需要改变相关接口,而不需要改变客户端,从而可以减少系统的维护和更新成本。
五、(依赖倒置原则)抽象(通用)不应该依赖于具体(特殊),具体(特殊)应该依赖于抽象(通用)。
也就是说,程序应该依赖于通用的抽象接口,而不应该依赖于非标准的具体实现。
这样做的目的是让代码更容易维护和更新,从而减少系统的复杂性。
六、(协作原则)一个类应该尽可能多的协作,而不是尽可能多的执行。
也就是说,类之间的交互应尽可能少,类的实现应尽可能多。
面向对象的设计原则
面向对象的设计原则一开放-关闭原则动机一个设计良好的应用程序应该充分考虑到开发和维护阶段需求的频繁变化,通常情况下,添加一个新的功能需要做出很多修改,我们应该使对已有代码的修改最小化,因为他们已经经过了测试。
对现有代码做出修改将会以一种不可预料的方式影响它们的已有功能。
开放-关闭原则(以下简称开闭原则)开-闭原则:一个软件实体应该对扩展开发,对修改关闭。
开闭原则是说我们应该努力设计不需要修改的模块。
在扩展系统的行为时,我们只需要添加新的代码,而不需要修改已有的代码。
一般可以通过添加新的子类和重写父类的方法来实现。
满足开闭原则的模块符合下面两个标准:∙对扩展开放 ------- 模块的行为可以被扩展从而满足新的需求。
∙对修改关闭 ------- 不允许修改模块的源代码。
(或者尽量使修改最小化)这两个标准看似相互矛盾的,那么我们怎么实现他们呢?怎样实现开闭原则∙抽象∙多态∙继承∙接口要想使一个软件系统的所有模块都满足开闭原则是不太现实的,不过我们应该努力使大部分模块满足开闭原则。
开闭原则是面向对象设计的核心,满足该原则可以达到最大限度的复用和可维护性。
实例考虑下面某个类的方法:public double totalPrice(Part[] parts) {double total = 0.0;for (int i=0; i<parts.length; i++) {total += parts[i].getPrice();}return total;}上面函数的功能是计算给定的零件数组中所有零件价格的总和,如果Part是一个基类或者接口,那我们就可以利用多态的特性,当有新的零件被添加进来时不需要修改该函数的代码。
这样它就可以满足开闭原则。
但是如果我们的会计部门规定当计算主板和内存的价格时,需要添加一些额外的费用,请看下面的代码:public double totalPrice(Part[] parts) {double total = 0.0;for (int i=0; i<parts.length; i++) {if (parts[i] instanceof Motherboard)total += (1.45 * parts[i].getPrice());else if (parts[i] instanceof Memory)total += (1.27 * parts[i].getPrice());elsetotal += parts[i].getPrice();}return total;}现在它还符合开闭原则吗?不!每次会计部门发布一个新的价格政策时,我们都需要修改totalPrice()方法!它对修改不是关闭的,显然,价格政策的改变意味着我们必须修改某处的代码,那么我们应该怎么做呢?为了使用我们第一个版本的totalPrice()方法,我们需要把Part的getPrice()方法的价格政策包含进来。
面向对象设计七大原则
⾯向对象设计七⼤原则1. 单⼀职责原则(Single Responsibility Principle)每⼀个类应该专注于做⼀件事情。
2. ⾥⽒替换原则(Liskov Substitution Principle)超类存在的地⽅,⼦类是可以替换的。
3. 依赖倒置原则(Dependence Inversion Principle)实现尽量依赖抽象,不依赖具体实现。
4. 接⼝隔离原则(Interface Segregation Principle)应当为客户端提供尽可能⼩的单独的接⼝,⽽不是提供⼤的总的接⼝。
5. 迪⽶特法则(Law Of Demeter)⼜叫最少知识原则,⼀个软件实体应当尽可能少的与其他实体发⽣相互作⽤。
6. 开闭原则(Open Close Principle)⾯向扩展开放,⾯向修改关闭。
7. 组合/聚合复⽤原则(Composite/Aggregate Reuse Principle CARP)尽量使⽤合成/聚合达到复⽤,尽量少⽤继承。
原则:⼀个类中有另⼀个类的对象。
细则单⼀职责原则(Single Responsibility Principle)因为:可以降低类的复杂度,⼀个类只负责⼀项职责,其逻辑肯定要⽐负责多项职责简单的多;提⾼类的可读性,提⾼系统的可维护性;变更引起的风险降低,变更是必然的,如果单⼀职责原则遵守的好,当修改⼀个功能时,可以显著降低对其他功能的影响。
需要说明的⼀点是单⼀职责原则不只是⾯向对象编程思想所特有的,只要是模块化的程序设计,都适⽤单⼀职责原则。
所以:从⼤局上看Android中的Paint和Canvas等类都遵守单⼀职责原则,Paint和Canvas各司其职。
⾥⽒替换原则(Liskov Substitution Principle)因为:⾥⽒替换原则告诉我们,在软件中将⼀个基类对象替换成它的⼦类对象,程序将不会产⽣任何错误和异常,反过来则不成⽴,如果⼀个软件实体使⽤的是⼀个⼦类对象的话,那么它不⼀定能够使⽤基类对象。
面向对象的六大设计原则
面向对象的六大设计原则一、单一职责原则1.定义:应该有且仅有一个原因引起类的变更。
2.单一职责的好处a.类的复制性降低,实现什么职责都有清晰明确的定义b.可读性提高,复杂性降低,那当然可读性提高了c.可维护性的提高,可读性提高,当然更容易维护d.变更引起的风险降低,本身变更是必不可少的,接口的单一职责做的好,一个接口修改只针对响应的实现类有影响,对其他接口无影响,对系统的扩展性和维护性都有非常大的帮助3.总结:现实中想要全部按照单一职责原则很难在项目中得到提现,需要考虑的问题比较多,环境、工作量、人员技术水平以及资源等等;对于接口再设计的时候一定要做到单一;而对于实现类就需要多方面考虑;生搬硬套单一职责原则会引起类的剧增,反而给维护带来非常多的麻烦;俗话说原则是死的人是活的;具体问题还需据对应对4.结合我们酷客多产品接口设计案列,非常明显可以体验出单一职责的好处例如:酷客多小程序产品详情页面,相对将页面价格信息和促销信息数据的获取独立成两个单独接口;酷客多营销插件的更新迭代是比较频繁,不时新增一种营销插件;而将促销信息接口独立出后,后续无论增加多少种插件,也只需要调整促销信息接口即可,对应商品详情其他数据接口无需任何改动。
二、里氏替换原则1.定义:a.如果对每一个类型为S的对象01,都有类型为T的对象02,使得以T定义的所有程序P 在所有的对象01都带换成02时,程序P的行为没有发生变化,那么类型S是类型T的子类型b.所有引用基类的地方必须能透明地使用其子类的对象;通俗的说,就是所有能使用父类的地方都可以替换为子类,不会产生任何错误或异常,但是反过来就不行了,有子类出现的地方,父类未必就能适应2.规范:a.子类必须完全实现父类的方法i.做系统设计时,经常会定义一个接口或抽象类,然后编码实现,调用类则直接传入接口或抽象类,这里就是使用了里氏替换原则ii.在类种调用其它类时务必要使用父类或接口,如果不能使用父类或接口,则说明类的设计已经违背了LSP原则iii.如果子类不能完整地实现父类的方法,或者父类的某些方法在子类中已经发生“畸变”,则建议断开负责继承关系,采用依赖、聚集、组合等关系代替继承b.子类可以有自己的个性,子类同时也可以有属于自己的属性和方法c.覆盖或实现父类的方法时输入参数可以被放大d.覆写或实现父类的方法时输出结果可以被缩小三、依赖倒置原则1.定义:a.高层模块不应该依赖底层模块,两则都应该依赖其抽象b.抽象不应该依赖细节i.什么是抽象:抽象就是指接口或抽象类,两者都是不能直接被实例化的ii.什么是细节:细节就是实现类,实现接口或继承抽象类而产生的类就是细节,特点就是可以直接实例化,也就是new产生一个对象c.细节应该依赖抽象2.作用:依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性3.依赖的三种写法a.构造函数传递依赖对象b.Setter方法传递依赖对象c.接口声明传递依赖对象四、接口隔离原则1.定义:a.客户端不应该依赖它不需要的接口。
简述面向对象设计的原则。
简述面向对象设计的原则。
面向对象设计的原则以抽象的概念建立起软件系统,使用继承、封装、多态等特性来实现可重用的设计。
它可以让软件更易于维护和扩展,也能提供更容易理解和食用的软件。
面向对象设计也提高了软件的可读性,加快了软件开发的进程,为现有软件提供了可依赖的结构。
面向对象设计有六种原则,它们是:单一职责原则(SRP),开放封闭原则(OCP),里氏代换原则(LSP),接口隔离原则(ISP),依赖反转原则(DIP)以及合成复用原则(CRP)。
第一、单一职责原则(SRP),即一个类应该只完成一个功能。
它可以帮助我们实现模块的划分以及职责的分配,提高模块可替换性和可扩展性。
一个类只做一种事情,让代码可读性更强,维护和扩展更容易。
第二、开放封闭原则(OCP),即一个软件实体(类,模块,函数等)应该可以扩展,但是不可修改。
这样可以降低程序的维护成本,以及增加软件的可扩展性。
第三、里氏代换原则(LSP),它要求子类必须能够替换其父类,如果父类可以接受所有类型的对象,那么子类也必须遵守这个原则。
LSP可以帮助我们编写出可维护和扩展的程序。
第四、接口隔离原则(ISP),它要求一个接口应该只有一个职责,每个接口应该尽量被保持小而聚焦。
Alisp引入了一种结构,将大的接口拆分为多个小接口,这样可以减少类的耦合,降低系统的复杂度,提高可维护性和可扩展性。
第五、依赖反转原则(DIP),最重要的原则之一,它强调高层模块不应该依赖低层模块,二者都应该依赖于抽象,同时也要鼓励以抽象为基础实现解耦,依赖反转从根本上决定了软件的可维护性,使用它可以使程序更具有弹性,可以更好地处理变化。
第六、合成复用原则,它要求对象组合,而非仅仅是继承。
这样的设计可以提高代码的复用性,并使得代码之间的耦合降低,这样可以把高层模块与低层模块分离,构成可维护和可拓展的软件体系结构。
面向对象设计的原则是软件设计的基本准则,它可以为软件开发建立一个结构,提高软件的可维护性以及可扩展性。
面向对象设计的原则和技巧
面向对象设计的原则和技巧在计算机科学领域中,面向对象设计(Object-Oriented Design)被广泛使用。
它是一种思考问题的方式,可以将复杂的问题分解成简单的对象,然后通过这些对象与其他对象进行交互和协作,从而实现问题的解决。
在面向对象设计过程中,有一些重要的原则和技巧,可以帮助我们设计出优秀的面向对象系统,下面我们来了解一下。
一、单一职责原则(Single Responsibility Principle)单一职责原则是指一个类或者一个函数应该只有一个职责,也就是说,一个类或者一个函数负责的功能应该尽可能单一,这样可以提高代码的可读性和可维护性。
如果一个类或者一个函数过于复杂,负责的职责太多,那么它就变得难以理解和修改。
因此,在设计类或者函数时,我们应该遵循单一职责原则,将它们拆分成更小的单元,每个单元只负责一个职责。
二、开放封闭原则(Open-Closed Principle)开放封闭原则是指一个模块或者一个类应该对扩展开放,对修改关闭。
也就是说,我们应该通过扩展现有的代码来实现新的功能,而不是直接修改现有的代码。
这样可以提高代码的稳定性和可维护性,避免因为修改现有代码而引入新的问题。
实现开放封闭原则的一个常用的方法是使用接口和抽象类。
三、里氏替换原则(Liskov Substitution Principle)里氏替换原则是指任何基类可以出现的地方,子类一定可以替换。
也就是说,一个子类应该完全继承和实现父类的方法和属性,而不应该修改父类的属性和方法。
这样可以确保子类可以替换父类,而不会对代码造成影响。
如果我们在子类中修改了父类的行为,那么就会打破里氏替换原则,导致代码出现问题。
四、依赖倒置原则(Dependency Inversion Principle)依赖倒置原则是指高层模块不应该依赖低层模块,它们应该依赖于抽象接口。
也就是说,我们应该通过接口来协调不同的模块之间的依赖关系,而不是通过直接依赖具体的实现类。
面向对象设计六大原则
软件的可维护性与可复用性 “开-闭”原则(OCP) 里氏代换原则(LSP) 依赖倒转原则(DIP) 接口隔离原则(ISP) 合成/聚合复用原则(CARP) 迪米特法则(LoD) 1、面向对象设计的复用 在面向对象的设计里面,可维护性复用是以设计原则为基础的 系统的可扩展性是由“开-闭”原则,里氏代换原则,依赖倒转原 则和合成/聚合复用原则保证的。 系统的灵活性是由“开-闭”原则,迪米特法则,接口隔离原则所 保证的。 系统的可插入性是由“开-闭”原则,里氏代换原则,合成/聚合复 用原则以及依赖倒转原则所保证的。 2、开闭原则(OCP --- Open-closed principle) (1)定义:一个软件实体应该对扩展开放,对修改关闭 怎样做到“开-闭”原则 抽象化是关键。 在像 Java 语言这样的面向对象的编程语言里面,可以给系统定义 出一个一劳永逸, 不再修改的抽象设计,此设计允许有无穷无尽的 行为在实现层被实现。 对可变性的封装原则 “开-闭”原则如果从另外一个角度讲述,就是所谓的“对可变性 的封装原则” 。 “对可变性的封装原则”讲的是找到一个系统的可变因素,将之封 装起来。 “对可变性的封装原则”意味着两点: • 一个可变性不应当散落在代码的很多角落里, 而应当被封装 到一个对象里面。 • 一种可变性不应当与另一种可变性混合在一起 3、里氏代换原则(LSP --- The Liskov Substtion Principle):父类出现的地方都可以 用子类来替代 4、依赖倒转原则(DIP --- The Dependency Inversion Principle ) :针对接口编程, 而不要针对实现编程 依赖倒转原则的定义 依赖倒转原则要求客户端依赖于抽象耦合。 依赖倒转原则的表述是:抽象不应当依赖于细节:细节应当依赖于 抽象。另一种表述是:要针对接口编程,不要针对实现编程。 依赖倒转原则的实现 以抽象方式耦合是依赖倒转原则的关键。
学习要点面向对象设计原则
学习要点面向对象设计原则学习要点:面向对象设计原则一、介绍面向对象设计原则是软件工程中的重要概念,它指导我们如何设计高质量、可维护、可扩展的软件系统。
本文将介绍几个常用的面向对象设计原则,包括单一职责原则、开放封闭原则、里氏替换原则、依赖倒置原则和接口隔离原则。
二、单一职责原则单一职责原则指的是一个类只应该有一个责任。
一个类承担的责任越多,其职责变得越复杂,不易维护和修改。
遵循单一职责原则可以让类的职责尽量清晰明确,提高代码的可读性和可维护性。
三、开放封闭原则开放封闭原则是指软件实体应该对扩展开放,对修改封闭。
也就是说,当需要修改一个类的行为时,应该通过扩展而不是修改原有的代码。
通过使用抽象、接口和多态等技术,可以实现代码的可扩展性,降低了代码的耦合性。
四、里氏替换原则里氏替换原则是指在一个软件系统中,任何一个父类可以被其子类所替代,而不会影响系统的正确性。
也就是说,子类对象应该能够替代父类对象,且原有的程序逻辑不会发生错误或异常。
遵循里氏替换原则可以提高代码的可复用性和可扩展性。
五、依赖倒置原则依赖倒置原则是指高层模块不应该依赖低层模块,二者应该依赖于抽象。
换言之,应该面向接口编程,而不是面向实现编程。
通过依赖倒置原则可以降低模块间的耦合度,提高系统的可维护性和可扩展性。
六、接口隔离原则接口隔离原则是指客户端不应该依赖于它不需要的接口。
一个类应该只依赖于它需要的接口,而不应该依赖于整个接口集合。
接口隔离原则可以提高系统的内聚性,减少对外部接口的依赖,降低系统耦合度。
七、总结面向对象设计原则是提高软件质量和可维护性的重要手段。
单一职责原则、开放封闭原则、里氏替换原则、依赖倒置原则和接口隔离原则都是设计高质量软件的指导原则。
在实际开发中,我们应该尽量遵循这些原则,以提高代码的可读性、可维护性和可扩展性。
请根据你的实际需要,适当增加字数限制。
面向对象设计的6个设计原则,23个经典设计模式
面向对象设计的6个设计原则,23个经典设计模式设计原则1.单一职责原则应该有且只有一个原因引起类的变化。
2.里氏替换原则只要父类能出现的地方,其子类就应该能出现。
也就是用子类替换父类后,保证程序照样运行。
3.依赖倒置原则面向接口编程。
4.接口隔离原则接口细化,也就是接口中的方法要尽量少。
5.迪米特法则也称为最少知识原则,其定义为:一个对象应当对其他对象有最少的了解。
也就是一个类中不要有过多的其他类。
6.开闭原则一个软件实体(如类,模块,和函数)应该对扩展开放,对修改关闭。
设计模式一、创建型模式1. 抽象工厂(abstract factory)2. 生成器(builder)3. 工厂方法(factory method)4. 原型(prototype)5. 单件(singleton)二、结构型模式1. 适配器(adapter)2. 桥接(bridge)3. 组成(composite)4. 装饰(decorator)5. 外观(facade)6. 享元(flyweight)7. 代理(proxy)三、行为模式1. 职责链(chain of responsibility)2. 命令(command)3. 解释器(interpreter)4. 迭代器(iterator)5. 中介者(mediator)6. 备忘录(memento)7. 观察者(observer)8. 状态(state)9. 策略(strategy)10. 模版方法(template method)11. 访问者(visitor)这里准备了一个记住23个设计模式的不入流的口诀:有一家抽打大象的工厂(抽象工厂模式),这家工厂的工人故意抽打其生殖器(生成器模式)。
该工厂有一种方法(工厂方法模式),生产圆形(原型模式)的单件(单件模式)的适配器(适配器模式),这种适配器用来桥接(桥接模式)人类和大象的交流。
适配器的组成(组成模式)没有人知道,其外观(外观模式)装饰(装饰模式)得非常喜气,让人想起元旦节(享元模式)。
简述面向对象设计的原则
简述面向对象设计的原则面向对象设计原则是一些指导原则,用于帮助开发者设计高质量、可维护、可扩展的面向对象程序。
这些原则是从实践中总结出来的,可以用于指导设计师在开发过程中做出正确的设计决策。
下面将详细介绍五个常用的面向对象设计原则。
1. 单一职责原则(Single Responsibility Principle,SRP)单一职责原则要求一个类应该只有一个引起它变化的原因。
换句话说,一个类应该只负责一项职责。
这样做的好处是,当需求发生变化时,只需修改与之相关的类,而不影响其他类。
这样可以降低类之间的耦合度,提高代码的可维护性和可复用性。
2. 开闭原则(Open-Closed Principle,OCP)开闭原则要求软件实体(类、模块、函数等)对扩展开放,对修改关闭。
这意味着,当需求发生变化时,应该通过扩展现有的实体来满足新的需求,而不是修改现有的代码。
通过使用抽象和接口来实现可扩展性,可以避免代码的大规模修改,减少出错的可能性。
3. 里氏替换原则(Liskov Substitution Principle,LSP)里氏替换原则要求子类型必须能够替换掉它们的父类型。
也就是说,父类型定义的所有功能在子类型中都应该可用,并且一致地实现。
这样才能确保代码的正确性和可靠性。
遵循里氏替换原则可以提高代码的可扩展性和可维护性,同时降低代码的复杂度。
4. 依赖倒置原则(Dependency Inversion Principle,DIP)依赖倒置原则要求高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
换句话说,高层模块和低层模块都应该依赖于抽象类或接口,而不是具体的实现类。
这样可以降低模块之间的耦合度,提高代码的可扩展性和可重用性。
5. 接口隔离原则(Interface Segregation Principle,ISP)接口隔离原则要求一个类不应该依赖于它不需要的接口。
换句话说,一个类应该只关心它需要使用的方法,而不关心其他方法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
public Drawer drawer; void do(int item) {
switch (item){
Drawer _isOpened : boolean
case 1: if (door.isOpen())
open()
door.close();
close() isOpened()
else door.open();
Client
Server
Client
<<Interface>> Client Interface
Server
-19-
-19-
20
范例:手与门
• 如何在程序中模拟用手去开门和关门? • 行为:
– 开门(open) – 关门(close) – 判断门的状态(isOpened)
-20-
-20-
21
设计实现
break;
public class SmartTest {
case 2:
public static void main(String[] args) {
if (drawer.isOpen())
Hand myHand = new Hand();
drawer.close();
myHand.door = new Door();
• 面向对象的设计原则是构造高质量软件 的出发点
-7-
-7-
8
设计目标
• 构造出高质量软件,以保持系统稳定 • 设计目标
– 可扩展性 (Extensibility) – 灵活性 (Flexibility) – 可插入性 (Pluggability) – ……
-8-
-8-
9
设计质量:培养灵敏的嗅觉
• 糟糕的设计总是散发出臭味,让人不悦
}
-21-
-21-
22
新的需求……
需要手去开关抽屉,冰箱……? 我们只好去修改程序!
-22-
-22-
23
解决新的需求:修改设计
Hand
Door _is Opened : boolean
public class Hand { public Door door;
do(item : int )
open() close() isOpened() : boolean
2015‐04‐14
1
第06章 面向对象的设计原则
Object-Oriented Design Principles
-1-
1 OO 3
2 UML
学习路线图
5
8
4
6
OOP
:
:
DP
7
9
… Case-Study …
学习路线图
2
1…………0 …………
-2-
3
从问题开始!
• 长方形与正方形
– 假如我们有一个类:长方形(Rectangle) – 我们需要一个新的类,正方形(Square) – 问:可否直接继承长方形?
public class Rectangle {
private int width;
private int height;
public void setWidth(int w) {
width = w;
}
public int getWidth() {
return width;
}
} public void setHeight(int
• …… -12-
12 -12-
2
2015‐04‐14
13
LSP
• LSP(The Liskov Substitution Principle, Liskov替换原则)
– “若对于类型S的任一对象o1,均有类型T的 对象o2存在,使得在T定义的所有程序P中, 用o1替换o2之后,程序的行为不变,则S是T 的子类型”
setSide() getSide() getWidth() getHeight()
-17-
17 -17-
18
OCP
• OCP(The Open-Close Principle, 开放-封 闭原则)
– 软件实体(类、模块、函数等)应该是可扩 展的,但是不可修改的
• 特征:
– 对于扩展是开放的(Open for extension):
• OCP:开放-封闭原则
– The Open-Close Principle
• SRP:单一职责原则
– The Single Responsibility Principle
• ISP:接口隔离原则
– The Interface Segregation Principle
• DIP:依赖倒置原则
– The Dependency Inversion Principle
else drawer.open();
myHand.drawer = new Drawer();
break;
myHand.do(1);
}
} }
手被改了!} }
主(使用手)程序也被改了!
-23-
-23-
24
符合OCP的设计方案
<<Interface>>
Ha nd
Excutable
public interface Excutable {
-10-
-10-
11
设计质量:好的设计
• 什么是好的设计?
– 容易理解 – 容易修改和扩展 – 容易复用 – 容易实现与应用 – 简单、紧凑、经济适用
•ቤተ መጻሕፍቲ ባይዱ让人工作起来心情愉快的设计 • 设计原则是提高设计质量的基本原则
-11-
-11-
面向对象的基本设计原则
• LSP:Liskov替换原则
– The Liskov Substitution Principle
9使用父类(长方形)时,程序正常运行 9使用子类(正方形)时,程序陷入死循环 9设计出问题了?继承出问题了?
-5-
-5-
6
为什么会出现问题?
违背了面向对象的设计原则!
-6-
-6-
1
2015‐04‐14
7
面向对象的设计原则
• 面向对象的设计原则
– 是面向对象设计的基本指导思想 – 是评价面向对象设计的价值观体系 – 是设计模式的出发点和归宿
-16-
-16-
解决方案
<<Interface>> Quadrange
getWidth() getHeight()
Rectangle2 width : int height : int
getWidth() setWidth() setHeight() getHeight()
Square2 side : int
Hand do()
Door _isOpened : boolean
open() close() isOpened() : boolean
public class Door { private boolean _isOpen=false; public boolean isOpen(){ return _isOpen; } public void open(){ _isOpen = true; } public void close(){ _isOpen = false; }
height = h; } public int getHeight() {
return height; }
h)
{puebxlitcencdlasssRSecqtuaanrgele { public void setWidth(int w) super.setWidth (w); super.setHeight (w); } public void setHeight(int h)
– 僵硬性(Rigidity):刚性,难以扩展
– 脆弱性(Fragility):易碎,难以修改
– 牢固性(Immobility):无法分解成可移植 的组件
– 不必要的复杂性(Needless Repetition): Ctrl C + Ctrl V
– 晦涩性(Opacity):不透明,很难看清设计 者的真实意图
{ {
super.setWidth (h);
super.setHeight (h) ;
}
}
-4-
-4-
5
设计方案正确吗?
public static void resize(Rectangle r) { while (r.getHeight() <= r.getWidth()) { r.setHeight(r.getHeight() + 1); } System.out.println(“It’s OK.");
模块的行为可以扩展,当应用的需求改变时, 可以对模块进行扩展,以满足新的需求
– 对于更改是封闭的(Closed for modification):对模块行为扩展时,不必改 动模块的源代码或二进制代码
-18-
-18-
3
2015‐04‐14
19
OCP的关键在于抽象
• OCP的关键在于抽象
– 抽象技术:abstract class, Interface – 抽象预见了可能的所有扩展(闭) – 由抽象可以随时导出新的类(开)
没问题,因为数学上正方形就是长方形的子类!
-3-
-3-
4
开始设计:正方形
Rectangle height : int width : int getHeight() : int getWidth() : i nt setHeight(h : int) setWidth(w : int)