如此理解面向对象编程

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

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

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

  public class PrintOS { public static void main(final String[] args) { String osName = System.getProperty("os.name") ; if (osName.equals("SunOS") || osName.equals("Linux")) { System.out.println("This is a UNIX box and therefore good.") ; } else if (osName.equals("Windows NT") || osName.equals("Windows 95")) { System.out.println("This is a Windows box and therefore bad.") ; } else { System.out.println("This is not a box.") ; } } } 然后开始用面向对象的编程方式一步一步地进化这个代码。

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

  过程化的方案

  public class PrintOS { private static String unixBox() { return "This is a UNIX box and therefore good." ; } private static String windowsBox() { return "This is a Windows box and therefore bad." ; } private static String defaultBox() { return "This is not a box." ; } private static String getTheString(final String osName) { if (osName.equals("SunOS") || osName.equals("Linux")) { return unixBox() ; } else if (osName.equals("Windows NT") ||osName.equals("Windows 95")) { return windowsBox() ; } else { return defaultBox() ; } } public static void main(final String[] args) { System.out.println(getTheString(System.getProperty("os.name"))) ; } } 然后是一个幼稚的面向对象的思路。

  幼稚的面向对象编程

  PrintOS.java

  public class PrintOS { public static void main(final String[] args) { System.out.println(OSDiscriminator.getBoxSpecifier()。getStatement()) ; } } OSDiscriminator.java

  public class OSDiscriminator // Factory Pattern { private static BoxSpecifier theBoxSpecifier = null ; public static BoxSpecifier getBoxSpecifier() { if (theBoxSpecifier == null) { String osName = System.getProperty("os.name") ; if (osName.equals("SunOS") || osName.equals("Linux")) { theBoxSpecifier = new UNIXBox() ; } else if (osName.equals("Windows NT") || osName.equals("Windows 95")) { theBoxSpecifier = new WindowsBox() ; } else { theBoxSpecifier = new DefaultBox () ; } } return theBoxSpecifier ; } } BoxSpecifier.java

  public interface BoxSpecifier { String getStatement() ; } DefaultBox.java

  public class DefaultBox implements BoxSpecifier { public String getStatement() { return "This is not a box." ; } } UNIXBox.java

  public class UNIXBox implements BoxSpecifier { public String getStatement() { return "This is a UNIX box and therefore good." ; } } WindowsBox.java

  public class WindowsBox implements BoxSpecifier { public String getStatement() { return "This is a Windows box and therefore bad." ; } } 他们觉得上面这段代码没有消除if语句,他们说这叫代码的“logic bottleneck”(逻辑瓶颈),因为如果你要增加一个操作系统的判断的话,你不但要加个类,还要改那段if-else的语句。

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

  OO大师的方案

  注意其中的Design Pattern

  PrintOS.java

  public class PrintOS { public static void main(final String[] args) { System.out.println(OSDiscriminator.getBoxSpecifier()。getStatement()) ; } } OSDiscriminator.java

  public class OSDiscriminator // Factory Pattern { private static java.util.HashMap storage = new java.util.HashMap() ; public static BoxSpecifier getBoxSpecifier() { BoxSpecifier value = (BoxSpecifier)storage.get(System.getProperty("os.name")) ; if (value == null) return DefaultBox.value ; return value ; } public static void register(final String key, final BoxSpecifier value) { storage.put(key, value) ; // Should guard against null keys, actually. } static { WindowsBox.register() ; UNIXBox.register() ; MacBox.register() ; } } BoxSpecifier.java

  public interface BoxSpecifier { String getStatement() ; } DefaultBox.java

  public class DefaultBox implements BoxSpecifier // Singleton Pattern { public static final DefaultBox value = new DefaultBox () ; private DefaultBox() { } public String getStatement() { return "This is not a box." ; } } UNIXBox.java

  public class UNIXBox implements BoxSpecifier // Singleton Pattern { public static final UNIXBox value = new UNIXBox() ; private UNIXBox() { } public String getStatement() { return "This is a UNIX box and therefore good." ; } public static final void register() { OSDiscriminator.register("SunOS", value) ; OSDiscriminator.register("Linux", value) ; } } WindowsBox.java

  public class WindowsBox implements BoxSpecifier // Singleton Pattern { public static final WindowsBox value = new WindowsBox() ; private WindowsBox() { } public String getStatement() { return "This is a Windows box and therefore bad." ; } public static final void register() { OSDiscriminator.register("Windows NT", value) ; OSDiscriminator.register("Windows 95", value) ; } } MacBox.java

  public class MacBox implements BoxSpecifier // Singleton Pattern { public static final MacBox value = new MacBox() ; private MacBox() { } public String getStatement() { return "This is a Macintosh box and therefore far superior." ; } public static final void register() { OSDiscriminator.register("Mac OS", value) ; } } 作者还非常的意地说,他加了一个“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/javaitpx/archive/2012/12/27/2835447.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/266562.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

