oop 类和对象的

实用程序类(也称为帮助程序类)是仅具有静态方法且不封装状态的“结构”。 StringUtilsIOUtilsFileUtils从Apache的共享 ; Guava的 IterablesIterators以及JDK7的Files是实用程序类的完美示例。

这种设计思想在Java世界(以及C#,Ruby等)中非常流行,因为实用程序类提供了在各处使用的通用功能。

在这里,我们要遵循DRY原则并避免重复。 因此,我们将通用代码块放入实用程序类中,并在必要时重用它们:

// This is a terrible design, don't reuse
public class NumberUtils {public static int max(int a, int b) {return a > b ? a : b;}
}

确实,这是一种非常方便的技术!

实用程序类是邪恶的

但是,在面向对象的世界中,实用程序类被认为是非常不好的实践(有些甚至可能说“可怕”)。

关于这个主题已经有很多讨论。 仅举几例: Helper Classes Evil? 尼克·马利克(Nick Malik)撰写的《 为什么西蒙·哈特(Simon Hart)的助手,单身人士和实用程序类大多不好 ,沃德元帅避免使用实用程序类 , 杀死 实用程序类 ! 由Dhaval Dalal撰写, 帮助类是 Rob Bagby的代码气味 。

此外,在StackExchange上还有一些关于实用程序类的问题: 如果“实用程序”类是邪恶的,那么我应该将通用代码放在哪里? , 实用程序类是邪恶的 。

他们所有论点的简要总结是,实用程序类不是正确的对象。 因此,它们不适合面向对象的世界。 它们从过程编程中继承而来,主要是因为大多数方法都用于那时的功能分解范例。

假设您同意这些参数并且想停止使用实用程序类,我将通过示例展示如何用适当的对象替换这些生物。

程序示例

举例来说,假设您要读取一个文本文件,将其拆分为几行,修剪每一行,然后将结果保存到另一个文件中。 这可以通过Apache Commons的FileUtils完成:

void transform(File in, File out) {Collection<String> src = FileUtils.readLines(in, "UTF-8");Collection<String> dest = new ArrayList<>(src.size());for (String line : src) {dest.add(line.trim());}FileUtils.writeLines(out, dest, "UTF-8");
}

上面的代码看起来很干净; 但是,这是过程编程,而不是面向对象的。 我们正在处理数据(字节和位),并明确指示计算机从何处检索数据,然后在何处将其放置在每一行代码中。 我们正在定义执行程序

面向对象的替代

在面向对象的范例,我们应该实例和撰写的对象,从而让他们管理数据时, 他们如何渴望。 与其调用补充静态函数,不如创建能够公开我们正在寻求的行为的对象:

public class Max implements Number {private final int a;private final int b;public Max(int x, int y) {this.a = x;this.b = y;}@Overridepublic int intValue() {return this.a > this.b ? this.a : this.b;}
}

此过程调用:

int max = NumberUtils.max(10, 5);

将成为面向对象的:

int max = new Max(10, 5).intValue();

土豆土豆 并不是的; 只是继续阅读...

对象而不是数据结构

这就是我如何设计与上述相同的文件转换功能,但是是以面向对象的方式进行的:

void transform(File in, File out) {Collection<String> src = new Trimmed(new FileLines(new UnicodeFile(in)));Collection<String> dest = new FileLines(new UnicodeFile(out));dest.addAll(src);
}

FileLines实现Collection<String>并封装所有文件读取和写入操作。 FileLines实例的行为与字符串的集合完全相同,并且隐藏了所有I / O操作。 当我们迭代它时—正在读取一个文件。 当我们addAll()时—正在写入文件。

Trimmed还实现了Collection<String>并封装了一个字符串集合( Decorator模式 )。 每次检索下一行时,都会对其进行修剪。

所有服用参与片断类是相当小: TrimmedFileLinesUnicodeFile 。 他们每个人都对自己的单一功能负责,因此完全遵循单一责任原则 。

在我们这方面,作为库的用户,这可能并不那么重要,但是对于他们的开发人员而言,这势在必行。 与在80多个方法和3000行实用程序类FileUtils使用readLines()方法相比,开发,维护和测试FileLines类要容易得多。 认真地看一下其源代码 。

面向对象的方法使延迟执行成为可能。 in需要输入数据之前,不会读取in文件。 如果我们不能开out由于一些I / O错误,第一个文件甚至不能触及。 整个节目只有在我们调用addAll()之后才开始。

除了最后一个片段外,第二个片段中的所有行都实例化并将较小的对象组合为较大的对象。 该对象组合对于CPU而言相当便宜,因为它不会引起任何数据转换。

除此之外,很明显第二个脚本在O(1)空间中运行,而第一个脚本在O(n)中运行。 这是我们对第一个脚本中的数据采用过程方法的结果。

在面向对象的世界中,没有数据。 只有对象及其行为!

相关文章

您可能还会发现以下有趣的帖子:

  • 为什么NULL是错误的?
  • 避免字符串串联
  • 对象应该是不可变的
  • Java代码中的典型错误

翻译自: https://www.javacodegeeks.com/2014/09/oop-alternative-to-utility-classes.html

oop 类和对象的

oop 类和对象的_实用程序类的OOP替代相关推荐

  1. 类和对象(一)——类对象概念及定义

    c++是基于面向对象的语言,并不是纯面向对象的语言,因为它包含c的部分,c是面向过程的语言 一.面向对象 概念:面向对象程序设计(OOP)是一种程序设计的泛型,同时也是一种程序开发的方法,它将对象作为 ...

  2. 设计如下类: 1) 建立一个Point类,表示平面中的一个点;建立一个Line类,表示平面中的一条线端, 内含两个Point类的对象;建立Triangle类,表示一个三角形

    设计如下类:     1) 建立一个Point类,表示平面中的一个点:建立一个Line类,表示平面中的一条线端,     内含两个Point类的对象:建立Triangle类,表示一个三角形,内含三个L ...

  3. 装饰器/使用类和对象封装一个工具类

    # coding:utf-8 # 装饰器是以@开头,@结构称为语法糖,装饰器的作用主要是给现有的函数增加一些额外的功能. # @classmethod # @staticmethod # @prope ...

  4. 回调函数_实用程序类与函数式编程无关

    回调函数 最近,我被指控反对函数式编程,因为我将实用程序类称为反模式. 绝对是错的! 好吧,我确实认为它们是一种糟糕的反模式,但是它们与函数式编程无关. 我相信有两个基本原因. 首先,函数式编程是声明 ...

  5. 声明式编程与函数式编程_实用程序类与函数式编程无关

    声明式编程与函数式编程 最近,我被指控反对函数式编程,因为我将实用程序类称为反模式 . 绝对是错的! 好吧,我确实认为它们是一个糟糕的反模式,但是它们与函数式编程无关. 我相信有两个基本原因. 首先, ...

  6. python类与对象作业_荐富贵和你一起复习Python(第10篇)— 面向对象程序设计

    继续复习Python,今日复习 -- 面向对象程序设计,中间会有自己的心得体会,要是有什么错误或者补充可直接评论或者私信哟. 面向对象程序设计 面向对象程序设计的思想主要针对大型软件设计提出,能够很好 ...

  7. 【C++从入门到踹门】第三篇:类和对象(中)类的默认成员函数

    目录 1.类的默认成员函数 2.构造函数 2.1 构造函数引入 2.2 构造函数概念及特点 3. 析构函数 3.1 析构函数引入 3.2 析构函数的概念 3.3 在哪些情况下会程序会执行析构函数? 3 ...

  8. java 类与对象实验报告_java类与对象实验报告

    java类与对象实验报告 西 安 邮 电 大 学(计算机学院)课内实验报告实验名称: 类与对象 专业名称: 计算机科学与技术班 级: 计科1405班 学生姓名: 高宏伟 学 号: 04141152指导 ...

  9. C++ 笔记(16)— 类和对象(类定义、类实例对象定义、访问类成员、类成员函数、类 public/private/protected 成员、类对象引用和指针)

    1. 类的定义 类定义是以关键字 class 开头,后跟类的名称.并在它后面依次包含类名,一组放在 {} 内的成员属性和成员函数,以及结尾的分号. 类声明将类本身及其属性告诉编译器.类声明本身并不能改 ...

