是的编程姿势。如此清楚面向对象编程。

不久前星星点点个礼拜,我动用 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 }

笔者betway必威还死的意地说,他加以了一个“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的统筹则

相关文章

发表评论

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