JavaRush /Java 博客 /Random-ZH /面向对象编程(文章翻译)
Exidnus
第 38 级
Санкт-Петербург

面向对象编程(文章翻译)

已在 Random-ZH 群组中发布
译者:不幸的是,尽管我读了很多英文书,但我在英文翻译方面没有任何丰富的经验。但事实证明,阅读和翻译是两件不同的事情。另外,不幸的是,我没有丰富的编程经验(我最近刚刚用 Spring MVC 和 Hibernate 制作了一个简单的 Web 应用程序)。因此,翻译的结果比预期的要糟糕得多。我冒昧地稍微修正了文章中给出的代码示例,因为它们不符合 Java 中的命名约定。也许不值得翻译某些模式的名称(这样的翻译并不能提供太多理解),但我认为这是两害相权取其轻的做法。值得单独提及的是“high cohesion”作为“high cohesion”的翻译。我同意,这不是最好的翻译。但“强连接”是“高耦合”(另一个重要概念),“一致性”在这里不太适用。我乐于接受批评,并非常乐意接受任何形式的对本文的评论。 面向对象编程是一种编程风格,其中程序由与现实世界对象相对应的组件组成。任何真实对象都具有一些属性(可能会或可能不会随时间变化)和行为(可能会或可能不会)取决于其他)。条件)。例如,铅笔是现实世界中的对象,具有以下属性:
  • 它是红色的(不会随着时间的推移而改变)。
  • 现在长 10 厘米(如果铅笔削尖,长度可能会改变)。
它具有以下行为:
  • 如果使用得当,它会留下痕迹。
  • 迹线可能会因压力而异(取决于外部因素)。
  • 如果削尖,其长度会缩短(永久行为)。
正如本例所示,现实世界中的对象可以具有许多属性,但在编写程序时我们只考虑必要的属性。面向对象编程有其优点。例如,它可以更轻松地以预期的方式在现实世界的对象和程序之间建立连接。随着应用程序的增长以及许多对象之间的交互,这确实很有帮助。这有助于在客观世界中分配责任,使您能够专注于通过应用程序进行思考。与OOP (面向对象编程)相关的另一个重要特征是对象的分类。由于世界(真实/虚拟)充满了物体,因此很难单独控制它们。我们需要一种对这些对象进行分类的方法,以帮助我们将不同的对象及其属性(例如黑色铅笔)关联起来。如果在前面的示例中使用,它将无法区分(相同?),但它是一个不同的对象。但由于它们都是铅笔,所以它们属于同一类“铅笔”。而钢笔与铅笔非常相似,但属于不同的类别。然而,钢笔和铅笔都是“书写工具”。 面向对象编程有以下原则:
抽象
抽象被定义为与思想而不是事件交互的质量,或者换句话说,不受表征质量的影响。这使得程序员可以专注于编程什么不是如何编程。抽象可以被认为是我们提供功能的契约。使用此概念时,实现细节可能会被隐藏。例如,如果我们需要一个可以写的类,那么我们必须确保它有一个“write”方法, abstract class writer { write (); } 我们做了什么?我们设计了一个抽象的高级类,换句话说,它知道我们需要什么功能,但如何实现它超出了该类的范围。这提供了许多好处:
  • 我们向外部实体披露最少的必要信息,这使我们能够专注于通过计划进行思考(这可以实现集中思考),避免混乱并避免做出无意的承诺。
  • 我们为未来的改进留出了空间,如果透露实施细节,这些改进将是不可能的。
遗产
“继承”在普通英语中的意思是“获得并传承”。这个词在我们的文化中已经存在很长时间了。祖先们通过辛勤劳动获得了土地并将其传给子孙,甚至大自然也青睐继承。所有身体特征,例如身高、皮肤/眼睛/头发颜色等。取决于我们从父母那里继承的基因。继承可以防止重新发明轮子并加快进步。在 OOP 中也是如此。我们创建一个具有一些基本属性/行为的父类。从该父级继承的所有类都将包含与其父级相同的属性/行为。但是,继承的类可能会获得更多属性/行为或更改行为的实现。 class WritingInstrument { colour; write() { } } class Pen (child of parent) { inkcolour; } 在上面的示例中,父类(WritingInstrument)具有“颜色”属性和“写入”行为。当子类(句柄)被声明时,“颜色”属性和“写入”行为不需要再次声明。由于继承,它们出现在“handle”类中。但是,后代类可以声明自己的附加属性/行为。我们如何在实践中使用它?我们开发者很懒。我们不想一遍又一遍地打印一些东西。由于以下考虑,不鼓励存在相同代码的多个副本:
  • 代码副本越少,就越容易维护。
  • 如果代码的副本不多,那么一处的更改就会变得随处可见。
  • 代码越少,错误就越少。
  • 如果一种代码在很多地方使用,那么就实现了泛化。
  • 我们专注于编写代码。
  • 我们专注于测试。
