新普京娱乐场没错的编程姿势。如此清楚面向对象编程。

多年来片独星期,我下 plantuml (贝尔实验室产品了一个顶尖级绘图工具
graphviz,
这是一个包装版)把自家之绘图项目开了一样次于到的接口及好像的可视化。使用了广大设计模式,包括:桥接、装饰器、生成器、抽象工厂。绘制了晚,图像是好抖的,接口之间的并行与参数定义清晰优雅。很完美!

由Rob Pike 的 Google+上之一个推看到了一样首被《Understanding Object
Oriented
Programming》的篇章,我先拿及时篇稿子简述一下,然后再说说老牌黑客Rob
Pike的评说。

然并卵!

优先看就首教程是怎么来讲述OOP的。它预先给了脚这个题材,这个题目亟需输出一段有关操作系统的字:假设Unix很正确,Windows很不同。

是项目于出之远在都背离了自的有感到,对于程序设计的觉得。从自家本着数据库及服务器的多年历,使用基于数据表和数据说明的抽象结构,你究竟能获无限简单易行容易用而扩大的软件结构。

以此把脚就段代码描述成是Hacker
Solution
。(这支援人觉得下面就让黑客?我估计马上帮助人算没有看罢C语言的代码)

可是,这个绘图项目确实特别复杂,涉及了重重的多态和关系。比如,在一个丰富的列表中存储种类不一之图形,这些图存储的绘图数据与系信息还不同,我索要将这些多少视做同一栽类型,然后迭代它们,选出需要之一个同时动其的系信息。所以,我尝试用学术界的设计模式来化解中的问题。

 

当型转移得甚庞大的时,我发现及设计模式屁都非是。诸如桥接、装饰器以及另,都是起家于相同栽如,假而你的父组件和子组件总是可以忽略对方的底细,而可以统一的拍卖它们。比如,面包来奶油味、抹茶味、水果味,面包又发生起码材料、高档材料,那么您可将味道和资料分为两个不等之接口,然后分别抽象,并且做这简单只接口生成更增长的面包,比如低档材料的去除茶味面包。但是,真实的编程世界面临,这样的良好状态非常少。在真正的编程世界面临,面包还想使更多的物,比如奶油味的起甜,抹茶味的无糖,有甜味的面包放在左边柜台及,没有糖的面包放在右边柜台及。看到了吧,复杂度升级了,柜台及面包来没发出糖是绑定的。这象征,如果您想像前那么抽象两独接口—味道和材料,那你现在须考虑柜台。因为低档材料的去茶味面包是绝非糖的,放在右边柜台。现在,你不得不抽象出味道跟柜台的涉。在方的接口之上再多一重叠。每当你的需要复杂一点,这种层就会见升级。比如,红糖面包和白糖面包。

01 public class PrintOS

一言以蔽之,就算设计模式避免了看似继承的爆炸,但是也避免不了抽象层级的纷繁。

