面向对象的设计原则之四大黄金法则
面向对象程序设计的设计原则及应用

面向对象程序设计的设计原则及应用一、概述面向对象程序设计是一种流行的编程范例,其核心思想是将现实世界中的事物抽象成对象,并通过类和实例对它们进行描述和操作。
在面向对象程序设计中,设计原则是非常重要的指导思想,它们可以帮助开发人员准确、高效地实现代码。
本文将介绍面向对象程序设计的五个设计原则,即单一职责原则、开放封闭原则、里氏替换原则、接口隔离原则和依赖倒置原则,并通过具体案例说明它们的应用。
二、单一职责原则单一职责原则是指一个类或者模块应该只有一个单一的职责。
也就是说,一个类或者模块不应该承担太多的功能,而应该聚焦于它所需解决的问题。
这样可以方便代码的维护和扩展。
以人事信息系统为例,我们可以将其分为员工信息管理、工资管理、考勤管理等多个模块,每个模块只负责一个单一的职责。
这样,当需要修改某一模块时,其他模块不会受到影响,代码的维护成本大大降低。
三、开放封闭原则开放封闭原则是指一个类或者模块应该对扩展开放,对修改封闭。
这意味着我们应该尽可能地通过扩展代码来实现新的功能,而不是修改已有的代码。
这样可以保证代码的稳定性和可维护性。
以图形计算器为例,我们可以通过扩展添加新的形状类型(如圆形、三角形等),而不是直接修改计算逻辑。
这样当需要添加新的形状时,我们只需要添加新的类,无需修改原有的代码。
四、里氏替换原则里氏替换原则是指子类可以替换父类在程序中出现的任何地方,并且程序的逻辑不应该受到影响。
这个原则保证了继承关系的正确性,并提高了代码的复用性。
以图形计算器为例,我们可以通过继承Shape类来实现不同形状的计算。
由于继承的存在,我们可以将所有形状的计算逻辑放在Shape类中,从而简化代码的结构。
五、接口隔离原则接口隔离原则是指客户端不应该依赖它不需要的接口。
这个原则保证了代码的灵活性和可维护性。
以人员信息管理系统为例,我们可以将所有的接口都抽象成不同的接口类。
这样,每个模块只需要依赖它所需的接口,无需依赖整体的接口类。
面向对象四大原则

面向对象四大原则
1. 单一职责原则(SRP):一个类只负责一项职责,避免类的职责过多过于复杂,容易引起类的不稳定,而且修改某些具体职责时可能会影响其它职责的功能,使得系统变得复杂和难以维护。
2. 开放封闭原则(OCP):一个软件实体应当对扩展开放,对修改关闭。
即:一个模块或者函数应当被设计成可以在不被修改的情况下被扩展。
3. 里氏替换原则(LSP):任何基类可以出现的地方,子类一定可以出现。
面向对象的继承是实现代码重用的重要手段,但是继承必须遵循一定规则,最基本的规则就是子类必须能够替换其基类。
4. 接口隔离原则(ISP):客户端不应该依赖它不需要的接口。
一个类对另一个类的依赖应该建立在最小的接口上。
任何代码依赖的都应该是它所需要的最小接口,而不是更大、更复杂的接口。
避免类之间的耦合度过高,修改一个类时,不应当影响到与它没有关系的类。
面向对象分析设计原则

一、单一职责原则(SRP)就一个类而言,应该仅有一个引起它变化的原因。
软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离。
测试驱动的开发实践常常会在设计出现臭味之前就迫使我们分离职责。
二、开闭原则(OCP)软件实体(类、模块、函数)应该是可扩展的,但是不可修改的。
也就是说:对于扩展是开放的,对于更改是封闭的。
怎样可能在不改动模块源代码的情况下去更改它的行为呢?怎样才能在无需对模块进行改动的情况下就改变它的功能呢?关键是抽象!因此在进行面向对象设计时要尽量考虑接口封装机制、抽象机制和多态技术。
该原则同样适合于非面向对象设计的方法,是软件工程设计方法的重要原则之一。
三、替换原则(LSP)子类应当可以替换父类并出现在父类能够出现的任何地方。
这个原则是Liskov于1987年提出的设计原则。
它同样可以从Bertrand Meyer 的DBC (Design by Contract〔基于契约设计〕) 的概念推出。
四、依赖倒置原则(DIP)1、高层模块不应该依赖于低层模块。
二者都应该依赖于抽象。
2、抽象不应该依赖于细节。
细节应该依赖于抽象。
在进行业务设计时,与特定业务有关的依赖关系应该尽量依赖接口和抽象类,而不是依赖于具体类。
具体类只负责相关业务的实现,修改具体类不影响与特定业务有关的依赖关系。
在结构化设计中,我们可以看到底层的模块是对高层抽象模块的实现(高层抽象模块通过调用底层模块),这说明,抽象的模块要依赖具体实现相关的模块,底层模块的具体实现发生变动时将会严重影响高层抽象的模块,显然这是结构化方法的一个"硬伤"。
面向对象方法的依赖关系刚好相反,具体实现类依赖于抽象类和接口。
五、接口分离原则(ISP)采用多个与特定客户类有关的接口比采用一个通用的涵盖多个业务方法的接口要好。
ISP原则是另外一个支持诸如COM等组件化的使能技术。
缺少ISP,组件、类的可用性和移植性将大打折扣。
面向对象的设计原则

