实现模式之一种编程理论

    这篇文章讲述的是,我们在编程的过程中以一种什么样的价值观作为导向,遵守一些什么样的规则。就能编写出比较优秀的代码。

   

     先说一下三个概念

     模式:也就是我们通常所说的解决方案,比如要写一个循环遍历有很多实现方案。模式表达的是我们要做什么和怎么做出来。

     价值观:也就是我们编程应该实现的目的,统一支配我们编程的过程。比如我们实现的模式要很灵活。

     原则:实现解决方案的准则。价值观为我们实现解决方案提供了方向,原则就是告诉我们在实现这种解决方案的过程中应该遵守怎么样的规则。

     他们三者之间的关系是:模式描述了要做什么,价值观提供了动机,原则把动机转变成了实际行动。

     也就是我们在编写一种解决方案的时候,应该有一种价值观导向(我们要编写出什么样的程序),在编写的过程中应该遵守一定的规则来实现这种价值观。(比如变量命名要规范之类)

 

     价值观

     有3个价值观与优秀的编程血脉相连。它们分别是:沟通,简单与灵活。

     1.沟通

     在编程的时候,我们很容易从计算机的角度进行思考,但只有一面编程一面考虑其他人的感受,才能编写出好的代码。也就是我们在编写代码的时候,想想别人看到这段代码会怎么想?Knuth提出过一种文学编程理论:程序应该读起来像一本优秀的小说,它需要有情节与韵律,句子之间应该有优雅的小小跌宕起伏。

 

     2. 简单

     尽量使程序的逻辑简单。去掉多余的复杂性可以让那些阅读,使用与修改代码的人更容易理解。有些复杂性是内在的,它们准确地反映出所有解决问题的复杂性。但有些复杂性的产生完全是因为我们忙着让程序跑起来,在摆弄过程中留下来的“指甲印”没有擦干净。所以回顾自己做过的事情,把麦子和糠分开,是编程不可或缺的一部分。

     其实这个目的与沟通是相辅相成的,程序逻辑越简单,与读者沟通也就越方便。

 

    3. 灵活

    在三个价值观中,灵活是衡量那些低效编码与设计实践的一把标尺。程序越灵活,后面维护起来也就越方便。但是灵活性的提高是以复杂性提高为代价的,这就需要我们好好权衡一下利弊了。不要盲目追求程序的灵活性而增加程序的复杂度。

 

    原则

    我们在编程的过程中应该遵守的一些准则。

  

     1. 局部化影响

     组织代码结构的时候,要保证变化只会产生局部化影响。如果这里的一个变化引起那里的一个问题,那么变化的代价就会急剧上升了。把影响范围缩到最小,代码就会有极佳的沟通效果。它可以被逐步深入理解,而不必一开始就要鸟瞰全图。

    

      2. 最小化重复

      如果相同的代码出现在多个地方,那么改动一处副本的时候,就不得不考虑是否需要修改其他的副本。这样变动不在发生在局部了,代码重复的越多,变化的代价就越高。所以我们要把重复的代码抽出来形成一小段代码或者方法,保证变化只会带来局部化影响。

 

     3. 将逻辑与数据捆绑

     把逻辑与逻辑所处理的数据放在一起,在发生变化的时候,数据和逻辑可能同时需要改动。如果把他们放在一起,那么修改它们所造成的影响只会停留在局部。

    

     4. 对称性

     程序中处处充满了对称性,比如add()方法总是伴着remove()方法。识别出对称性,把它清晰表达出来,代码将更加容易阅读。一但阅读者理解了对称性所涵盖的某一半,它们就会很快理解另外一半。程序中的对称性指的是概念上的对称性,无论在什么地方,同样的概念都以同样的形式呈现。

     比如: 缺少对称性的例子:

     void process() {

          input();

          count++;

          output();

     }

     第二条语句更加具体。应该跟第一条与第三条语句一样使用方法的形式展示。

      void process() {

          input();

          incrementCount();

          output();

     }

     但是这个方法依然违反了对称性。第一个方法和第三个方法都是以方法意图来命名的,而第二个方法是以实现方式来命名的。我们应该想到我count++是为了干什么,于是就像如下的结果:(tally: 记账)

 

      void process() {

          input();

          tally();

          output();

     }

 

     5. 声明式表达

     实现模式背后另一条原则是尽可能声明式地表达出你的意图。(这个地方没看得很明白,不详述了,今后补充!)

 

     6. 变化率

     把具有相同变化率的逻辑,数据放在一起,把具有不同变化率的逻辑与数据分离。一个对象中所有成员变量的变化率应该差不多相同。两个同时变化但又和其他成员的变化步调不一致的变量应该属于某一个辅助对象。比如金融票据的数值和币种会同时变化,那么这两个变量最好放到一个辅助对象里面:

    setAmount(int value, String currency) {

        this.value = value;

        this.currency = currency;

     }

    调整为:

    setAmount(Money money) {

      this.money = money;

     }

     变化率原则也是对称性的一个应用,不过是时间上的对称。在上面的例子中value与currency是对称的,它们会同时变化。但它们与其他字段不对称,把它们放到属于自己的对象中,让新的对象向阅读者传递它们的对称关系,这样就更可以在将来消除重复,进一步达到影响的局部化。

 

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值