最新文章

  1. 用JScript.net写.net应用程序
  2. Go的go-sql-driver/mysql
  3. 【题解】CF#611 H-New Year and Forgotten Tree
  4. 控制两个等交替慢慢变亮,慢慢变暗【占空比】
  5. python中列表元素类型可以不同吗_list列表等同于数组,是一种放数据的容器
  6. 若川诚邀你加源码共读群,每周一起学源码
  7. 国嵌c语言深度,国嵌C语言深度剖析班(第一期)-国嵌
  8. Drools 文档(目录)
  9. Win10下安装Intel Visual Fortran2019具体步骤及初始调试过程。
  10. “李记餐厅”微信点餐小程序的设计与实现
  11. excel如何晒出重复数据_excel怎么查找重复的内容 excel重复数据怎么筛选出来
  12. [Java,IDEA]连接oracle的关于oracle.jdbc.driver.OracleDriver一直驱动加载失败的原因
  13. ps后期调色教程,ps怎么后期调色步骤图
  14. 物联网安全与安全分析
  15. Android APP 卡顿问题分析及解决方案
  16. Android 7.0正式版工厂镜像下载
  17. 计算机主硬盘隐藏分区大小,容量不翼而飞 解密四类硬盘空间隐藏占用(组图)
  18. MySQL中计算两个年份的相差
  19. php 包含字母随机数_php随机生成数字字母组合的方法
  20. 哔哩哔哩直播姬和OBS源码对比

热门文章

  1. 欢乐纪中某A组赛【2019.1.19】
  2. 欢乐纪中某B组赛【2018.12.8】
  3. 【线段树】开关(luogu 3870)
  4. 动态规划训练8 [E - Multiplication Puzzle POJ1651]
  5. 史上最全MySQL 大表优化方案(长文)
  6. JavaFX UI控件教程(一)之简述
  7. Mybatis与Hibernate的详细对比
  8. 一道非常棘手的 Java 面试题:i++ 是线程安全的吗
  9. 学习java多线程,这必须搞懂的这几个概念
  10. 二叉树删除节点+思路分析