面向对象的设计原则-类设计原则在面向对象设计中,如何通过很小的设计改变就可以应对设计需求的变化,这是令设计者极为关注的问题。
为此不少OO先驱提出了很多有关面向对象的设计原则用于指导OO的设计和开发。
下面是几条与类设计相关的设计原则。
1. 开闭原则(the Open Closed Principle OCP)一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。
因此在进行面向对象设计时要尽量考虑接口封装机制、抽象机制和多态技术。
该原则同样适合于非面向对象设计的方法,是软件工程设计方法的重要原则之一。
我们以收音机的例子为例,讲述面向对象的开闭原则。
我们收听节目时需要打开收音机电源,对准电台频率和进行音量调节。
但是对于不同的收音机,实现这三个步骤的细节往往有所不同。
比如自动收缩电台的收音机和按钮式收缩在操作细节上并不相同。
因此,我们不太可能针对每种不同类型的收音机通过一个收音机类来实现(通过重载)这些不同的操作方式。
但是我们可以定义一个收音机接口,提供开机、关机、增加频率、降低频率、增加音量、降低音量六个抽象方法。
不同的收音机继承并实现这六个抽象方法。
这样新增收音机类型不会影响其它原有的收音机类型,收音机类型扩展极为方便。
此外,已存在的收音机类型在修改其操作方法时也不会影响到其它类型的收音机。
图1是一个应用OCP生成的收音机类图的例子:图1 OCP应用(收音机)2. 替换原则(the Liskov Substitution Principle LSP)子类应当可以替换父类并出现在父类能够出现的任何地方。
这个原则是Liskov于1987年提出的设计原则。
它同样可以从Bertrand Meyer 的DBC (Design by Contract) 的概念推出。
我们以学生为例,夜校生为学生的子类,因此在任何学生可以出现的地方,夜校生均可出现。
这个例子有些牵强,一个能够反映这个原则的例子是圆和椭圆,圆是椭圆的一个特殊子类。
面向对象的设计原则-类设计原则

面向对象的设计原则-类设计原则在面向对象设计中,如何通过很小的设计改变就可以应对设计需求的变化,这是令设计者极为关注的问题。
为此不少OO先驱提出了很多有关面向对象的设计原则用于指导OO的设计和开发。
下面是几条与类设计相关的设计原则。
1. 开闭原则(the Open Closed Principle OCP)一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。
因此在进行面向对象设计时要尽量考虑接口封装机制、抽象机制和多态技术。
该原则同样适合于非面向对象设计的方法,是软件工程设计方法的重要原则之一。
我们以收音机的例子为例,讲述面向对象的开闭原则。
我们收听节目时需要打开收音机电源,对准电台频率和进行音量调节。
但是对于不同的收音机,实现这三个步骤的细节往往有所不同。
比如自动收缩电台的收音机和按钮式收缩在操作细节上并不相同。
因此,我们不太可能针对每种不同类型的收音机通过一个收音机类来实现(通过重载)这些不同的操作方式。
但是我们可以定义一个收音机接口,提供开机、关机、增加频率、降低频率、增加音量、降低音量六个抽象方法。
不同的收音机继承并实现这六个抽象方法。
这样新增收音机类型不会影响其它原有的收音机类型,收音机类型扩展极为方便。
此外,已存在的收音机类型在修改其操作方法时也不会影响到其它类型的收音机。
图1是一个应用OCP生成的收音机类图的例子:图12. 替换原则(the Liskov Substitution Principle LSP)子类应当可以替换父类并出现在父类能够出现的任何地方。
这个原则是Liskov于1987年提出的设计原则。
它同样可以从Bertrand Meyer 的DBC (Design by Contract) 的概念推出。
我们以学生为例,夜校生为学生的子类,因此在任何学生可以出现的地方,夜校生均可出现。
这个例子有些牵强,一个能够反映这个原则的例子时圆和椭圆,圆是椭圆的一个特殊子类。
因此任何出现椭圆的地方,圆均可以出现。
面向对象的四项基本原则

