可是,这个绘图项目真正坏复杂,涉及了成百上千的多态和涉嫌。比如,在一个抬高的列表中贮存种类不一之图片,这些图存储的绘图数据及相关信息都不比,我用拿这些数据视做同一栽类型,然后迭代它们,选出需要之一个以动其的连锁消息。所以,我尝试采取学术界的设计模式来解决其中的题材。

 

自身当搜到了同一可怜堆 Linus 排斥面向对象和 C++ Java
的讲话,从感觉上,这些虽是自我面临设计困难时刻的感到。我就无数不善这样化解我之次序设计。

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

git的统筹其实十分之略,它的数据结构很平稳,并且发生增长的文档描述。事实上,我非常之同情应该围绕我们的数据结构来统筹代码,而不是根据其它的,我觉得就为是git之所以成功之缘故之一。[…]
依我之观,好程序员和烂程序员之间的差别就在于他们认为是代码更重要还是数据结构更要紧。

每当特大之路被,人们对匪是团结开发的模块并无了解,能便捷掌握外模块中函数的恰到好处含义才能够增长开支效率。而C++引入的各种抽象则要代码非常靠上下文,想知道一段子代码,需要看多得几近的上下文。

面向对象语言为目标啊主干,加有相互关联的法,简直是呓语。重要之事物应该是数据结构,对象自我有何要?真正有意思的,是于不同档次的不同对象交互而且有锁规则之早晚。但是,即使是这,封装什么“对象接口”也断然大错特错,因为不再是十足对象的题目了。

18     }

是类型于开之远在早已背了自家的一对觉得,对于程序设计之发。从自我对数据库和服务器的连年历,使用基于数据表和多少说明的抽象结构,你说到底能获得无限简单易行好用而扩大的软件结构。

10         else if (osName.equals("Windows NT") || osName.equals("Windows 95"))

为此,我道我还要不见面编程了。于是,我竭尽的重新考虑这些规划,并且更当网及查找曾经支持自己之计划论调:面向数据结构编程而休是目标。如果非是为是绘图项目,我绝对免会见铤而走险再同不成下设计模式和面向对象。

07         {

有趣的凡,这里出平等篇另外一个长辈的怪早的字,推在 Google+ 上,来自 Unix
核心创建者之一 Rob Pike:

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

毋庸置疑,我们用的便是数的纸上谈兵和数据的解释器。用表来存储你需要的依次数据,对于多态,C
语言中简易直接干净:union。使用这样一个略的布局,你可知积存各种不同的种类,而且你只是需要仓储他们之指针,这意味你无见面浪费多少内存,同时您可知得到同等内存段但是多少不同的空洞。

预先看就首教程是怎么来讲述OOP的。它预先让了下是题材,这个题材要输出一段关于操作系统的仿:假设Unix很科学,Windows很不同。

原文链接
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))

接下来起用面向对象的编程方式一样步一步地提高之代码。

接下来,使用一个链表或者反复组,把此 union
装进去,遍历,cast,然后下你需要的特定数据。

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

总之,就算设计模式避免了近似继承的爆炸,但是也避免不了纸上谈兵层级的纷繁。

15         {
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]

斯把下面这段代码描述成是Hacker
Solution
。(这拉人认为下面就被黑客?我估摸就支援人当成无看了C语言的代码)

当型转移得十分巨大的时刻,我意识及设计模式屁都未是。诸如桥接、装饰器以及任何,都是建于同栽要,假而你的父组件和子组件总是可以忽略对方的底细,而得以合的拍卖它们。比如,面包来奶油味、抹茶味、水果味,面包又起起码材料、高档材料,那么您可拿味道跟素材分为两单不同的接口,然后分别抽象,并且做这简单只接口生成更增长的面包,比如低档材料的删除茶味面包。但是,真实的编程世界中,这样的佳状态大少。在真实的编程世界被,面包还眷恋只要又多之东西,比如奶油味的发出甜,抹茶味的尚未糖,有甜味的面包放在左边柜台上,没有糖的面包放在右边柜台及。看到了咔嚓,复杂度升级了,柜台及面包来没有发出糖是绑定的。这表示,如果你想像前那么抽象两个接口—味道和材料,那你现在必考虑柜台。因为低档材料的删除茶味面包是没糖的,放在右边柜台。现在,你只能抽象出味道跟柜台的涉。在方的接口之上再搭一交汇。每当你的急需复杂一点,这种层就见面提升。比如,红糖面包和白糖面包。

自家之懂得

本身觉得,这首文章的例子举得无比差了,差得发就是比如是OO的高档黑。面向对象编程注重的是:1)数据和那个表现之打包封装,2)程序的接口和兑现的解耦。你那怕,举一个大抵个开关和多单电器的例子,不然就是像STL中,一个排序算法对大多独不同容器的事例,都于之例子要好得几近得几近。老实说,Java
SDK里极其多如此的事物了。

我原先受一些铺称一些设计模式的培训课,我一再提到,那23只经的设计模式和OO半毛钱干远非,只不过人家用OO来促成罢了。设计模式就三独准则:1)中意为整合而未是继续,2)依赖让接口而休是实现,3)高内聚,低耦合。你看,这全然就是是Unix的计划则

过多语言都生 union 的变体,现代语言中的泛型就是 union
的一律栽语法糖,但是若往往忘记了这种结构的确实价值以及图。仔细回味下这新的筹划:

02 {

近来点滴单周末,我使用 plantuml (贝尔实验室产品了一个顶尖级绘图工具
graphviz,
这是一个包装版)把自身之绘图项目举行了一样潮全面的接口及好像的可视化。使用了众多设计模式,包括:桥接、装饰器、生成器、抽象工厂。绘制了晚,图像是生美的,接口之间的相与参数定义清晰优雅。很美妙!

16             System.out.println("This is not a box.") ;

然并卵!

17         }
13         }
19 }
12             System.out.println("This is a Windows box and therefore bad.") ;

纯真的面向对象编程

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的面向对象的缓解方案。

过程化的方案

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 }

接下来是一个稚嫩的面向对象的笔触。

 

 

01 public class PrintOS
04     {
14         else
05         String osName = System.getProperty("os.name") ;

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.

09         }

首先因为过程化的思绪来重构之。

从今Rob Pike 的 Google+上的一个推看到了同一篇让《Understanding Object
Oriented
Programming》的章,我事先将当时首文章简述一下,然后再说说老牌黑客Rob
Pike的褒贬。

 

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是果刚刚完结了一致按部就班关于敏捷和模式的书写。

11         {

相关文章

网站地图xml地图