65.9K
CodeProject 正在变化。 阅读更多。
Home

面向对象初学者教程

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (8投票s)

2011年4月24日

CPOL

7分钟阅读

viewsIcon

65458

面向对象初学者教程

引言

在设计师们寻找逻辑解决方案来解决问题的活动中,使用对象需要对面向对象有基本的理解。任何编写代码的人都应该了解基本的OOAD,以确保他们遵循OO的基本编程设计——面向对象。本文将通过参考实时对象(图片)来帮助开发人员理解OOAD的基础知识。

背景

在开发过程中,除非开发人员具备基本的OOAD知识来编写对象,否则输出将是过程式的,就像技术作者在编写伪代码一样。在许多项目中,这种情况时有发生。如今,非IT专业的毕业生在几周内就能开始从事真实项目开发,他们通过导师/领导获得基本编码指导。许多培训这些新手的导师/领导/负责人从不提及OO的基础知识。

让我们来讨论OOAD

我们将通过将OOAD划分为以下几个部分来讨论

  • OOS
  • OOA
  • OOD
  • 面向对象设计的基本原则缩略图
  • 面向对象设计质量度量

面向对象系统(OOS)

  • 面向对象系统由对象组成
  • 系统的行为是通过这些对象之间的协作来实现的
  • 系统的状态是其中所有对象的组合状态
  • 对象之间的协作涉及它们相互发送消息。
  • 对象之间消息发送的确切语义因所建模的系统类型而异。
    • 通过“调用方法”
    • 通过发送数据通过套接字

面向对象分析(OOA)

OOA.jpg

面向对象设计(OOD)

OOD.jpg

面向对象设计的基本原则缩略图

OOPrinciples.jpg

SOLID原则

单一职责原则

  • 一个类应该只有一个职责
  • 它承担了所有职责,
  • 做得很好,并且
  • 只做这一件事。
  • 一个类应该只有一个、且仅有一个改变的原因。
  • 每个职责都应该是一个单独的类,因为每个职责都是一个变化的轴心。
  • 如果业务规则的改变导致一个类发生改变,那么数据库模式、GUI、报表格式或其他任何系统部分的改变都不应该迫使该类发生改变。

经验法则

  • 除非一个类的描述在25个单词或以内,并且包含“和”或“或”这两个词,否则它可能实际上拥有不止一个类。
  • 当类、接口、函数等试图做太多的事情时,它们都会变得庞大而臃肿。
  • 为了避免臃肿和混乱,并确保代码真正简单(而不仅仅是容易快速修改),我们必须实践代码规范化,这似乎是一次且仅一次做最简单的可行事情的一种变体。这是职责驱动设计的一部分。
  • S.jpg

开闭原则

  • 软件实体(类、模块等)应该对扩展开放,对修改关闭。
  • 换句话说(在理想世界里……),您永远不需要更改现有代码或类:所有新功能都可以通过添加新的子类和重写方法,或通过委托重用现有代码来实现。
  • 这可以防止您在新代码中引入新的bug。如果您从不更改它,就无法破坏它。

使用抽象类、用接口实现的类

O.jpg

里氏替换原则-LSP

  • 派生类必须可以通过基类接口使用,而无需用户知道其中的区别。
  • “派生类的实例应该能够替换其超类的任何实例”
详细说明
  • 层次结构的使用是面向对象设计中的一个重要组成部分。层次结构允许使用类型族,其中更高级别的超类型捕获了所有子类型共有的行为。为了使这种方法有效,有必要清楚地理解子类型和超类型之间的关系。
  • “就任何使用超类对象的个人或程序而言,子类型的对象应该表现得和超类型对象一样。”
重要
  1. 因为如果不是这样,类层次结构就会一团糟。一团糟意味着当子类实例被作为参数传递给任何方法时,都会出现奇怪的行为。
  2. 因为如果不是这样,超类的单元测试对于子类将永远不会成功。

L.jpg

接口隔离原则

  • 许多特定于客户端的接口比一个通用的接口更好
  • 一个类对另一个类的依赖关系应该依赖于尽可能小的接口

I.jpg