面向对象的四项基本原则这四项基本原则就像是面向对象编程这个大王国里的四位大管家,各管一摊,超级重要呢!1. 单一职责原则这个原则就好比是说,每个人都只干自己擅长的一件事儿,不要啥都揽着。
在面向对象里呢,就是一个类啊,它就只负责一个功能。
比如说,有个类是专门管计算长方形面积的,那就别让它再去管长方形周长的计算啦。
不然的话,这个类就变得很臃肿,就像一个人又要当厨师又要当司机又要当医生,肯定会乱套的呀。
2. 开闭原则这可是个很有趣的原则呢。
简单来说就是,对扩展开放,对修改关闭。
啥意思呢?就像是搭积木,你可以增加新的积木块(扩展功能),但是已经搭好的部分(原有的代码)就不要乱动啦。
比如说你写了个游戏,里面有各种角色,后来你想加个新的超级英雄角色,那你就直接写个新的类来表示这个超级英雄就好啦,不要去改原来那些角色类的代码。
这样可以保证之前的功能不会被破坏,而且新功能也能顺利加进去。
3. 里氏替换原则这个原则有点像角色扮演的游戏规则。
如果有个父类,然后有个子类,子类应该能够完全替代父类的位置,并且表现得很正常。
比如说,父类是动物,有个“叫”的方法,子类是狗,狗也是动物嘛。
那狗这个子类的“叫”方法就应该符合动物类的“叫”方法的逻辑。
不能说动物叫是“汪汪汪”,结果狗叫是“喵喵喵”,那就不对啦。
4. 依赖倒置原则这个原则像是一种关系的反转。
就是说高层模块不应该依赖低层模块,它们都应该依赖抽象。
比如说,有个高层模块是做蛋糕的,低层模块是提供面粉、鸡蛋这些材料的。
那做蛋糕这个模块不应该直接依赖于具体的面粉、鸡蛋的来源,而是依赖于一个抽象的“食材提供者”。
这样的话,如果换了食材的来源(比如从本地农场换成了进口供应商),做蛋糕的模块也不用改,只要这个新的供应商也符合“食材提供者”这个抽象的定义就好啦。
这四项基本原则在面向对象编程里就像指南针一样,指引着我们写出更好、更合理、更容易维护的代码呢。
面向对象七大设计原则

面向对象七大设计原则面向对象(Object-Oriented)编程是一种用于设计、编码和组织计算机程序的编程范式。
其核心是将程序中的数据和行为封装到类中,使得程序可以更易于扩展和维护。
在面向对象编程中,遵循七大设计原则是非常重要的,下面分别进行介绍:1、单一职责原则(SRP)单一职责原则强调一个类只应该有一个单一的责任。
这样可以使类更加简单,易于维护和扩展。
如果一个类具有多个职责,那么一旦其中一个职责发生变化,就可能会影响到其他职责。
2、开放封闭原则(OCP)开放封闭原则强调软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
也就是说,当需要添加新功能时,应该通过扩展现有的代码来实现,而不是直接修改原有代码。
这样可以减少对原有代码的影响,并且可以使程序更加稳定和可维护。
3、里氏替换原则(LSP)里氏替换原则指的是,子类应该能够替换掉父类并且不会影响原有的程序逻辑。
也就是说,任何一个基类可以在不影响程序正确性的情况下被其子类所替代。
4、依赖倒置原则(DIP)依赖倒置原则强调抽象不应该依赖于具体实现,具体实现应该依赖于抽象。
也就是说,高层模块(如应用程序)不应该依赖于底层模块(如数据库、文件系统等),而是应该依赖于抽象(如接口、抽象类等)。
5、接口隔离原则(ISP)接口隔离原则指的是,客户端不应该依赖于它不需要的接口。
也就是说,一个类不应该被强迫实现那些它不需要的接口。
这样可以降低类之间的耦合度,并且可以使接口更加清晰和易于维护。
6、迪米特法则(LKP)迪米特法则也叫作最少知识原则(LKP),它强调一个对象应该对其他对象有最少的了解。
也就是说,一个对象不应该直接与其他对象交互,它应该通过中介者来实现。
这样可以减少类之间的耦合度,使得程序更加稳定和易于维护。
7、合成复用原则(CRP)合成复用原则强调在软件设计中应尽量使用合成/聚合而不是继承来实现代码复用。
也就是说,应该通过组合多个简单的对象来构建复杂的对象,而不是通过继承来扩展已有的代码。
面向对象系统设计六大设计原则

