从Rob Pike 的 Google+上的一个推看到了一篇叫《Understanding Object Oriented Programming》的文章,我先把这篇文章简述一下,然后再说说老牌黑客Rob Pike的评论。

先看这篇教程是怎么来讲述OOP的。它先给了下面这个问题,这个问题需要输出一段关于操作系统的文字:假设Unix很不错,Windows很差。

这个把下面这段代码描述成是Hacker Solution。(这帮人觉得下面这叫黑客?我估计这帮人真是没看过C语言的代码)

  1. public class PrintOS
  2. {
  3. public static void main(final String[] args)
  4. {
  5. String osName = System.getProperty("os.name") ;
  6. if (osName.equals("SunOS") || osName.equals("Linux"))
  7. {
  8. System.out.println("This is a UNIX box and therefore good.") ;
  9. }
  10. else if (osName.equals("Windows NT") || osName.equals("Windows 95"))
  11. {
  12. System.out.println("This is a Windows box and therefore bad.") ;
  13. }
  14. else
  15. {
  16. System.out.println("This is not a box.") ;
  17. }
  18. }
  19. }

然后开始用面向对象的编程方式一步一步地进化这个代码。

先是以过程化的思路来重构之。

过程化的方案

  1. public class PrintOS
  2. {
  3. private static String unixBox()
  4. {
  5. return "This is a UNIX box and therefore good." ;
  6. }
  7. private static String windowsBox()
  8. {
  9. return "This is a Windows box and therefore bad." ;
  10. }
  11. private static String defaultBox()
  12. {
  13. return "This is not a box." ;
  14. }
  15. private static String getTheString(final String osName)
  16. {
  17. if (osName.equals("SunOS") || osName.equals("Linux"))
  18. {
  19. return unixBox() ;
  20. }
  21. else if (osName.equals("Windows NT") ||osName.equals("Windows 95"))
  22. {
  23. return windowsBox() ;
  24. }
  25. else
  26. {
  27. return defaultBox() ;
  28. }
  29. }
  30. public static void main(final String[] args)
  31. {
  32. System.out.println(getTheString(System.getProperty("os.name"))) ;
  33. }
  34. }

然后是一个幼稚的面向对象的思路。

幼稚的面向对象编程 

PrintOS.java

  1. public class PrintOS
  2. {
  3. public static void main(final String[] args)
  4. {
  5. System.out.println(OSDiscriminator.getBoxSpecifier().getStatement()) ;
  6. }
  7. }

OSDiscriminator.java

  1. public class OSDiscriminator // Factory Pattern
  2. {
  3. private static BoxSpecifier theBoxSpecifier = null ;
  4. public static BoxSpecifier getBoxSpecifier()
  5. {
  6. if (theBoxSpecifier == null)
  7. {
  8. String osName = System.getProperty("os.name") ;
  9. if (osName.equals("SunOS") || osName.equals("Linux"))
  10. {
  11. theBoxSpecifier = new UNIXBox() ;
  12. }
  13. else if (osName.equals("Windows NT") || osName.equals("Windows 95"))
  14. {
  15. theBoxSpecifier = new WindowsBox() ;
  16. }
  17. else
  18. {
  19. theBoxSpecifier = new DefaultBox () ;
  20. }
  21. }
  22. return theBoxSpecifier ;
  23. }
  24. }

BoxSpecifier.java

  1. public interface BoxSpecifier
  2. {
  3. String getStatement() ;
  4. }

DefaultBox.java

  1. public class DefaultBox implements BoxSpecifier
  2. {
  3. public String getStatement()
  4. {
  5. return "This is not a box." ;
  6. }
  7. }

UNIXBox.java

  1. public class UNIXBox implements BoxSpecifier
  2. {
  3. public String getStatement()
  4. {
  5. return "This is a UNIX box and therefore good." ;
  6. }
  7. }

