找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3518|回复: 0

软件架构初体验

[复制链接]
发表于 2011-12-27 13:41:59 | 显示全部楼层 |阅读模式
近两个月来,自己都在架构设计中痛苦挣扎着。很多人都会奇怪,做架构设计是多么另人心动的事情呀,怎么会痛苦呢?原因很简单,就是我不会!本人就职以来并没有系统的学习过架构设计,只是在工作中用到过一些如UML画类图等知识,而更多的,就是上头分配任务给我做,而让我从头做架构设计,从来没有过。我不知从何开始。
         对不知的事物,我都是从搜索引擎开始。我在网络上畅游,想找到对我有用的东西,可是我发现用架构这个关键词去搜索,找到很多的是软件架构这个词条,还有一些网址。我把词条通读后,发现对我还是有帮助的(因为我是零基础),但这好像远远不够。我想找这方面的教程,找到一些培训的课程的目录,里面好多都是我想学习的,但是并没有找到书籍。尝试过不同关键字后,找到了两本外文书,是叙述如何做框架的,专业术语太多,我只好先放弃了。功夫不负有心人,找到了两本中文教程。开始了我的边学边实践的旅程。整个过程是很痛苦的,因为身边并没有人给你指导,只能靠着一两本书,自己也不知道书中是否就是适合自己的,就这样的摸索着,在最后完成后才感受到一些喜悦。
        其实无论做什么事,都要清楚要干什么。这在我们做软件中就是要深入理解需求。这一点说起来容易,做起来很难。我的痛苦经历告诉我,表达不清的需求太多,不明确就意味着这个东西不好做。很多时候,客户是表达不清自己要什么的,那么需要我们去引导。这时有经验的大牛就会发挥很大的左右。还有很多功能点遗漏,不定什么时候客户想起来了,让你给加上。需求的不确定,对架构的要求就很高了。能够支持扩展的架构才是好架构。
         从需求中找出重点功能,围绕着它塑造你的概念架构。有位老师这样总结到:有这样两种常见的情况,业务流程不变而业务单元可变,方案就是利用设计模式构建软件框架;另一种是业务单元不变而流程变化,方案就是需要适应业务流程敏捷性处理的面向服务的架构。我遇到的情况属于第一种。
        我需要一种框架。这方面我得到了同事的大力支持。给出了非常好的适应变化的框架。举个耳熟能详的例子,《Java编程思想》中讲解内部时引入了一个Control框架,对,就是这种思想。
  1. //: Event.java
  2. // The common methods for any control event
  3. package c07.controller;
  4. abstract public class Event {
  5.   private long evtTime;
  6.   public Event(long eventTime) {
  7.     evtTime = eventTime;
  8.   }
  9.   public boolean ready() {
  10.     return System.currentTimeMillis() >= evtTime;
  11.   }
  12.   abstract public void action();
  13.   abstract public String description();
  14. } ///:~/: Controller.java
  15. // Along with Event, the generic
  16. // framework for all control systems:
  17. package c07.controller;
  18. // This is just a way to hold Event objects.
  19. class EventSet {
  20.   private Event[] events = new Event[100];
  21.   private int index = 0;
  22.   private int next = 0;
  23.   public void add(Event e) {
  24.     if(index >= events.length)
  25.       return; // (In real life, throw exception)
  26.     events[index++] = e;
  27.   }
  28.   public Event getNext() {
  29.     boolean looped = false;
  30.     int start = next;
  31.     do {
  32.       next = (next + 1) % events.length;
  33.       // See if it has looped to the beginning:
  34.       if(start == next) looped = true;
  35.       // If it loops past start, the list
  36.       // is empty:
  37.       if((next == (start + 1) % events.length)
  38.          && looped)
  39.         return null;
  40.     } while(events[next] == null);
  41.     return events[next];
  42.   }
  43.   public void removeCurrent() {
  44.     events[next] = null;
  45.   }
  46. }
  47. public class Controller {
  48.   private EventSet es = new EventSet();
  49.   public void addEvent(Event c) { es.add(c); }
  50.   public void run() {
  51.     Event e;
  52.     while((e = es.getNext()) != null) {
  53.       if(e.ready()) {
  54.         e.action();
  55.         System.out.println(e.description());
  56.         es.removeCurrent();
  57.       }
  58.     }
  59.   }
  60. } ///:~
