澳门网上娱乐平台不错的编程姿势。如此清楚面向对象编程。

近些年少只礼拜,我以 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的计划则