面向对象设计原则

合集下载

软件工程第十一章面向对象设计

软件工程第十一章面向对象设计

THANKS
感谢观看
01
抽象类是一种不能被实例化的 类,它只能被其他类继承。
02
抽象类可以包含抽象方法和具 体方法。抽象方法是没有具体 实现的方法,需要在继承抽象 类的子类中实现。
03
通过继承抽象类,子类可以继 承抽象类的属性和方法,并且 可以重写或实现抽象类中的方 法。
接口与抽象类的选择
在设计软件时,选择使用接口还是抽象类取决于具体需求和设计目标。
关系
关系描述了对象之间的交互和联系。 常见的关系包括关联、聚合和继承。
继承与多态的设计
继承
继承是一种实现代码重用的方式,子类可以继承父类的属性和方法,并可以扩展或覆盖它们。通过继承,可以建 立类之间的层次结构,使得代码更加清晰和易于维护。
多态
多态是指一个接口可以有多种实现方式,或者一个对象可以有多种形态。多态可以提高代码的灵活性和可扩展性, 使得程序更加易于维护和修改。
02
类与对象的设计
类的定义与属性
类的定义
类是对象的抽象,它描述了一组具有相同属性和行为的对象。类定义了对象的结构、行为和关系。
属性
属性是类中用于描述对象状态的变量。每个对象都有其自己的属性值,这些属性值决定了对象的状态 。
对象的行为与关系
行为
行为是类中定义的方法,用于描述对 象可以执行的操作。方法定义了对象 的行为和功能。
高层模块不应该依赖于低层模块,它们都应 该依赖于抽象。
面向对象设计的优势
提高代码可重用性
通过类和继承实现代码重用,减少重 复代码。
提高代码可维护性
面向对象设计使得代码结构更加清晰, 易于理解和维护。
提高开发效率
通过快速原型开发,快速构建软件系 统。

面向对象设计原则实验报告实验01

面向对象设计原则实验报告实验01

面向对象设计原则实验报告1.1实验目的1. 通过实例深入理解和掌握所学的面向对象设计原则。

2.熟练使用面向对象设计原则对系统进行重构。

3.熟练绘制重构后的结构图(类图)。

1.2实验内容1.在某绘图软件中提供了多种大小不同的画笔(Pen),并且可以给画笔指定不同颜色,某设计人员针对画笔的结构设计了如图1-1所示的初始类图。

通过仔细分析,设计人员发现该类图存在非常严重的问题,即如果需要增加一种新的大小或颜色的笔,就需要增加很多子类,例如增加一种绿色的笔,则对应每一种大小的笔都需要增加一支绿色笔,系统中类的个数急剧增加。

试根据依赖倒转原则和合成复用原则对该设计方案进行重构,使得增加新的大小或颜色的笔都较为方便,请绘制重构之后的结构图(类图)。

2.在某公司财务系统的初始设计方案中存在如图1-2所示的Employee类, 该类包含员工编号(ID),姓名(name),年龄(age).性别(gender)、薪水(salary)、每月工作时数( workHoursPerMonth),每月请假天数(leaveDaysPerMonth)等属性。

该公司的员工包括全职和兼职两类,其中每月工作时数用于存储兼职员工每个月工作的小时数,每月请假天数用于存储全职员工每个月请假的天数。

系统中两类员工计算工资的万法也不一样,全职员工按照工作日数计算工资﹐兼职员工按照工.作时数计算上资﹐内此在 Employee 类中提供了两个方法calculateSalaryByDays()和calculateSalaryByHours(),分别用于按照大数和时数计算工资,此外,还提供了方法displaySalary()用于显示工资。

试采用所学面向对象设计原则分析图1-2中Employee类存在的问题并对其进行重构绘制重构之后的类图。

3.在某图形界面中存在如下代码片段,组件类之间有较为复杂的相互引用关系:如果在上述系统中增加一个新的组件类,则必须修改与之交互的其他组件类的源代码,将导致多个类的源代码需要修改。