复制代码
那么如何使用呢?一个greenhouse的例子:
  1. //: GreenhouseControls.java
  2. // This produces a specific application of the
  3. // control system, all in a single class. Inner
  4. // classes allow you to encapsulate different
  5. // functionality for each type of event.
  6. package c07.controller;
  7. public class GreenhouseControls
  8.     extends Controller {
  9.   private boolean light = false;
  10.   private boolean water = false;
  11.   private String thermostat = "Day";
  12.   private class LightOn extends Event {
  13.     public LightOn(long eventTime) {
  14.       super(eventTime);
  15.     }
  16.     public void action() {
  17.       // Put hardware control code here to
  18.       // physically turn on the light.
  19.       light = true;
  20.     }
  21.     public String description() {
  22.       return "Light is on";
  23.     }
  24.   }
  25.   private class LightOff extends Event {
  26.     public LightOff(long eventTime) {
  27.       super(eventTime);
  28.     }
  29.     public void action() {
  30.       // Put hardware control code here to
  31.       // physically turn off the light.
  32.       light = false;
  33.     }
  34.     public String description() {
  35.       return "Light is off";
  36.     }
  37.   }
  38.   private class WaterOn extends Event {
  39.     public WaterOn(long eventTime) {
  40.       super(eventTime);
  41.     }
  42.     public void action() {
  43.       // Put hardware control code here
  44.       water = true;
  45.     }
  46.     public String description() {
  47.       return "Greenhouse water is on";
  48.     }
  49.   }
  50.   private class WaterOff extends Event {
  51.     public WaterOff(long eventTime) {
  52.       super(eventTime);
  53.     }
  54.     public void action() {
  55.       // Put hardware control code here
  56.       water = false;
  57.     }
  58.     public String description() {
  59.       return "Greenhouse water is off";
  60.     }
  61.   }
  62.   private class ThermostatNight extends Event {
  63.     public ThermostatNight(long eventTime) {
  64.       super(eventTime);
  65.     }
  66.     public void action() {
  67.       // Put hardware control code here
  68.       thermostat = "Night";
  69.     }
  70.     public String description() {
  71.       return "Thermostat on night setting";
  72.     }
  73.   }
  74.   private class ThermostatDay extends Event {
  75.     public ThermostatDay(long eventTime) {
  76.       super(eventTime);
  77.     }
  78.     public void action() {
  79.       // Put hardware control code here
  80.       thermostat = "Day";
  81.     }
  82.     public String description() {
  83.       return "Thermostat on day setting";
  84.     }
  85.   }
  86.   // An example of an action() that inserts a
  87.   // new one of itself into the event list:
  88.   private int rings;
  89.   private class Bell extends Event {
  90.     public Bell(long eventTime) {
  91.       super(eventTime);
  92.     }
  93.     public void action() {
  94.       // Ring bell every 2 seconds, rings times:
  95.       System.out.println("Bing!");
  96.       if(--rings > 0)
  97.         addEvent(new Bell(
  98.           System.currentTimeMillis() + 2000));
  99.     }
  100.     public String description() {
  101.       return "Ring bell";
  102.     }
  103.   }
  104.   private class Restart extends Event {
  105.     public Restart(long eventTime) {
  106.       super(eventTime);
  107.     }
  108.     public void action() {
  109.       long tm = System.currentTimeMillis();
  110.       // Instead of hard-wiring, you could parse
  111.       // configuration information from a text
  112.       // file here:
  113.       rings = 5;
  114.       addEvent(new ThermostatNight(tm));
  115.       addEvent(new LightOn(tm + 1000));
  116.       addEvent(new LightOff(tm + 2000));
  117.       addEvent(new WaterOn(tm + 3000));
  118.       addEvent(new WaterOff(tm + 8000));
  119.       addEvent(new Bell(tm + 9000));
  120.       addEvent(new ThermostatDay(tm + 10000));
  121.       // Can even add a Restart object!
  122.       addEvent(new Restart(tm + 20000));
  123.     }
  124.     public String description() {
  125.       return "Restarting system";
  126.     }
  127.   }
  128.   public static void main(String[] args) {
  129.     GreenhouseControls gc =
  130.       new GreenhouseControls();
  131.     long tm = System.currentTimeMillis();
  132.     gc.addEvent(gc.new Restart(tm));
  133.     gc.run();
  134.   }
  135. } ///:~
复制代码
有了这种框架的思想,下面就容易做到“把稳定和变化分离开”,做到封装变化。

细化架构的时候,需要确定各模块的接口和数据结构。一个好的数据结构会让你的架构增光不少。一个原则,就是要把数据结构设计好,让其适应变化。
这个时候就可以开始基类的定义了,画类图、时序图等等。文档也是必不可少。
这方面我还没有好好做就开始编码了,而且框架也在适当的修改着。
这只是一个开始,以后还能有机会做设计,就不会想这次这样痛苦和难堪了。
作者:lincyang 发表于2011-12-26 21:04:22 原文链接
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-4-29 21:36 , Processed in 0.011074 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表