node 版本升级_Node-RED: 自动化事件触发工具的安装与介绍

Node-RED 介绍Node-RED 是一种基于流程的编程工具由 IBM 的新兴技术服务团队原创开发Node-RED 是一种事件触发工具,和 StackStorm 类似, 可以归类为上层的自动化工具,可以用来触发与之相对应的下层自动化工具,比如 ansible,来更加…

用Python写网络爬虫pdf

下载地址:网盘下载 作为一种便捷地收集网上信息并从中抽取出可用信息的方式,网络爬虫技术变得越来越有用。使用Python这样的简单编程语言,你可以使用少量编程技能就可以爬取复杂的网站。 《用Python写网络爬虫》作为使用Python来爬取网络数据…

python处理mysql数据结构_python环境下使用mysql数据及数据结构和二叉树算法(图)...

python环境下使用mysql数据及数据结构和二叉树算法(图):1 python环境下使用mysql2使用的是 pymysql库3 开始-->创建connection-->获取cursor-->操作-->关闭cursor->关闭connection->结束45 代码框架6 import pymysql.cursors7 ###连接数据库8 con…

全国计算机等级考试题库二级C操作题100套(第14套)

第14套: 给定程序中, 函数fun的功能是用函数指针指向要调用的函数,并进行调用。 规定在__2__处使f指向函数f1,在__3__处使f指向函数f2。当调用正确时,程序输出: x15.000000, x23.000000, x1x1x1x240.000000 请在程序的下划线处填入正确的内容…

2012.12.26日学习笔记

DNS架构由根,最高层域,第二层域,子域的树状结构构成 FQDN: FULLY QUALIFIED DOMAIN NAME:WWW.SAYMS.COM可以在POWERSHELL内使用HOSTNAME查看主机名称,就是FQDNDNS服务器分为授权服务器,主服务器,辅助服务器…

大数据工作流_大数据和人工智能时代下的数字化工作流

点击上方“Bentley软件”可以订阅哦本文作者Bentley 软件公司高级技术经理赵顺耐大数据、人工智能以及与之相伴相生的物联网已经成为现代社会的运行方式,信息技术的急速发展,和数据量爆炸式增长,改变了整个社会传统的运行方式。人类与信息技术…

00x1 python分支循环

三大结构 顺序分支循环分支 分支的基本语法 if 条件表达式: 语句1语句2语句3......条件表达式就是计算结果必须为布尔值的表达式表达式后面的冒号不能少注意if后面的出现的语句,如果属于if语句块,则必须同一个锁紧等级条件表达式结果为True执…

多租户系统技术实现mysql_SaaS “可配置”和“多租户”架构的几种技术实现方式...

1、数据存储方式的选择多租户(Multi-Tenant ),即多个租户共用一个实例,租户的数据既有隔离又有共享,说到底是要解决数据存储的问题。常用的数据存储方式有三种。方案一:独立数据库一个Tenant,一个Database“的数据存储…

全国计算机等级考试题库二级C操作题100套(第15套)