面向对象设计的三大原则,理解并能举例

面向对象设计的三大原则,理解并能举例

面向对象设计的三大原则,理解并能举例
面向对象编程设计有三大原则,分别是封装(Encapsulation)、继承(Inheritance)和多态(Polymorphism)。

1. 封装(Encapsulation):封装是将数据和相关行为(方法)
组合在一个类中,以实现隐藏内部实现细节的原则。

通过封装,可以将一组数据和对它们的操作封装在一个类中,对外部只暴露必要的接口,隐藏了实现的细节,提高了代码的安全性和可维护性。

例如,一个汽车类可以封装了颜色、品牌、速度等变量和加速、刹车等方法,对外只提供加速和刹车的接口,而隐藏了内部细节。

2. 继承(Inheritance):继承是指创建一个新类(子类)从已
有的类(父类)中继承属性和方法的过程。

子类可以通过继承父类的特性来扩展和增强功能,并且可以重用已有的代码。

例如,有一个动物类,定义了一些公共属性和方法,然后创建了狗类和猫类继承动物类,狗类和猫类就可以共享动物类的一些功能,同时可以根据需要添加自己的特定功能。

3. 多态(Polymorphism):多态是指同一类对象在不同情况下
可以表现出不同的行为。

对象多态性使用继承和接口实现,通过动态绑定和方法重写,允许不同的对象对同一个方法做出不同的响应。

例如,一个动物类中有一个叫声的方法,猫类和狗类都继承了动物类,并重写了叫声的方法,当通过调用叫声方法时,猫和狗的叫声不同,实现了多态性。

这三个原则是面向对象设计的基石,有助于实现代码的可重用性、可扩展性和灵活性。

里氏代换原则

里氏代换原则

里氏代换原则
里氏代换原则,即Liskov Substitution Principle,是面向对象设计的基本原则之一。

原则的核心思想是:子类可以扩展父类的功能,但不能改变父类原有的功能。

这意味着子类的行为必须与父类的行为保持一致。

里氏代换原则被广泛应用于面向对象软件设计,它可以帮助开发人员更好地开发可维护、可扩展、可复用的面向对象软件系统。

如果开发人员在设计系统时不遵守里氏代换原则,则可能出现以下问题:
1. 子类的行为与父类的行为不一致,将导致系统出现潜在的问题;
2. 如果子类破坏了父类的行为,则可能会使程序出现不可预料的行为,并导致系统崩溃;
3. 如果父类的行为被子类破坏,则可能会使开发人员在修改程序时产生困惑,从而增加调试和维护成本。

因此,里氏代换原则是面向对象设计的基本原则,它可以帮助开发人员设计出可维护、可扩展、可复用的面向对象软件系统。

它的实施可以帮助开发人员避免程序出现潜在的错误,从而降低调试和维护成本。

php面向对象程序设计(OOP)的61条准则

php面向对象程序设计(OOP)的61条准则
一个类用到的其他类的数目应当尽量少。
(23)尽量减少类和协作者之间传递的消息的数量。
(24)尽量减少类和协作者之间的协作量,也即:减少类和协作者之间传递的不同消息的数量。
(25)尽量减少类的扇出,也即:减少类定义的消息数和发送的消息数的乘积。
(26)如果类包含另一个类的对象,那么包含类应当给被包含的对象发送消息。也即:包含关系总是意味着使用关系。
(27)类中定义的大多数方法都应当在大多数时间里使用大多数数据成员。
(28)类包含的对象数目不应当超过开发者短期记忆的容量。这个数目常常是6。
当类包含多于6个数据成员时,可以把逻辑相关的数据成员划分为一组,然后用一个新的包含类去包含这一组成员。
(29)让系统功能在窄而深的继承体系中垂直分布。
(10)把不相关的信息放在另一个类中(也即:互不沟通的行为)。
朝着稳定的方向进行依赖.
(11)确保你为之建模的抽象概念是类,而不只是对象扮演的角色。
(12)在水平方向上尽可能统一地分布系统功能,也即:按照设计,顶层类应当统一地共享工作。
(13)在你的系统中不要创建全能类/对象。对名字包含Driver、Manager、System、Susystem的类要特别多加小心。
(41)所有的抽象类都应当是基类。
(42)所有的基类都应当是抽象类。
(43)把数据、行为和/或接口的共性尽可能地放到继承层次体系的高端。
(44)如果两个或更多个类共享公共数据(但没有公共行为),那么应当把公共数据放在一个类中,每个共享这个数据的类都包含这个类。
(45)如果两个或更多个类有共同的数据和行为(就是方法),那么这些类的每一个都应当从一个表示了这些数据和方法的公共基类继承。

