zoukankan      html  css  js  c++  java
  • 《大话设计模式》第四章

    对于扩展是开放的,对于更改是封闭的

    无论模块是多么的“封闭”,都会存在些无法对之封闭的变化。我们是很难预先猜测,但我们却可以在发生小变化时,就及早去想办法应对发生更大变化的问题。也就是说,等到变化发生时立即采取行动。正所谓,同一地方,摔第一跤不是你的错,再次在此摔跤就是你的不对了。

    在我们最初编写代码时,假设变化不会发生。当变化发生时,我们就创建抽象来隔离以后发生的同类变化。面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码。

    当然,并不是什么时候应对变化都是容易的,我们希望的是在开发工作展开不久就知道可能发生的变化。查明可能发生的变化所等待的时间越长,要创建正确的抽象就越困难。

    开发人员应该仅对程序中呈现出频繁变化的那些部分做出抽象,然而,对于应用程序中的每个部分都刻意地进行抽象同样不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要。

    --高级的开发人员就是之前经历过变化,或事先就能预感到哪些是较大可能性的变化,

    从子程序到控件的发展,就是经历“对更改是封闭”的这个动作。原来,我们的操作逻辑都用子程序体现出来,但这些子程序一旦给其它程序员使用,他们在自己的程序出错时,就跟踪到了子程序里面,然后想当然地以为共用的子程序出错了(准确地,可以说外部的条件不满足子程序的要求,也可以说子程序的功能不够强),然后就开始更改子程序,后面就越改越乱。后来,我们把这些子程序封装到控件中去,这些程序员根本无法调试进入这些代码,因此更不要说更改代码了。
    虽然说我们解决了一部分问题,但随之而来的问题是程序员出错后,根本不知道是什么原因出错,然后只能提交给公司的核心技术人员来调试,如果中间沟通的不够充分,核心技术人员又无法创建相应的出错情况,那处理时间又被拖延。开放代码与不开放代码中间,我们无从决择。开放代码造成公司关键技术到处流传,也不是个好事。假设我们决定“坚决不开放代码”……不过即使其它公司,也没有非常好的解决方案,这也离题了。
    控件这一些是“对更改是封闭”的实现了,但“对扩展是开放”的,实现得不那么好,我们虽然在控件中有插入事件,如BeforeClick、AfterClick,但要想象类那样创建新对象,自由地或完全地替代对象的某个方法是不可能的,虽然有时完全替代一个复杂的逻辑也不是个好主意,但类的继承仍然能够随时调用父类的原来处理过程,这就有极大的灵活性。
    有时说,VB的控件完全没有“对扩展是开放”,这明显也是错的,如果我们创建一个控件,然后控件中拉入别人写得很好的控件时,自己再加上一两个功能,也是实现了把别人控件的好东西都带来,而自己又加上了一些功能。只是这种复用是功能上的复用,而不是代码上的复用。

    我要用什么实例来体现出类的“对更改是封闭的,对扩展是开放的”这一点呢?

    什么是更改,什么是扩展,如果猜数字的游戏中,我原来只能猜3位的数,现在要“扩展”为猜4位的数,能够通过不修改原来的类代码就扩展吗?显然不行。
    这是否是说,类的扩展也是有限的,它还与当初设计类的人的能力有关,一个糟糕的类,在变化面前,对其只能进行更改,而不是扩展。
    更深的课题应该是“如何设计出良好的类?”,让别人有较多的扩展空间。

    这一次,我试着新建一个“类库”的项目,里面加入game.cs这个类,并且,让这个类写得像话一点,并且在设计时,考虑有可能扩展为几位。
    对错误的修改,例如输入的位数不够的判断,还是必须进入类而进行修改。
    对功能性的扩展,如,要想加入一个最后提示你成功,或再加上你成功的步数。好象不行。

    我这个类糟糕得实在不行了。

  • 相关阅读:
    Axis,axis2,Xfire以及cxf对比 (转)
    客户端调用服务器端三种方式
    webservice发送数据,取数据的方式
    强制关闭myeclipse出现的问题
    取当前系统的上月时间
    oracle 报Ora-01008错误:oracle 并非所有变量都已绑定的原因.TO_number();动态执行select..into..语句时
    ResultSetMetaData rsmd = rs.getMetaData()是什么意思?
    概率质量函数:怀孕周期的PMF
    Python 正则表达式
    TF-IDF
  • 原文地址:https://www.cnblogs.com/yzx99/p/1243778.html
Copyright © 2011-2022 走看看