Fork me on GitHub
框架、架构、模式、重构

框架很多,各种各样的,不同的平台,不同的语言,不同的功能。
    现阶段的软件项目,几乎都会用到框架,何为框架,为什么要用框架。
    所谓框架,是一种看得见的软件产品,是一种半成品。既然他是产品,他应该已经在那里了,如果你愿意,你可以使用他。就像一幢施工了一半,已经有梁有柱,有楼板、简单楼梯的五层楼房,只要你愿意,你可以爬楼梯锻炼身体。而他是半成品,说明他还不完整,需要对他进行填空。而这些空将决定“成品”是什么。刚才锻炼身体的楼房按照不同的布局和装饰可以成为写字楼,或者住宅。由于软件的可复制性,抽取出大部分楼房的共性,在此基础上加以相对少量的施工即可满足市场的需要,提高了软件的生产效率,此其一。
    同样由于软件的可复制性,框架代码往往是较长时间的积累与实践测试,质量较高。上面说的那个楼房我保证每层楼高都相同,且结构可以抗8级地震,只要在这个结构基础上施工,不论多少人一起施工,房子也不会出这方面的问题,不管你懂不懂工程力学。因此提高了软件的质量,降低了开发难度与风险,加强团队开发的可能性,并降低了施工人员成本。此其二。
    框架有其与生俱来的限制。还是那幢楼,如果你想在这个基础上建成国家体育场,想必也是没有什么可能的,如果蛮干,把大梁卸了,可能离新闻报道就不远了。所以选择框架要合适,使用框架也要遵循当初框架设计者的思路。此其三。

    关于架构,这里讲的是软件架构。那是一种思想,你看不见。也没有一一对应的产品。他是实践中总结出的一种指导如何设计软件以达到某种要求的思路。
    你要盖个一层两层小房,简单,来几根好点的木料,加几车砖,就行了,砖木结构。三到四层?砖混结构。五到十五层?钢混结构。十五层到四十层?全钢结构。四十层以上?那就复杂了,请教专家去。
    架构思路是比较抽象的,他指明了在某种大体的场景下的大概的方向。在框架的设计中往往始终贯穿着一种或者几种架构思想。

    模式呢?那是在某一范围内某种场景下为解决某种问题而可以重复实践的方案。高层建筑,用电梯。要房间明亮,弄个落地窗。这些使得我们在遇到某种场景下,不需要花大力气去思考,就可以较完美解决的方案。就像数学公式。
    在框架内部,结构可能会十分复杂,中间也夹杂着太多的问题需要解决,所以在框架设计中,往往非常多的应用到模式。

    事情很复杂,在开工之前没有必要将所有的细节全部考虑清楚。在施工过程中发现当前的结构中有一些不合理的地方。盖楼前没考虑用哪种门,先盖了再说吧,等开始装门的时候,发现每个房间的门都自己做,费工时,成本高,效果又不好。于是有个前辈说:不用这么麻烦,打个电话给XXX工厂,让他们提供某个系列的各种规格的门,送货上门,包安装还有保修,省心了。唔,重构就是在设计过程中对于软件中出现的臭味进行消除,使之符合某种设计模式的过程。

      一直以来我们都希望我们的代码在不影响可读、可维护、可移植等条件下尽可能的短小精悍。
      对于编程发烧友来说将代码的精简做极致,往往会比较变态,今天我也变了一把,时刻准备着各位拍砖。

      事情是这样的,有个朋友说他写了个彩票机先程序,然后群里开始讨论他的代码,后来谈到是否可以精简,有人说80行,有人说60行。问到笔者这里,我想应该10行左右,怎么样算一行呢,一个分号算一行吧,不包含命名空间。
      需求是这样的, 
      1、从1-33里随机取出7个数据,从小到大排列;
      2、再从1-16随机选中一个数字,作为特别号码,组成最后的彩票号码;
      3、用Windows应用程序,点击开始,滚动号码,点击停止,停止号码滚动。

      于是就动手开始写吧,从一开始15个分号,到12个分号,最后到8个分号,算是一个比较成型的代码吧:
 

 1 using System;
 2 using System.Windows.Forms;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 
 6 class Program
 7 {
 8     static void Main(string[] args)
 9     {
10         new Func<Form, Random, Form>((f, r) =>
11         {
12             f.Controls.AddRange(new Control[] { new Button { Text = "start", Top = 50 }, new Label { AutoSize = true } });
13             ((Button)f.Controls[0]).Click += (sender, e) =>{
14                 new Action<int>((ni) =>
15                 {
16                     ((Button)sender).Text = ((Button)sender).Text == "stop" ? "start" : "stop";
17                     while (f.Controls[0].Text == "stop") { f.Controls[1].Text = new int[33].Select(i => ni > 33 ? ni = 1 : ni++).Distinct().OrderBy(i => r.Next(33)).Take(7).OrderBy(i => i).ToList().Aggregate<intstring>(string.Empty, (s, i) => s + " - " + i.ToString()).Substring(3+ " = " + r.Next(117).ToString(); Application.DoEvents(); }
18                 })(1);};
19             return f;
20         })(new Form { Text = "xxxx" }, new Random()).ShowDialog();
21     }
22 }
23 

      运行结果就是这样子:
      

      代码中,为了尽可能少的分号,将临时变量的定义放进了委托调用的参数中,为了使委托也变少,将Click事件处理程序委托中的临时变量直接用sender中的某个成员,于是有了以下7个分号的代码,就显得比较变态了。
      

 1 class Program
 2 {
 3     static void Main(string[] args)
 4     {
 5         new Func<Form, Random, Form>((f, r) =>
 6         {
 7             f.Controls.AddRange(new Control[] { new Button { Text = "start", Top = 50 }, new Label { AutoSize = true } });/*分号甲*/
 8             ((Button)f.Controls[0]).Click += (sender, e) =>{
 9                 ((Button)sender).Text = ((Button)sender).Text == "stop" ? "start" : "stop";/*分号乙*/
10                 while (f.Controls[0].Text == "stop") { f.Controls[1].Text = new int[33].Select(i => ((Control)sender).Tag is int && (int)((Control)sender).Tag < 33 ? (int)(((Control)sender).Tag = ((int)((Control)sender).Tag) + 1) : (int)(((Control)sender).Tag = 0+ 1).Distinct().OrderBy(i => r.Next(33)).Take(7).OrderBy(i => i).ToList().Aggregate<intstring>(string.Empty, (s, i) => s + " - " + i.ToString()).Substring(3+ " = " + r.Next(117).ToString();/*分号丙*/ Application.DoEvents();/*分号丁*/ }};/*分号戊*/
11             return f;/*分号己*/
12         })(new Form { Text = "xxxx" }, new Random()).ShowDialog();/*分号庚*/
13     }
14 }
15 

      这是笔者目前能想到最精简的代码,运行效果和之前一致。
      今天比较无聊,纯属娱乐,很多为了减少分号出现的伎俩并不适合在真实开发中使用。
      如果有哪位朋友有更少分号的实现,欢迎共享之。
posted on 2010-05-20 15:40  HackerVirus  阅读(503)  评论(0编辑  收藏  举报