跟我学面向对象设计中的五大原则——“单一职责”原则

跟我学面向对象设计中的五大原则——“单一职责”原则

不管它是不是用到了数据连接功能。 (4)改进的设计方案
我们应该把这两部分适当的分离开来,重新对上面的接口进行设计:
class SomeDBConnectionBean
杨教授大学堂,版权所有,盗版必究。
2/10 页
杨教授大学堂 精心创作的优秀程序员 职业提升必读系列资料
{ public void ConnectDB() { } public void DisConnectDB() { } //other DB Functions;
杨教授大学堂,版权所有,盗版必究。 3/10 页
杨教授大学堂 精心创作的优秀程序员 职业提升必读系列资料
们写到同一个类体中,否则代码将会很混乱。 同时,在业务处理层的设计中,我们将各个业务模块中的共同功能要求抽出放到业务
基类中,这样使的各个子类完成其特有的功能。从而分清基类的职责(完成共同的功能实 现)和各个子类的职责(完成各个具体的业务功能实现)。 (2)应用示例代码----没有遵守单一职责原则时的代码 import java.sql.*; import java.io.*; public class JavaJdbc {
this.dbConnection = dbConnection; } }
1.1.2 遵守单一职责原则的应用示例
1、单一职责原则应用示例之一 (1)问题的技术背景
在数据访问层组件的设计中,我们将其拆分为数据实体类、数据访问逻辑组件和数据 连接组件的目的,就是为了能够遵守组件类在设计时的“单一职责愿则”。从而避免将它
try { Class.forName(DBDriver); } catch(ClassNotFoundException e) { System.out.println(e); } try {

面向对象设计的基本原则和模式

面向对象设计的基本原则和模式

面向对象设计的基本原则和模式面向对象设计是一种软件开发的方法论,它将现实世界中的事物抽象成对象,然后通过对象之间的交互来完成软件系统的设计和开发。

面向对象设计的基本原则和模式是其核心,它们是设计和开发高质量、可维护、可扩展软件系统的基石。

本文将会首先介绍面向对象设计的基本原则,然后再介绍面向对象设计的基本模式。

一、面向对象设计的基本原则面向对象设计的基本原则是一些通用的、普遍适用的软件设计规则,它们有助于设计出高质量、可维护、可扩展的软件系统。

下面是面向对象设计的基本原则:1.单一责任原则(SRP)单一责任原则是面向对象设计的一个基本原则,它规定一个类应该只有一个引起它变化的原因。

换句话说,一个类应该只有一个职责。

这样可以降低类的复杂度,使得类更容易理解、维护和重用。

2.开放-封闭原则(OCP)开放-封闭原则是指一个软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。

这意味着当需要改变一个软件实体的行为时,不应该修改它的源代码,而是应该通过扩展它来实现。

3.里氏替换原则(LSP)里氏替换原则是指一个子类型(派生类)必须能够替换掉它的父类型(基类)而不影响系统的功能性和可靠性。

这意味着一个接口实现的任何地方都可以被子类型替换。

4.依赖倒置原则(DIP)依赖倒置原则是指高层模块不应该依赖于低层模块,二者都应该依赖于抽象。

具体来说就是,抽象不应该依赖于细节,而细节应该依赖于抽象。

5.接口隔离原则(ISP)接口隔离原则是指一个类不应该依赖它不需要的接口,换句话说,一个类应该尽可能多地使用它所需要的接口,而不是多余的接口。

6.迪米特原则(LoD)迪米特原则是指一个对象应该尽可能少地了解其他对象,它应该只与其直接的朋友通信。

这可以降低对象之间的耦合度,使得系统更易于维护和扩展。

以上就是面向对象设计的基本原则,它们是设计和开发高质量、可维护、可扩展软件系统的重要指导。

下面我们将介绍面向对象设计的基本模式。

面向对象设计六大原则

面向对象设计六大原则

面向对象设计六大原则面向对象设计的原则是面向对象思想的提炼,它比面向对象思想的核心要素更具可操作性,但与设计模式相比,却又更加的抽象,是设计精神要义的抽象概括。

形象地将,面向对象思想像法理的精神,设计原则则相对于基本宪法,而设计模式就好比各式各样的具体法律条文了。

面向对象设计原则有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类,从中抽象出两个接口,一个专门负责连接,另一个专门负责数据传送。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

面向对象设计原则⏹OO原则:◆封装变化之物◆针对接口编码,而不是对实现◆应用程序中的每一个类只有一个改变的理由◆类是关于行为与功能的⏹目的:设计原则形成更可维护更具灵◆使用已被证实的OO设计原则形成更可维护、更具灵活性以及更易扩展的软件Design Principles⏹OCP (The Open-Closed Principle) 开放-封闭原则SRP(The Single Responsibility Principle)单职责原则⏹SRP (The Single-Responsibility Principle) 单一职责原则⏹LSP (The Liskov Substitution Principle) Liskov替换原则⏹DIP (The Dependency-Inversion Principle) 依赖倒置原则⏹ISP (The Interface-Segregation Principle) 接口隔离原则⏹CARP (Composition/Aggregation Principle ) 合成/聚合复用原则⏹LoD(Law of Demeter) 迪米特法则Open-Closed Principle⏹开-闭原则(Open-Closed Principle)对扩展开放对修改关闭◆对扩展开放,对修改关闭◆OCP允许改变,以不需要修改现有程序代码的方式进行SRP⏹单一职责原则(SRP)就一个类而言,应该仅有一个引起它变化的原因。

◆就个类而言,应该仅有个引起它变化的原因。

Example: SRP violationinterface Modem{public void dial (String pno);ti public void dial (String pno);public void hangup();public void send (char c);public char recv();}connection management data communicationExampleSeparated modem interfaceQuestion AnswerLSP: Liskov替换原则⏹Subtypes must be substitutable for their base types. 子类型必须能够替换掉它们的基类型。

⏹If for each object o1of type S there is an object o2 oftype T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1issubstituted for o2then S is a subtype of T.[Liskov88]LSP Violation (I)struct Shape{enum ShapeType{square circle}enum ShapeType {square, circle}itsType;Shape(ShapeType t):itsType(t){ }};struct Circle: public Shape{ Circle():Shape(circle){ }; void Draw() const;void DrawShape(const Shape& s ){ if(s.itsType == Shape::square){static_cast<const Square&>(s).draw()};struct Square: public Shape{ Square():Shape(circle){ }; void Draw() const;};else if (s.itsType == Shape::circle)static_cast<const Circle&>(s).draw() }RTTI(Run-Time TypeIdentification)LSP Violation (II)class Rectangle{blipublic:void SetWidth(double w) {itsWidth=w;}void SetHeight(double h) {itsHeight=h;}…private:d bl it Widthdouble itsWidth;double itsHeight;…}IS-A RelationshipLSP Violation (II)void Square::SetWidth(double w){Rectangle::SetWidth(w);Rectangle::SetHeight(w):}void Square::SetHeight(double w){ Rectangle::SetWidth(w);Rectangle::SetHeight(w):void f (Rectangle& r){ r.SetWidth(32);}}:SquareViolated!LSP Violation (II)class Rectangle{Are Rectangle and Squareself-consistent? public:virtual void SetWidth(double w) {itsWidth=w;}virtual void SetHeight(double h) {itsHeight=h;}…private:double itsWidth;void g (Rectangle& r){r.SetWidth(5);r SetHeight(4);:SquareTdouble itsWidth;double itsHeight;…}r.SetHeight(4);assert(r.Area()==20);}Trueorfalse?Violated!启发⏹Violation 1:Degenerate functions in derivatives◆Degenerate functions in derivatives 派生类中的退化函数⏹Violation 2:◆Throwing exceptions from derivatives 从派生类中抛出异常LSP⏹One of the enablers of the OCPIt is the substitutability of subtypes that allows a⏹It is the substitutability of subtypes that allows amodule, expressed in terms of a base type, to beextensible without modification.DIP 依赖倒置原则⏹High level modules should not depend on low-levelmodules Both should depend on abstractions modules. Both should depend on abstractions. 高层模块不应该依赖于低层模块,二者都应该依赖于抽象。

⏹Abstractions should not depend on details. Details should depend on abstractions. 抽象不应该依赖于细节,细节应该依赖于抽象。

⏹Inversion: 相对于结构化方法而言Laying⏹Booch: “… all well structured OO architectures have clearlydefined layers with each layer providing some coherent set of defined layers, with each layer providing some coherent set of services through a well-defined and controlled interface.”Unfortunate!Laying⏹Inverted layers Hollywood principle: “don’t call us, we’ll call,you.”also an inversion of interface ownership: 客户拥有抽象接口,服务者则从这些抽象接口派生。

启发⏹“Depend on abstractions”should not depend on a concrete class–that all◆should not depend on a concrete class that allrelationships in a program should terminate on anabstract class or an interface.⏹According to it:◆No variable should hold a pointer or reference to aconcrete class.No class should derive from a concrete class◆No class should derive from a concrete class.◆No method should override an implementedmethod of any of its base classes.DIP⏹If its dependencies are inverted, it has an OO design Otherwise it has a procedure design⏹Otherwise, it has a procedure design.⏹LSP is the fundamental low-level mechanism behindmany of the benefits claimed for OO technology.ISP 接口隔离原则⏹Clients should not be forced to depend on methodsthat they do not usethat they do not use. 不应该强迫客户依赖于它们不用的方法。

⏹Deals with the disadvantage of “fat” interfaces –whose interfaces are not cohesive.Exampleclass Timer {common door!class Door {public:virtual void Lock() = 0;virtual void Unlock() = 0;virtual bool IsDoorOpen() = 0; }public:void Register (int timeout,TimeClient* client );}class TimerClient {public:virtual void TimeOut () = 0; }How about a timed door?Interface PollutionBut not all varietiesof Door need timing!Separate InterfacesSolution 1: adapterTimer +TimeOut()Timer Client *0..*DoorTimed DoorDoor Timer Adapter +DoorTimeOut()+TimeOut()*0..*class TimedDoor: public Door{public: virtual void DoorTimeOut(int timeoutId);}Class DoorTimerAdapter: public TimeClient {pubic:DoorTimerAdapter(TimedDoor& theDoor): itsTimedDoor(theDoor){} virtual void TimeOut(int timeoutId){itsTimedDoor.DoorTimeOut(timeoutId);}private:TimedDoor& istTimedDoor;}Separate InterfacesSolution 2: multiple inheritanceclass TimedDoor: public Door, publid TimerClient{public: virtual void TimeOut(int timeoutId);}CARP⏹别名:Composite Reuse Principle 合成复用原则)vs Aggregation(⏹Composition(合成) vs. Aggregation(聚合)◆聚合表示“拥有”关系或者整体与部分的关系◆合成是一种强得多的“拥有”关系——部分和整体的生命周期是一样的。

相关文档
最新文档