面向对象系统设计六大设计原则一.单一职责原则,应该有且仅有一个原因引起类的变更。
单一职责原则的优点:类的复杂性降低:实现什么职责都有清晰明确的定义;可读性提高:复杂性降低,可读性就会提高;可维护性提高变更引起的风险降低:变更是必不可少的,接口的单一职责做好的话,一个接口修改只对相应的类有影响,与其他接口无影响,这对项目有非常大的帮助。
二.里氏替换原则,通俗讲,只要父类出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或异常,使用者可能根本就不需要知道是父类还是子类。
但是反过来就不行了,有子类出现的地方,父类未必就能适应。
里氏替换原则的目的:增强程序的健壮性:版本升级时也可以保持非常好的兼容性即使增加子类,原有的子类也可以继续运行在实际项目中,每个子类对应不同的业务含义,使用父类作为参数,传递不同的子类完成不同的业务逻辑,非常完美。
三.依赖倒置原则,依赖倒置原则包含三层含义:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。
四.接口隔离原则,接口隔离原则定义:客户端不应该依赖它不需要的接口;类间的依赖关系应该建立在最小的接口上。
接口隔离原则包含以下4层含义:接口要尽量小:“小”是由限度的,首先就是不能违反单一职责原则。
接口要高内聚:要求在接口中尽量少公布public方法,接口是对外的承诺,承诺越少对系统的开发越有利,变更的风险也就越少,同时也有利于降低成本。
定制服务:定制服务就是单独为一个个体提供优良的服务。
接口设计是有限度地五.迪米特法则,迪米特法则(Law of Demeter, LoD)也称为最少知识原则,一个对象应该对其他对象有最少的了解。
一个类应该对自己需要耦合或调用的类知道得最少,被耦合或调用的类的内部如何复杂都和我没有关系,那是你的事情,我就知道你提供的这么多public方法,我就调用这么多,其他的我一概不关心。
六.开闭原则,一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一些面向对象的设计法则Bob T arr 著outmyth 译法则1:优先使用(对象)组合,而非(类)继承[ Favor Composition Over Inheritance ]组合⏹(对象)组合是一种通过创建一个组合了其它对象的对象,从而获得新功能的复用方法。
⏹将功能委托给所组合的一个对象,从而获得新功能。
⏹有些时候也称之为“聚合”(aggregation)或“包容”(containment),尽管有些作者对这些术语赋予了专门的含义⏹例如:☞聚合:一个对象拥有另一个对象或对另一个对象负责(即一个对象包含另一个对象或是另一个对象的一部分),并且聚合对象和其所有者具有相同的生命周期。
(译者注:即所谓的“同生共死”关系,可参见GOF的Design Patterns: Elements of ReusableObject-Oriented Software的引言部分。
)☞包容:一种特殊类型的组合,对于其它对象而言,容器中的被包含对象是不可见的,其它对象仅能通过容器对象来访问被包含对象。
(Coad)⏹包含可以通过以下两种方式实现:☞根据引用(By reference)☞根据值(By value)⏹C++允许根据值或引用来实现包含。
⏹但是在Java中,一切皆为对象的引用!组合的优点和缺点⏹优点:☞容器类仅能通过被包含对象的接口来对其进行访问。
☞“黑盒”复用,因为被包含对象的内部细节对外是不可见。
☞对装性好。
☞实现上的相互依赖性比较小。
(译者注:被包含对象与容器对象之间的依赖关系比较少)☞每一个类只专注于一项任务。
☞通过获取指向其它的具有相同类型的对象引用,可以在运行期间动态地定义(对象的)组合。
⏹缺点:☞从而导致系统中的对象过多。
☞为了能将多个不同的对象作为组合块(composition block)来使用,必须仔细地对接口进行定义。
继承⏹(类)继承是一种通过扩展一个已有对象的实现,从而获得新功能的复用方法。
⏹泛化类(超类)可以显式地捕获那些公共的属性和方法。
⏹特殊类(子类)则通过附加属性和方法来进行实现的扩展。
继承的优点和缺点⏹优点:☞容易进行新的实现,因为其大多数可继承而来。
☞易于修改或扩展那些被复用的实现。
⏹缺点:☞破坏了封装性,因为这会将父类的实现细节暴露给子类。
☞“白盒”复用,因为父类的内部细节对于子类而言通常是可见的。
☞当父类的实现更改时,子类也不得不会随之更改。
☞从父类继承来的实现将不能在运行期间进行改变。
Coad规则仅当下列的所有标准被满足时,方可使用继承:⏹子类表达了“是一个…的特殊类型”,而非“是一个由…所扮演的角色”。
⏹子类的一个实例永远不需要转化(transmute)为其它类的一个对象。
⏹子类是对其父类的职责(responsibility)进行扩展,而非重写或废除(nullify)。
⏹子类没有对那些仅作为一个工具类(utility class)的功能进行扩展。
⏹对于一个位于实际的问题域(Problem Domain)的类而言,其子类特指一种角色(role),交易(transaction)或设备(device)。
继承/组合示例1⏹“是一个…的特殊类型”,而非“是一个由…所扮演的角色”☞失败。
乘客是人所扮演的一种角色。
代理人亦然。
⏹永远不需要转化☞失败。
随着时间的发展,一个Person的子类实例可能会从Passenger转变成Agent,再到Agent Passenger。
⏹扩展,而非重写和废除☞通过。
⏹不要扩展一个工具类☞通过。
⏹在问题域内,特指一种角色,交易或设备☞失败。
Person不是一种角色,交易或设备。
继承并非适用于此处!使用组合进行挽救!继承/组合示例2⏹“是一个…的特殊类型”,而非“是一个由…所扮演的角色”☞通过。
乘客和代理人都是特殊类型的人所扮演的角色。
⏹永远不需要转化☞通过。
一个Passenger对象将保持不变;Agent对象亦然。
⏹扩展,而非重写和废除☞通过。
⏹不要扩展一个工具类☞通过。
⏹在问题域内,特指一种角色,交易或设备☞通过。
PersonRole是一种类型的角色。
继承适用于此处!继承/组合示例3⏹“是一个…的特殊类型”,而非“是一个由…所扮演的角色”☞通过。
预订和购买都是一种特殊类型的交易。
⏹永远不需要转化☞通过。
一个Reservation对象将保持不变;Purchase对象亦然。
⏹扩展,而非重写和废除☞通过。
⏹不要扩展一个工具类☞通过。
⏹在问题域内,特指一种角色,交易或设备☞通过。
是一种交易。
继承适用于此处!继承/组合示例4⏹“是一个…的特殊类型”,而非“是一个由…所扮演的角色”☞失败。
预订不是一种特殊类型的observable。
⏹永远不需要转化☞通过。
一个Reservation对象将保持不变。
⏹扩展,而非重写和废除☞通过。
⏹不要扩展一个工具类☞失败。
Observable就是一个工具类。
⏹在问题域内,特指一种角色,交易或设备☞不适用。
Observable是一个工具类,并非一个问题域的类。
继承并非适用于此处!继承/组合总结⏹组合与继承都是重要的重用方法⏹在OO开发的早期,继承被过度地使用⏹随着时间的发展,我们发现优先使用组合可以获得重用性与简单性更佳的设计⏹当然可以通过继承,以扩充(enlarge)可用的组合类集(the set of composable classes)。
⏹因此组合与继承可以一起工作⏹但是我们的基本法则是:优先使用对象组合,而非(类)继承[ Favor Composition Over Inheritance ]法则2:针对接口编程,而非(接口的)实现[ Program To An Interface, Not An Implementation ]接口⏹接口是一个对象在对其它的对象进行调用时所知道的方法集合。
⏹一个对象可以有多个接口(实际上,接口是对象所有方法的一个子集)⏹类型是对象的一个特定的接口。
⏹不同的对象可以具有相同的类型,而且一个对象可以具有多个不同的类型。
⏹一个对象仅能通过其接口才会被其它对象所了解。
⏹某种意义上,接口是以一种非常局限的方式,将“是一种…”表达为“一种支持该接口的…”。
⏹接口是实现插件化(pluggability)的关键实现继承和接口继承⏹实现继承(类继承):一个对象的实现是根据另一个对象的实现来定义的。
⏹接口继承(子类型化):描述了一个对象可在什么时候被用来替代另一个对象。
⏹C++的继承机制既指类继承,又指接口继承。
⏹C++通过继承纯虚类来实现接口继承。
⏹Java对接口继承具有单独的语言构造方式-Java接口。
⏹Java接口构造方式更加易于表达和实现那些专注于对象接口的设计。
接口的好处⏹优点:☞Client不必知道其使用对象的具体所属类。
☞一个对象可以很容易地被(实现了相同接口的)的另一个对象所替换。
☞对象间的连接不必硬绑定(hardwire)到一个具体类的对象上,因此增加了灵活性。
☞松散藕合(loosens coupling)。
☞增加了重用的可能性。
☞提高了(对象)组合的机率,因为被包含对象可以是任何实现了一个指定接口的类。
⏹缺点:☞设计的复杂性略有增加(译者注:接口表示“…像…”(LikeA)的关系,继承表示“…是…”(IsA)的关系,组合表示“…有…”(HasA)的关系。
)接口实例⏹该方法是指其它的一些类可以进行交通工具的驾驶,而不必关心其实际上是(汽车,轮船,潜艇或是其它任何实现了IManeuverabre的对象)。
法则3:开放-封闭法则(OCP)软件组成实体应该是可扩展的,但是不可修改的。
[ Software Entities Should Be Open For Extension, Yet Closed For Modification ]开放-封闭法则⏹开放-封闭法则认为我们应该试图去设计出永远也不需要改变的模块。
⏹我们可以添加新代码来扩展系统的行为。
我们不能对已有的代码进行修改。
⏹符合OCP的模块需满足两个标准:☞可扩展,即“对扩展是开放的”(Open For Extension)-模块的行为可以被扩展,以需要满足新的需求。
☞不可更改,即“对更改是封闭的”(Closed for Modification)-模块的源代码是不允许进行改动的。
⏹我们能如何去做呢?☞抽象(Abstraction)☞多态(Polymorphism)☞继承(Inheritance)☞接口(Interface)⏹一个软件系统的所有模块不可能都满足OCP,但是我们应该努力最小化这些不满足OCP的模块数量。
⏹开放-封闭法则是OO设计的真正核心。
⏹符合该法则便意味着最高等级的复用性(reusability)和可维护性(maintainability)。
OCP示例⏹考虑下面某类的方法:⏹以上函数的工作是在制订的部件数组中计算各个部件价格的总和。
⏹若Part是一个基类或接口且使用了多态,则该类可很容易地来适应新类型的部件,而不必对其进行修改。
⏹其将符合OCP⏹但是在计算总价格时,若财务部颁布主板和内存应使用额外费用,则将如何去做。
⏹下列的代码是如何来做的呢?⏹这符合OCP吗?⏹当每次财务部提出新的计价策略,我们都不得不要修改totalPrice()方法!这并非“对更改是封闭的”。
显然,策略的变更便意味着我们不得不要在一些地方修改代码的,因此我们该如何去做呢?⏹为了使用我们第一个版本的totalPrice(),我们可以将计价策略合并到Part的getPrice()方法中。
⏹这里是Part和ConcretePart类的示例:⏹但是现在每当计价策略发生改变,我们就必须修改Part的每个子类!⏹一个更好的思路是采用一个PricePolicy类,通过对其进行继承以提供不同的计价策略:⏹看起来我们所做的就是将问题推迟到另一个类中。
但是使用该解决方案,我们可通过改变Part对象,在运行期间动态地来设定计价的策略。
⏹另一个解决方案是使每个ConcretePart从数据库或属性文件中获取其当前的价格。
单选法则单选法则(the Single Choice Principle)是OCP的一个推论。
单选法则:无论在什么时候,一个软件系统必须支持一组备选项,理想情况下,在系统中只能有一个类能够知道整个的备选项集合。
法则4:Liskov替换法则(LSP)使用指向基类(超类)的引用的函数,必须能够在不知道具体派生类(子类)对象类型的情况下使用它们。
[ Function Thar Use Referennces To Base(Super) Classes Must Be Able To Use Objects Of Derived(Sub) Classes Without Knowing It ] Liskov替换法则⏹显而易见,Liskov替换法则(LSP)是根据我所熟知的“多态”而得出的。