WindowsBox.java

  1. public class WindowsBox implements BoxSpecifier
  2. {
  3. public String getStatement()
  4. {
  5. return "This is a Windows box and therefore bad." ;
  6. }
  7. }

他们觉得上面这段代码没有消除if语句,他们说这叫代码的“logic bottleneck”(逻辑瓶颈),因为如果你要增加一个操作系统的判断的话,你不但要加个类,还要改那段if-else的语句。

所以,他们整出一个叫Sophisticated的面向对象的解决方案。

OO大师的方案

注意其中的Design Pattern

PrintOS.java

  1. public class PrintOS
  2. {
  3. public static void main(final String[] args)
  4. {
  5. System.out.println(OSDiscriminator.getBoxSpecifier().getStatement()) ;
  6. }
  7. }

OSDiscriminator.java

  1. public class OSDiscriminator // Factory Pattern
  2. {
  3. private static java.util.HashMap storage = new java.util.HashMap() ;
  4. public static BoxSpecifier getBoxSpecifier()
  5. {
  6. BoxSpecifier value = (BoxSpecifier)storage.get(System.getProperty("os.name")) ;
  7. if (value == null)
  8. return DefaultBox.value ;
  9. return value ;
  10. }
  11. public static void register(final String key, final BoxSpecifier value)
  12. {
  13. storage.put(key, value) ; // Should guard against null keys, actually.
  14. }
  15. static
  16. {
  17. WindowsBox.register() ;
  18. UNIXBox.register() ;
  19. MacBox.register() ;
  20. }
  21. }

BoxSpecifier.java

  1. public interface BoxSpecifier
  2. {
  3. String getStatement() ;
  4. }

DefaultBox.java

  1. public class DefaultBox implements BoxSpecifier // Singleton Pattern
  2. {
  3. public static final DefaultBox value = new DefaultBox () ;
  4. private DefaultBox() { }
  5. public String getStatement()
  6. {
  7. return "This is not a box." ;
  8. }
  9. }

UNIXBox.java

  1. public class UNIXBox implements BoxSpecifier // Singleton Pattern
  2. {
  3. public static final UNIXBox value = new UNIXBox() ;
  4. private UNIXBox() { }
  5. public  String getStatement()
  6. {
  7. return "This is a UNIX box and therefore good." ;
  8. }
  9. public static final void register()
  10. {
  11. OSDiscriminator.register("SunOS", value) ;
  12. OSDiscriminator.register("Linux", value) ;
  13. }
  14. }

WindowsBox.java

  1. public class WindowsBox implements BoxSpecifier  // Singleton Pattern
  2. {
  3. public  static final WindowsBox value = new WindowsBox() ;
  4. private WindowsBox() { }
  5. public String getStatement()
  6. {
  7. return "This is a Windows box and therefore bad." ;
  8. }
  9. public static final void register()
  10. {
  11. OSDiscriminator.register("Windows NT", value) ;
  12. OSDiscriminator.register("Windows 95", value) ;
  13. }
  14. }

MacBox.java

  1. public class MacBox implements BoxSpecifier // Singleton Pattern
  2. {
  3. public static final MacBox value = new MacBox() ;
  4. private MacBox() { }
  5. public  String getStatement()
  6. {
  7. return "This is a Macintosh box and therefore far superior." ;
  8. }
  9. public static final void register()
  10. {
  11. OSDiscriminator.register("Mac OS", value) ;
  12. }
  13. }

作者还非常的意地说,他加了一个“Mac OS”的东西。老实说,当我看到最后这段OO大师搞出来的代码,我快要吐了。我瞬间想到了两件事:一个是以前酷壳上的《面向对象是个骗局》和 《各种流行的编程方式》中说的“设计模式驱动编程”,另一个我想到了那些被敏捷洗过脑的程序员和咨询师,也是这种德行。

于是我去看了一下第一作者Joseph Bergin的主页,这个Ph.D是果然刚刚完成了一本关于敏捷和模式的书。

Rob Pike的评论

(Rob Pike是当年在Bell lab里和Ken一起搞Unix的主儿,后来和Ken开发了UTF-8,现在还和Ken一起搞Go语言。注:不要以为Ken和Dennis是基友,其实他们才是真正的老基友!)

Rob Pike在他的Google+的这贴里评论到这篇文章——

他并不确认这篇文章是不是搞笑?但是他觉得这些个写这篇文章是很认真的。他说他要评论这篇文章是因为他们是一名Hacker,至少这个词出现在这篇文章的术语中。

他说,这个程序根本就不需要什么Object,只需要一张小小的配置表格,里面配置了对应的操作系统和你想输出的文本。这不就完了。这么简单的设计,非常容易地扩展,他们那个所谓的Hack Solution完全就是笨拙的代码。后面那些所谓的代码进化相当疯狂和愚蠢的,这个完全误导了对编程的认知。

然后,他还说,他觉得这些OO的狂热份子非常害怕数据,他们喜欢用多层的类的关系来完成一个本来只需要检索三行数据表的工作。他说他曾经听说有人在他的工作种用各种OO的东西来替换While循环。(我听说中国Thoughtworks那帮搞敏捷的人的确喜欢用Object来替换所有的if-else语句,他们甚至还喜欢把函数的行数限制在10行以内)

他还给了一个链接http://prog21.dadgum.com/156.html,你可以读一读。最后他说,OOP的本质就是——对数据和与之关联的行为进行编程。便就算是这样也不完全对,因为:

Sometimes data is just data and functions are just functions.

我的理解

我觉得,这篇文章的例子举得太差了,差得感觉就像是OO的高级黑。面向对象编程注重的是:1)数据和其行为的打包封装,2)程序的接口和实现的解耦。你那怕,举一个多个开关和多个电器的例子,不然就像STL中,一个排序算法对多个不同容器的例子,都比这个例子要好得多得多。老实说,Java SDK里太多这样的东西了。

我以前给一些公司讲一些设计模式的培训课,我一再提到,那23个经典的设计模式和OO半毛钱关系没有,只不过人家用OO来实现罢了。设计模式就三个准则:1)中意于组合而不是继承,2)依赖于接口而不是实现,3)高内聚,低耦合。你看,这完全就是Unix的设计准则。

 

转载于:https://www.cnblogs.com/BrightMoon/archive/2013/02/23/2923339.html

