毋庸置疑的编程姿势。如此清楚面向对象编程。

新近零星独星期日,我用 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的宏图则

相关文章