更多干货推荐可以去牛客网看看,他们现在的IT题库内容很丰富,属于国内做的很好的了,而且是课程刷题面经求职讨论区分享,一站式求职学习网站,最最最重要的里面的资源全部免费!!!点击进…

iOS如何判断当前网络的运营商

2019独角兽企业重金招聘Python工程师标准>>> 在IOS上存在retain屏,经常需要在一些时刻用到高清图,有些时候也要到普通图。 在网络条件很爽的情况下,这当然不在话下。如果咱是iphone用户,又正好用的是移动卡。 如果还用…

Py函数直接传入root是啥意思_Python内部函数——用处何在?

这是一篇译文,原文地址:https://realpython.com/inner-functions-what-are-they-good-for/1. 封装内部函数可以免受函数之外的情况的影响,也就是说,对于全局命名空间而言,它们是隐藏的。下面是一个简单的例子&#xff…

高级计算机网络的基本知识

请同学们自由组队,每队2-3人,每对从以下网络基本问题中选取一个作为课题研究内容,题目自拟,写一篇研究性论文。在本学期结束之前完成,并在课堂上进行汇报。 1. 网络基础理论1.1. 容量与可扩展性 1.2. …

java 树面试题_java——二叉树面试题

12 importjava.util.ArrayList;3 importjava.util.Iterator;4 importjava.util.LinkedList;5 importjava.util.List;6 importjava.util.Queue;7 importjava.util.Stack;89 /**10 *http://blog.csdn.net/luckyxiaoqiang/article/details/7518888轻松搞定面试中的二叉树题目11 *h…

Linux 和 Windows 平台不同的 UCS-2 编码

2019独角兽企业重金招聘Python工程师标准>>> 以下是有关两个平台 UCS-2 编码的潜规则: 1, UCS-2 不等于 UTF-16。 UTF-16 每个字节使用 ASCII 字符范围编码,而 UCS-2 对每个字节的编码可以超出 ASCII 字符范围。UCS-2 和 UTF-16 对每个字符至…

vld检测不输出_输出轴热处理形变超差,找找原因

这里有最实用的技术,点击↑↑关注作者:阚亚威单位:镇江液压股份有限公司来源:《金属加工(热加工)》杂志我公司摆线液压马达输出轴材料主要为20CrMnTi,热处理工艺为渗碳直接淬火低温回火,工艺如图1所示。近期…

全国计算机等级考试题库二级C操作题100套(第16套)

第16套&#xff1a; 给定程序中&#xff0c;函数fun的功能是:求出形参ss所指字符串数组中最长字符串的长度&#xff0c;将其余字符串右边用字符*补齐,使其与最长的字符串等长。ss所指字符串数组中共有M个字符串&#xff0c;且串长<N。 请在程序的下划线处填入正确的内容并…

H5横向滚动提示

<marquee>啦啦啦&#xff0c;Hello World</marquee>转载于:https://www.cnblogs.com/Dingcps/p/9353625.html

java 独占锁_锁分类(独占锁、分拆锁、分离锁、分布式锁)

一、java内存模型提到同步、锁&#xff0c;就必须提到Java的内存模型&#xff0c;为了提高程序的执行效率&#xff0c;java也吸收了传统应用程序的多级缓存体系。在共享内存的多处理器体系架构中&#xff0c;每个处理器都拥有自己的缓存&#xff0c;并且定期地与主内存进行协调…

WinCE切换GPRS

// GPRSwitch.cpp : 定义应用程序的入口点。 //#include "stdafx.h" #include "GPRSwitch.h" #include <windows.h> #include <commctrl.h> #include "GprsXmlConfig.h" #include <connmgr.h> #include <ras.h> #includ…

url模糊匹配优化_企业必备的网站SEO优化解决方案

一、网站优化与调整倡议一个好网站不只要满足阅读者&#xff0c;还要契合搜索引擎规则、满足搜索引擎快照抓取、赋予评级、提升关键词排序等。我们站在用户角度和搜索引擎规则根底上为您提供一套完好的SEO处理计划SEO处理计划SEO倡议大纲&#xff1a;1、目的客户剖析与定位&…