Java 中的继承是通过关键字“extends”和“implements”来实现的。 class WritingInstrument { } class Pen extends WritingInstrument { }
多态性
“多态性”一词来自两个词: “Poly”,即 “许多”/“多个” “变形”,即 “形式” 从字面上看,“多态性”一词是指对象根据条件以不同方式表现的能力。在编程中,多态性可以在几个地方实现:
  • 课程
  • 方法
  • 运营商
上述所有内容的行为可能会有所不同,具体取决于使用它们的条件(也许是上下文)。这很有用,因为客户端(使用库的程序员)不需要了解很多细节,并且通过从上下文中选择必要的信息来实现所需的功能。 Class WritingObject { wrire() { // пишем, используя стандартные (по дефолту) цвета } } class Pencil extends WritingObject { write() { // пишем, используя серый цвет, написанный текст можно стереть } } class Pen extends WritingObject { write() { // пишем, используя голубой цвет, написанный текст нельзя стереть } } class Main { main() { WritingObject wr = new WritingObject(); wr.write(); // первый вызов WritingObject wr = new Pen(); wr.write(); // второй вызов WritingObject wr2 = new Pencil(); wr2.write(); // третий вызов } } 上面的示例在writingObject中有一个默认实现,它由后代类pen和pen扩展/覆盖。在 Main 类中 write() 方法被调用了 3 次。每次调用不同的实现时,都会根据调用该方法的对象来调用。在本例中,write() 方法具有多种类型的行为,因为它是多态的。
封装
封装被定义为将相关数据/功能收集在一个单元中。这有助于促进数据访问/修改。例如,如果我们需要打印给定用户拥有的所有属性,我们有以下选择: 我们 printUserProperties(userName, userId, firstname, lastname, email, phone, … … ….) 创建了一种方法,该方法获取所有属性并依次打印它们。随着列表中元素数量的增加,将不再可能识别正确的字段,并且添加/删除一个字段将更改方法签名。因此,我们需要替换该方法的所有用户,即使他们不需要最近添加的字段。为了使代码更具可读性并方便以后的修改,我们将属性封装在类中,并将其变成一个集体对象。 class User { userName userId firstname lastname email phone .. .. .. } printUserProperties(user) {} 对象是变量和关联方法的软件包。您可以使用程序对象来表示现实世界的对象。您可以想象动画程序中的真实狗,或者将真实的自行车想象为健身车内的软件对象。在 OOP 中,类是一个可扩展模板(程序代码模板),用于创建对象、为它们提供初始状态(变量)和实现行为(函数、方法)。SOLID 是 Michael Feather 为 2000 年代初 Robert C. Martin 提出的“前五项原则”创造的缩写。这些原则的目标是,当一起实施时,增加程序员创建易于维护和扩展的系统的可能性。SOLID 原则是程序开发中的指南,需要通过重构来删除“腐烂”的代码,从而使代码变得易于阅读和扩展。这是敏捷和自适应编程策略的一部分。
单一责任原则
在 OOP 中,单一职责原则规定每个类应该负责程序提供的一部分功能,并且该职责应该完全由该类封装。它的所有功能都应该与这个职责密切相关。
开闭原理
在 OOP 中,开放/封闭原则指出“软件实体(类、模块、方法等)应该对扩展开放,但对更改封闭。” 换句话说,实体必须允许在不更改源代码的情况下扩展其行为。
里氏替换原则
可替代性是 OOP 中的一个原则。它指出,如果计算机程序中的 S 是 T 的子类型,那么 T 类型的对象必须可以被 S 类型的对象替换(即 S 类型的对象可以被 T 类型的对象替换)而不改变任何所需的属性程序(准确性、任务完成情况等)。
接口隔离原则
接口分离的原则规定,客户端程序员不应被迫依赖其不使用的方法。根据这个原则,有必要将大的接口分成更小、更具体的接口,以便客户端程序员只知道他感兴趣的方法。接口解耦原则的目的是让系统保持解耦,这样会更容易重构、更改和重新部署。
依赖倒置原则
在OOP中,依赖倒置原则是指程序模块断开的一种特定形式。遵循这一原则,将构成应用架构(策略设置)的高层模块与依赖的低层模块之间建立的标准依赖关系颠倒(反转),使得修改后的高层模块变得独立于应用程序的实现细节。低级模块。该原则规定:
  • 高层模块不应该依赖于低层模块。两种类型的模块都必须依赖于抽象。
  • 抽象不应依赖于实现细节。细节必须依赖于抽象。
该原则颠倒了人们思考面向对象设计的方式,认为高层和低层对象应该依赖于相同的抽象。

掌握原则

通用职责分配软件模式 (GRASP) 提供了在面向对象设计中将职责分配给类和对象的指南。
控制器
控制器模式将与系统事件交互的责任分配给代表整个系统或用例场景的非 GUI 类。控制器:
  • 这是一个不直接与用户交互的对象,负责接收和响应系统事件。
  • 必须用于处理一个(或多个相关)用例的所有系统事件。
  • 它是 GUI 背后控制系统操作的第一个对象。
  • 他不必自己做这项工作;他的任务是控制事件的流程。
创作者
创建者类的任务是创建并启动对象以供后续使用。它知道初始化参数,以及将创建什么对象。有时创建者类会主动创建对象并将其放入缓存中,并在需要时提供一个实例。
高内聚力
高内聚是一种评估模式,其目的是将对象保持在一种状态,即它们旨在执行一项明确的任务,易于控制和理解。高耦合通常用来支持低耦合。高一致性意味着给定元素的职责被明确定义(强相关且高度集中)。将程序划分为类和子系统是增加系统属性内聚性的操作示例。另一方面,松耦合是指一个元素具有太多不相关任务的情况。松散耦合的元素往往难以理解、可重用、难以维护且难以更改。
间接
Roundabout 模式通过将两个元素之间的交互责任分配给中间对象来保持两个元素之间的松散耦合(和可重用性)。一个示例是在模型-视图-控制器 (MVC) 模式中引入控制器来协调数据(模型)及其显示(视图)。
信息专家
信息专家(也称为专家或专家原则)是用于确定将责任委托给谁的原则。职责包括方法、计算字段等。当使用这一原则分配责任时,主要方法是以下操作顺序:分析责任,识别履行责任所需的信息,最后确定该信息所在的位置。使用信息专家原则会将责任分配给拥有最多执行信息的类。
低耦合
松耦合是一种评估模式,指定如何分配职责:类之间的松耦合,更改一个对另一个的影响应该最小,最大限度地提高可重用性。
多态性
根据多态性,基于类型的行为变化被分配给发生这种变化的类型。这是通过使用多态操作来实现的。
受保护的变体
受保护的更改模式通过将不稳定的焦点包装在接口中并使用多态性来创建该接口的不同实现,从而保护元素免受其他元素(对象、系统、子系统)的更改。
纯制造
纯构造涉及一个不代表问题域中的概念的类,并且专门设计用于实现松耦合、高耦合,从而实现最大的重用潜力(信息专家模式提供的解决方案无法实现这一点)。这样的类在领域驱动设计中通常称为“服务”。

批评

Potok 等人的研究表明 OOP 和过程方法之间没有显着差异。
由于缺乏严格且广泛接受的 OOP 定义,将 OOP 与其他技术(尤其是关系技术)进行批判性比较是很困难的(Christopher J. Date)
与其他语言(LISP 方言、函数式语言等)相比,OOP 语言没有独特的优势,并且强加了不必要的复杂性。(劳伦斯·克鲁布纳)
我发现面向对象编程在技术上很脆弱。它试图根据单一类型内不同的接口将世界分解为多个部分。为了处理实际问题,您需要多排序代数——跨多种类型的接口族。我发现面向对象编程在哲学上是不健康的。它指出一切都是对象。即使这是真的,也不是很有趣:说一切都是对象就等于什么也没说。(亚历山大·斯捷潘诺夫)
OOP 在大公司中的流行是由于“大量(且经常变化的)平庸程序员群体”。OOP 强加的纪律可以防止程序员造成“太多伤害”。(保罗·格雷厄姆)
面向对象编程将名词放在首位。为什么要采取如此极端的措施并把某个词性推上神坛呢?为什么一个概念优先于另一个概念?OOP 不可能突然使动词对我们的思维变得不那么重要。这是一个奇怪的倾斜的观点。(史蒂夫·叶格)
Clojure 的创建者 Rick Hickey 将对象系统描述为现实世界的极其简化的模型。他强调 OOP 无法正确建模时间,当多线程在程序中变得普遍时,这会产生巨大的问题。Eric S. Raymond 是一位 Unix 程序员和开源软件倡导者,他对 OOP 是“唯一解决方案”的说法持批评态度,并写道 OOP 鼓励多层程序,这阻碍了透明度。作为相反的方法,Raymond 举了 Unix 和 C 的例子。

链接

作者:玛格丽特·劳斯@WhatIs.com 维基百科!俄文版继承就是多态性 SOLID(面向对象设计)俄文版单一责任原则反对 OOPS 的争论俄文版什么是 OOPS(没有炒作) 翻译:Varygin D.V.
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION