从Rob Pike 的 Google+上的一个推看到了一篇叫《Understanding Object Oriented Programming》的文章,我先把这篇文章简述一下,然后再说说老牌黑客Rob Pike的评论。
先看这篇教程是怎么来讲述OOP的。它先给了下面这个问题,这个问题需要输出一段关于操作系统的文字:假设Unix很不错,Windows很差。
这个把下面这段代码描述成是Hacker Solution。(这帮人觉得下面这叫黑客?我估计这帮人真是没看过C语言的代码)
public class PrintOS
{
public static void main(finalString[] 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.") ;
}
elseif(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(finalString osName)
{
if(osName.equals("SunOS") || osName.equals("Linux"))
{
returnunixBox() ;
}
elseif(osName.equals("Windows NT") ||osName.equals("Windows 95"))
{
returnwindowsBox() ;
}
else
{
returndefaultBox() ;
}
}
public static void main(finalString[] args)
{
System.out.println(getTheString(System.getProperty("os.name"))) ;
}
}
然后是一个幼稚的面向对象的思路。

幼稚的面向对象编程
PrintOS.java
publicclassPrintOS
{
publicstaticvoidmain(finalString[] args)
{
System.out.println(OSDiscriminator.getBoxSpecifier().getStatement()) ;
}
}

OSDiscriminator.java
publicclassOSDiscriminator// Factory Pattern
{
privatestaticBoxSpecifier theBoxSpecifier =null;
publicstaticBoxSpecifier getBoxSpecifier()
{
if(theBoxSpecifier ==null)
{
String osName = System.getProperty("os.name") ;
if(osName.equals("SunOS") || osName.equals("Linux"))
{
theBoxSpecifier =newUNIXBox() ;
}
elseif(osName.equals("Windows NT") || osName.equals("Windows 95"))
{
theBoxSpecifier =newWindowsBox() ;
}
else
{
theBoxSpecifier =newDefaultBox () ;
}
}
returntheBoxSpecifier ;
}
}

BoxSpecifier.java
publicinterfaceBoxSpecifier
{
String getStatement() ;
}

DefaultBox.java
publicclassDefaultBoximplementsBoxSpecifier
{
publicString getStatement()
{
return"This is not a box.";
}
}

UNIXBox.java
publicclassUNIXBoximplementsBoxSpecifier
{
publicString getStatement()
{
return"This is a UNIX box and therefore good.";
}
}

WindowsBox.java
publicclassWindowsBoximplementsBoxSpecifier
{
publicString getStatement()
{
return"This is a Windows box and therefore bad.";
}
}
他们觉得上面这段代码没有消除if语句,他们说这叫代码的“logic bottleneck”(逻辑瓶颈),因为如果你要增加一个操作系统的判断的话,你不但要加个类,还要改那段if-else的语句。
所以,他们整出一个叫Sophisticated的面向对象的解决方案。

OO大师的方案
注意其中的Design Pattern

PrintOS.java
publicclassPrintOS
{
publicstaticvoidmain(finalString[] args)
{
System.out.println(OSDiscriminator.getBoxSpecifier().getStatement()) ;
}
}

OSDiscriminator.java
publicclassOSDiscriminator// Factory Pattern
{
privatestaticjava.util.HashMap storage =newjava.util.HashMap() ;

publicstaticBoxSpecifier getBoxSpecifier()
{
BoxSpecifier value = (BoxSpecifier)storage.get(System.getProperty("os.name")) ;
if(value ==null)
returnDefaultBox.value ;
returnvalue ;
}
publicstaticvoidregister(finalString key,finalBoxSpecifier value)
{
storage.put(key, value) ;// Should guard against null keys, actually.
}
static
{
WindowsBox.register() ;
UNIXBox.register() ;
MacBox.register() ;
}
}

BoxSpecifier.java
publicinterfaceBoxSpecifier
{
String getStatement() ;
}

DefaultBox.java
publicclassDefaultBoximplementsBoxSpecifier// Singleton Pattern
{
publicstaticfinalDefaultBox value =newDefaultBox () ;
privateDefaultBox() { }
publicString getStatement()
{
return"This is not a box.";
}
}

UNIXBox.java
publicclassUNIXBoximplementsBoxSpecifier// Singleton Pattern
{
publicstaticfinalUNIXBox value =newUNIXBox() ;
privateUNIXBox() { }
public String getStatement()
{
return"This is a UNIX box and therefore good.";
}
publicstaticfinalvoidregister()
{
OSDiscriminator.register("SunOS", value) ;
OSDiscriminator.register("Linux", value) ;
}
}

WindowsBox.java
publicclassWindowsBoximplementsBoxSpecifier // Singleton Pattern
{
public static final WindowsBox value =new WindowsBox() ;
privateWindowsBox() { }
publicString getStatement()
{
return"This is a Windows box and therefore bad.";
}
publicstaticfinalvoidregister()
{
OSDiscriminator.register("Windows NT", value) ;
OSDiscriminator.register("Windows 95", value) ;
}
}

MacBox.java
publicclassMacBoximplementsBoxSpecifier// Singleton Pattern
{
publicstaticfinalMacBox value =newMacBox() ;
privateMacBox() { }
public String getStatement()
{
return"This is a Macintosh box and therefore far superior.";
}
publicstaticfinalvoidregister()
{
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的设计准则。
(全文完)

C++——OOP面向对象理解的更多相关文章

  1. c#基础-oop(面向对象理解)

    OOP-面向对象 封装,继承多态 一个桌子,用面向对象来描述一下它这个桌子项目 定义桌子类 对象:桌子 桌子的属性:名字,材质,体积 桌子的方法;放东西(方法) 现在桌子要放书,放花瓶,放文件(这里就 ...

  2. js面向对象理解

    js面向对象理解 ECMAScript 有两种开发模式:1.函数式(过程化),2.面向对象(OOP).面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.但是, ...

  3. OOP面向对象 三大特征 继承封装多态

    OOP面向对象 ----三大特征 继承封装多态 面向对象(Object Oriented,OO)是软件开发方法.面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统.交互式界面.应用结构 ...

  4. OOP面向对象三大特点

    OOP面向对象三大特点 (一)封装:将现实中一个事物的属性和功能集中定义在一个对象中.(创建对象) 创建对象的3种方式: 1.直接量方式:(创建一个单独的对象) var obj={ 属性名:值,    ...

  5. 我个人对OOP的理解

    OOP面向对象的思维:pay1:封装 A.避免使用非法数据赋值 B.保证数据的完整性 C.避免类内部发生修改的时候,导致整个程序的修改 pay2:继承 A.继承模拟了现实世界的关系,OOP中强调一切皆 ...

  6. OOP 面向对象 七大原则 (二)

    OOP 面向对象   七大原则 (二) 上一篇写到了前四个原则,这一篇继续~~ 接口隔离:客户端不应该依赖它不需要的接口:一个类对另一个类的依赖应该建立在最小的接口上. 又是一句大白话~就是说接口尽量 ...

  7. OOP 面向对象 七大原则 (一)

    OOP 面向对象   七大原则 (一) 大家众所周知,面向对象有三大特征继承封装多态的同时,还具有这七大原则,三大特征上一篇已经详细说明,这一篇就为大家详解一下七大原则: 单一职责原则,开闭原则,里氏 ...

  8. 用C实现OOP面向对象编程(1)

    如摘要所说,C语言不支持OOP(面向对象的编程).并这不意味着我们就不能对C进行面向对象的开发,只是过程要复杂许多.原来以C++的许多工作,在C语言中需我们手动去完成. 博主将与大家一起研究一下如下用 ...

  9. OOP面向对象程序设计原则

    OOP面向对象程序设计原则 开闭原则(Open Close Principle) 对扩展开放,对修改关闭 里氏代换原则(Liskov Substitution Principle) 继承必须确保超累所 ...

随机推荐

  1. mac phpstorm 破解方法

    方法参考如下链接: 来源:http://www.cnblogs.com/zyliang/p/6148960.html

  2. QOS-CBQ概述

     QOS-CBQ概述 2018年7月7日    19:56 CBQ(基于类的对列)是一种基于QOS policy实现的拥塞管理技术. CBQ中包含一个LLQ(低延迟队列),用来支撑EF(快速转发)类业 ...

  3. Apache Tomcat 整合

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 一.Apache+Tomcat整合是什么: 1.Apache默认访问端口是80,Tomcat默认访问端口是8080 ...

  4. Java基础——内部类

    一.什么是内部类 将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类 内部类所在的类在编译成功后,会出现这样两个class文件:OuterClass.class和OuterClass$In ...

  5. 长沙Uber优步司机奖励政策(3月28日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  6. [Python 3.X]python练习笔记[2]-----用python实现七段数码管显示年月日

    #SevenDigitsDrawV2.py import turtle import time def drawGap(i):#绘制数码管间隔 turtle.penup() turtle.fd(i) ...

  7. Git中从远程的分支获取最新的版本到本地——两种命令

    Git中从远程的分支获取最新的版本到本地有这样2个命令: 1. git fetch:相当于是从远程获取最新版本到本地,不会自动merge Git fetch origin master git log ...

  8. php杂记——2(数组的使用)

    1.建立升序数组:range(); $numarr1 = range(1,4); //(1,2,3,4) $numarr2 = range(1,10,2); //(1,3,5,7,9) $letter ...

  9. 签名的html

    <b><a href="http://www.feiyuanxing.com" style="color:red">未来星开发团队--狒 ...

  10. 【算法】 string 转 int

    [算法] string 转 int 遇到的一道面试题, 当时只写了个思路, 现给出具体实现 ,算是一种比较笨的实现方式 public class StringToInt { /// <summa ...