Java(面向对象OOP)相关推荐

  1. java基础(三):java面向对象OOP

    java面向对象OOP 基本概念 面向过程与面向对象 面向过程:关注代码实现的细节.复用性 面向对象:先把每个过程的代码实现细节整合到对象中,只要找到对象就能拥有对象身上所有的功能. 面向对象基于面向 ...

  2. java面向对象oop阶段总结

    名词解释 笔记0927 *对象数组起始位置可以初始化几个元素 // 1.功能五 判断队名是否重复2.给队起名:3.队伍建队用flag循环判断是否队伍已满: 2.功能六 遍历二维数组子元素的方法 *3. ...

  3. 什么是Java面向对象OOP

    OOP是Java的核心编程思想,整套Java的精髓就是OPP思想的实现 一.封装 定义:封装就是把对象的属性(状态)和⽅法(⾏为)结合在⼀起,并尽可能隐蔽对象的内部细节,成为⼀个不可分割的独⽴单位(即 ...

  4. Java面向对象(OOP)--面向过程 面向对象 OOP详解

    1. 面向过程 & 面向对象 语言的进化发展跟生物的进化发展其实是一回事,都是"物以类聚".相近的感光细胞聚到一起变成了我们的眼睛,相近的嗅觉细胞聚到一起变成了我们的鼻子. ...

  5. Java面向对象(OOP)入门

    一.面向对象概述 Java是面向对象思想的高级计算机编程语言. 面向对象(简称:OOP)是一种以事物为中心的编程思想,是一种程序开发的方法,它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件 ...

  6. JAVA面向对象OOP→构造方法、this、访问修饰符、static、方法重载、JVM内存分配、GC垃圾回收、包、样例代码

    构造方法 构造方法(constructor):与类名同名,没有返回值 其初始化作用:一为属性分配内存空间.二为属性赋值 构造方法不能自己调用,只能通过new实例化对象调用 隐式构造方法:对象实例化时编 ...

  7. JAVA面向对象OOP多态→抽象类abstract、接口interface实现implement、final不变修饰符、样例代码

    抽象类 抽象类-接口关系示意图 如果一个类实现接口,就要把接口中所有的抽象方法都重写. A接口继承另一个B接口时,类要重写AB两个接口的方法 如果只是实现部分接口,可以用抽象类实现. 抽象类与接口不同 ...

  8. JAVA面向对象OOP→继承extends、构造方法super、方法重写override、样例代码

    继承(extends扩展) 一个子类只有一个父类,单一继承,可以在不同包内,不同包要导入import 基类(Object)如果一个类不继承任何类,默认就自动继承Object类 子类可以对父类的属性不用 ...

  9. JAVA面向对象OOP、类、属性、方法、样例代码

    类由属性和方法组成.jdk类接近八千个 成员变量 一个类中的任何方法,都可以使用同一个属性. 属性可以被类中的所有方法访问,类中的所有方法都可以改变属性值. 为区分,类名默认首字母大写,方法名默认首字 ...

  10. Java面向对象(OOP)--内部类(匿名内部类)

    1. 匿名内部类 没有(或者不需要)命名来初始化类,就称为匿名内部类. 在这四种内部类中,以后的工作可能遇到最多的是匿名内部类,所以说匿名内部类是最常用的一种内部类. 什么是匿名对象? 如果一个对象只 ...

最新文章

  1. 使用Linux的lsblk命令列出块设备信息
  2. 【架构二】后端高可用架构演进
  3. LeetCode 1002. 查找常用字符(哈希)
  4. 数据库范式5nf_第四范式(4NF)| 数据库管理系统
  5. 乔新亮:以赢为终,三个月打造一支硬核IT团队
  6. 使用@Embed嵌入元素
  7. python测验4_Python小测试_4
  8. 深度学习开源项目学习
  9. 网页下载CAB文件总结
  10. 云服务器机型系统选择,云服务器机型选择操作系统
  11. Java 基础 10 个简单测试
  12. mybatis java 帅帅 2021年5月17日20:36:25
  13. C++:利用泰勒公式求cos x近似值
  14. python取系统日期前一天_python 获取前一天或前N天的日期
  15. 【计算机网络】【应用层-5】
  16. 创意信息联席CTO:学习财务思维,打造100位技术大咖
  17. 千兆光模块如何与交换机搭配使用?
  18. android手机截屏代码,Android手机截屏代码
  19. Edge浏览器主页被hao123劫持怎么办?
  20. 又双叒叕可以 4 折买书了!!来薅羊毛了!

热门文章

  1. Python爬取王者荣耀手游中的游戏英雄角色
  2. linux 隐藏字符 h,webpack手动配置
  3. nginx学习笔记 nginx 配置文件位置 常用命令
  4. 区块链 Hyperledger fabric 排序服务Kafka
  5. Docker教程小白实操入门(21)--如何备份、恢复数据卷
  6. matlab axes坐标轴长度,[转载]Matlab 坐标轴(axes),数据提示(data
  7. 数据结构和算法——线性结构(3)递归和斐波那契数列、汉诺塔问题
  8. html5编写商城页面,HTML5+CSS3前端入门教程---从0开始通过一个商城实例手把手教你学习PC端和移动端页面开发第2章HTML基础知识...
  9. c++获取ctrl+v内容_处理文档时,快捷键「Ctrl+E」的 8 大妙用
  10. 多人在线答题游戏 小程序 (规划设计方案)