02 {

为此,我以为自身还要休会见编程了。于是,我尽可能的双重考虑这些规划,并且更当网直达找寻曾经支持自的计划论调:面向数据结构编程而不是目标。如果无是以这个绘图项目,我绝对不见面铤而走险再同浅下设计模式和面向对象。

03     public static void main(final String[] args)

自己当搜到了一如既往老堆 Linus 排斥面向对象和 C++ Java
的言辞,从感觉上,这些虽是自身面临设计困难时刻的感觉。我都无数糟糕这样化解我之次第设计。

04     {

git的宏图其实很的大概,它的数据结构很稳定,并且发生抬高的文档描述。事实上,我十分之赞同应该围绕我们的数据结构来规划代码,而不是根据其它的,我觉着就为是git之所以成功之因之一。[…]
依我之观,好程序员和烂程序员之间的差距就在他们觉得是代码更着重还是数据结构更重要。

当庞大之路蒙,人们对未是上下一心开之模块并无打听,能快掌握外模块中函数的合适含义才能够增高支付效率。而C++引入的各种抽象则只要代码非常靠上下文,想明白一段代码,需要看多得几近的上下文。

面向对象语言为目标也着力,加有交互关联的章程,简直是呓语。重要的物应该是数据结构,对象自我产生何要?真正有意思的,是当不同档次的不同目标交互而且出锁规则的下。但是,即使是此时,封装什么“对象接口”也绝对大错特错,因为不再是纯粹对象的题材了。

05         String osName = System.getProperty("os.name") ;

有趣之凡,这里发生相同首另外一位长辈的要命早的契,推在 Google+ 上,来自 Unix
核心创建者之一 Rob Pike:

06         if (osName.equals("SunOS") || osName.equals("Linux"))

原文链接
A few years ago I saw this page:
http://www.csis.pace.edu/~bergin/patterns/ppoop.html

Local discussion focused on figuring out whether this was a joke or
not. For a while, we felt it had to be even though we knew it wasn’t.
Today I’m willing to admit the authors believe what is written there.
They are sincere.

But… I’d call myself a hacker, at least in their terminology, yet my
solution isn’t there. Just search a small table! No objects required.
Trivial design, easy to extend, and cleaner than anything they
present. Their “hacker solution” is clumsy and verbose. Everything
else on this page seems either crazy or willfully obtuse. The lesson
drawn at the end feels like misguided epistemology, not technological
insight.

It has become clear that OO zealots are afraid of data. They prefer
statements or constructors to initialized tables. They won’t write
table-driven tests. Why is this? What mindset makes a multilevel type
hierarchy with layered abstractions better than searching a three-line
table? I once heard someone say he felt his job was to remove all
while loops from everyone’s code, replacing them with object stuff.
Wat?

But there’s good news. The era of hierarchy-driven, keyword-heavy,
colored-ribbons-in-your-textook orthodoxy seems past its peak. More
people are talking about composition being a better design principle
than inheritance. And there are even some willing to point at the
naked emperor; see
http://prog21.dadgum.com/156.html
for example. There are others. Or perhaps it’s just that the old guard
is reasserting itself.

Object-oriented programming, whose essence is nothing more than
programming using data with associated behaviors, is a powerful idea.
It truly is. But it’s not always the best idea. And it is not well
served by the epistemology heaped upon it.

Sometimes data is just data and functions are just functions.

— Rob Pike (One of the Unix creators (Ken Thompson, Dennis M.
Ritche, and Rob Pike))

几乎年前我见到了是网页:
http://www.csis.pace.edu/~bergin/patterns/ppoop.html

自身真的不懂得就首文章到底是匪是于搞笑。读了一晃,我虽然好想说立刻不是一样首将笑的章,但是,拜托,它根本就是。让我来跟你们说出口他们于整笑啊吧。

e…以他们之说话,我应该称好吗 hacker
(黑客),不管我不关心这些。Hello! 你独自待一个多少的免可知再稍加之 table

根本无欲什么目标。朴素平凡,容易扩展,容易清除,(比由她们之那种设计)多
TM 简单。他们之 “hacker solution”
真的凡同时蠢又笨。他们写出来的那么堆物到处透漏着疯狂和愚昧。他们缺少技术认知。

坏显眼,OO 的狂热者们心惊肉跳数据。他们喜爱用讲话或者组织器来初始化 tables
。他们从来无写 table-driven 的测试。Why is this?
得有多生的心里才会选择用一连串并且大多重合的类似华而不实,而休去用一个细小三行
table ? 我就听说有人因此各种 OO 的物替换掉 while 循环。

然好信息是,hierarchy-driven, keyword-heavy,
colored-ribbons-in-your-textook orthodoxy
这些东东快到头了。更多之人挑选组合要休是继往开来。有些人就重复开始认识
OO。

面向对象编程语言,其本意是用数据以及有关的作为开展编程,这是一个可怜好之想法。事实真的这样。但是,这个想法并无连续太好之
idea。 这个想法并不曾完全的认知编程的社会风气。

Sometimes data is just data and functions are just functions.

— Rob Pike (Unix 创建者之一之 (Ken Thompson, Dennis M. Ritche, and
Rob Pike))

07         {

正确,我们用之就是数的肤浅和多少的解释器。用表来存储你需要的各个数据,对于多态,C
语言中简单直接干净:union。使用这样一个简约的组织,你会储存各种不同之类型,而且你只是需要仓储他们之指针,这代表你免会见浪费多少内存,同时你能够获得同样内存段但是多少不同的架空。

08             System.out.println("This is a UNIX box and therefore good.") ;

下一场,使用一个链表或者频繁组,把这 union
装进去,遍历,cast,然后下你用之特定数据。

09         }

有的是语言都出 union 的变体,现代语言中的泛型就是 union
的等同种语法糖,但是你往往忘记了这种结构的实在价值跟图。仔细回味下此新的宏图:

10         else if (osName.equals("Windows NT") || osName.equals("Windows 95"))
enum ShapeKind {
  skLINE, skPORT, skBOARD
}

class Shape {
  kind: ShapeKind   
  value: Line | Port | Board
  contains(x: number, y: number): boolean
}

class ShapeContainer {
  shapes: Array<Shape>
  search(x: number, y: number): [ShapeKind, Shape]
}

type
  ShapeKind = enum
    skLINE, skPORT, skBOARD

  Shape = ref object
    case kind: ShapeKind
    of skLINE:
      line: Line
    of skPORT:
      port: Port
    of skBOARD:
      board: Board
    contains: (x: number, y: number): bool

  ShapeContainer = object
    shapes: seq[Shape]

proc search(c: ShapeContainer, x: number, y: number): tuple[kind: ShapeKind, shape: Shape]
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 }

接下来起用面向对象的编程方式同步一步地发展之代码。

先是因为过程化的笔触来重构之。

 

过程化的方案

01 public class PrintOS
02 {
03     private static String unixBox()
04     {
05         return "This is a UNIX box and therefore good." ;
06     }
07     private static String windowsBox()
08     {
09         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

 

 

01 public class OSDiscriminator // Factory Pattern
02 {
03     private static BoxSpecifier theBoxSpecifier = null ;
04     public static BoxSpecifier getBoxSpecifier()
05     {
06         if (theBoxSpecifier == null)
07         {
08             String osName = System.getProperty("os.name") ;
09             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

 

 

01 public class OSDiscriminator // Factory Pattern
02 {
03     private static java.util.HashMap storage = new java.util.HashMap() ;
04   
05     public static BoxSpecifier getBoxSpecifier()
06     {
07         BoxSpecifier value = (BoxSpecifier)storage.get(System.getProperty("os.name")) ;
08         if (value == null)
09             return DefaultBox.value ;
10         return value ;
11     }
12     public static void register(final String key, final BoxSpecifier value)
13     {
14         storage.put(key, value) ; // Should guard against null keys, actually.
15     }
16     static
17     {
18         WindowsBox.register() ;
19         UNIXBox.register() ;
20         MacBox.register() ;
21     }
22 }

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

 

 

01 public class UNIXBox implements BoxSpecifier // Singleton Pattern
02 {
03     public static final UNIXBox value = new UNIXBox() ;
04     private UNIXBox() { }
05     public  String getStatement()
06     {
07         return "This is a UNIX box and therefore good." ;
08     }
09     public static final void register()
10     {
11         OSDiscriminator.register("SunOS", value) ;
12         OSDiscriminator.register("Linux", value) ;
13     }
14 }

WindowsBox.java

 

 

01 public class WindowsBox implements BoxSpecifier  // Singleton Pattern
02 {
03     public  static final WindowsBox value = new WindowsBox() ;
04     private WindowsBox() { }
05     public String getStatement()
06     {
07         return "This is a Windows box and therefore bad." ;
08     }
09     public static final void register()
10     {
11         OSDiscriminator.register("Windows NT", value) ;
12         OSDiscriminator.register("Windows 95", value) ;
13     }
14 }

MacBox.java

 

 

01 public class MacBox implements BoxSpecifier // Singleton Pattern
02 {
03     public static final MacBox value = new MacBox() ;
04     private MacBox() { }
05     public  String getStatement()
06     {
07         return "This is a Macintosh box and therefore far superior." ;
08     }
09     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的宏图则

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图