依赖倒置原则

  • 细节应该依赖于抽象。抽象不应该依赖于细节。
  • “实现高级策略的模块不应该依赖于实现低级策略的模块,而应该依赖于一些定义良好的接口。它源于这样一个认识:我们必须改变这些依赖的方向,以避免僵化、脆弱和不灵活。”
  • 避免以下设计:
    • 僵化的(由于依赖性而难以更改。尤其因为依赖性是传递的。)
    • 脆弱的(更改会导致意外的bug。)
    • 固定的(由于隐式依赖于当前应用程序代码而难以重用。)

D.jpg

包内聚性原则

  • 重用/发布等效原则:重用的粒度与发布的粒度相同。只有通过跟踪系统发布的组件才能有效地重用。
  • 共同关闭原则:一起变化的类,应该在一起。
  • 共同重用原则:不一起重用的类不应该被分组在一起。

PackCohes.jpg

包耦合性原则

  • 无环依赖原则:已发布组件的依赖结构必须是定向无环图。不能有循环。
  • 稳定依赖原则:已发布类别之间的依赖关系必须遵循稳定性方向。被依赖者必须比依赖者更稳定。

    PackCouple.jpg

  • 稳定抽象原则:一个类别的稳定性越高,它就应该包含越多的抽象类。完全稳定的类别应该只包含抽象类。

    StableAbstract.jpg

最佳设计

OOD 指南 –(最佳设计的规则)

BD.jpg

在设计过程中,当我们从需求和用例到系统组件时,每个组件都必须满足该需求,而不会影响其他需求。以下是避免设计危害的步骤

继承

  • 子类在属性和方法方面与超类耦合
  • 高继承耦合是可取的
  • 每个专门化类不应继承大量不相关和不必要的类和属性

耦合类型和程度

Couple.jpg

内聚性(单个对象或软件组件内的交互)

  • 反映了对象的“单一目的性”
  • 方法内聚性
  • 一个方法应该只执行一个功能。执行多个功能是不可取的。

优化技术

OPTech.jpg

重构考虑

ReConstr.jpg

识别不良设计的规则

Bad.jpg

面向对象设计质量度量

度量(用于衡量面向对象设计的质量)

相互依赖性(子系统之间)

  • 高相互依赖性倾向于僵化、不可重用、难以维护,并导致依赖模块发生级联更改。
    • 子系统协作需要相互依赖
    • 支持设计内的通信
    • 将可重用元素与不可重用元素隔离,并
    • 阻止因维护而导致的更改传播
    • 决定设计能够抵御更改或被重用的能力
    • 对单一更改很脆弱

依赖

  • “良好的依赖”是依赖于非常稳定的东西。
  • “不良的依赖”是依赖于不稳定的东西。

稳定性

  • 最稳定的类是既独立又负责任的类。这类类没有理由改变,并且有很多理由不改变。
类范畴:重用和发布的粒度

一个类很少能单独重用。

“类范畴”——类范畴(以下简称范畴)是一组高内聚的类,它们遵循以下三条规则:

  1. 范畴内的类对任何变化力量都紧密关闭。如果一个类必须改变,范畴内的所有类都可能发生改变。
  2. 范畴内的类一起被重用。它们高度相互依赖,无法互相分离。因此,如果尝试重用范畴内的任何一个类,所有其他类也必须与它一起重用。
  3. 范畴内的类共享一些共同的功能或实现一些共同的目标。

列出了三条规则,按重要性排序。规则3可以为规则2牺牲,规则2又可以为规则1牺牲。

作者必须提供其范畴的版本,并用版本号标识它们,以便重用者能够确信他们可以获得范畴的、不会发生改变的版本。

依赖性度量

范畴的责任、独立性和稳定性可以通过计算与该范畴交互的依赖数量来度量。

  • Ca:传入耦合:外部类依赖于此范畴内类的数量
  • Ce:传出耦合:此范畴内类依赖于此范畴外类的数量
  • I:不稳定性:(Ce ÷(Ca+Ce)):此度量的范围是[0,1]
  • I=0 表示最大稳定范畴
  • I=1 表示最大不稳定性范畴
  • 高度稳定的范畴不依赖于任何东西。
  • 不稳定的范畴不应该是抽象的,它们应该是具体的。
  • 理想情况下,设计应该足够灵活,能够承受大量的变化。

结论

希望您对OOAD有了有趣且更易懂的理解。

历史

  • 2011年4月24日:初始发布
© . All rights reserved.