IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]软件架构初体验

    lincyang发表于 2011-12-26 21:04:22
    love 0

            近两个月来,自己都在架构设计中痛苦挣扎着。很多人都会奇怪,做架构设计是多么另人心动的事情呀,怎么会痛苦呢?原因很简单,就是我不会!本人就职以来并没有系统的学习过架构设计,只是在工作中用到过一些如UML画类图等知识,而更多的,就是上头分配任务给我做,而让我从头做架构设计,从来没有过。我不知从何开始。

             对不知的事物,我都是从搜索引擎开始。我在网络上畅游,想找到对我有用的东西,可是我发现用架构这个关键词去搜索,找到很多的是软件架构这个词条,还有一些网址。我把词条通读后,发现对我还是有帮助的(因为我是零基础),但这好像远远不够。我想找这方面的教程,找到一些培训的课程的目录,里面好多都是我想学习的,但是并没有找到书籍。尝试过不同关键字后,找到了两本外文书,是叙述如何做框架的,专业术语太多,我只好先放弃了。功夫不负有心人,找到了两本中文教程。开始了我的边学边实践的旅程。整个过程是很痛苦的,因为身边并没有人给你指导,只能靠着一两本书,自己也不知道书中是否就是适合自己的,就这样的摸索着,在最后完成后才感受到一些喜悦。

            其实无论做什么事,都要清楚要干什么。这在我们做软件中就是要深入理解需求。这一点说起来容易,做起来很难。我的痛苦经历告诉我,表达不清的需求太多,不明确就意味着这个东西不好做。很多时候,客户是表达不清自己要什么的,那么需要我们去引导。这时有经验的大牛就会发挥很大的左右。还有很多功能点遗漏,不定什么时候客户想起来了,让你给加上。需求的不确定,对架构的要求就很高了。能够支持扩展的架构才是好架构。

             从需求中找出重点功能,围绕着它塑造你的概念架构。有位老师这样总结到:有这样两种常见的情况,业务流程不变而业务单元可变,方案就是利用设计模式构建软件框架;另一种是业务单元不变而流程变化,方案就是需要适应业务流程敏捷性处理的面向服务的架构。我遇到的情况属于第一种。

            我需要一种框架。这方面我得到了同事的大力支持。给出了非常好的适应变化的框架。举个耳熟能详的例子,《Java编程思想》中讲解内部时引入了一个Control框架,对,就是这种思想。

    //: Event.java
    // The common methods for any control event
    package c07.controller;
    
    abstract public class Event {
      private long evtTime;
      public Event(long eventTime) {
        evtTime = eventTime;
      }
      public boolean ready() {
        return System.currentTimeMillis() >= evtTime;
      }
      abstract public void action();
      abstract public String description();
    } ///:~
    /: Controller.java
    // Along with Event, the generic
    // framework for all control systems:
    package c07.controller;
    
    // This is just a way to hold Event objects.
    class EventSet {
      private Event[] events = new Event[100];
      private int index = 0;
      private int next = 0;
      public void add(Event e) {
        if(index >= events.length)
          return; // (In real life, throw exception)
        events[index++] = e;
      }
      public Event getNext() {
        boolean looped = false;
        int start = next;
        do {
          next = (next + 1) % events.length;
          // See if it has looped to the beginning:
          if(start == next) looped = true;
          // If it loops past start, the list 
          // is empty:
          if((next == (start + 1) % events.length)
             && looped)
            return null;
        } while(events[next] == null);
        return events[next];
      }
      public void removeCurrent() {
        events[next] = null;
      }
    }
    
    public class Controller {
      private EventSet es = new EventSet();
      public void addEvent(Event c) { es.add(c); }
      public void run() {
        Event e;
        while((e = es.getNext()) != null) {
          if(e.ready()) {
            e.action();
            System.out.println(e.description());
            es.removeCurrent();
          }
        }
      }
    } ///:~
    那么如何使用呢?一个greenhouse的例子:

    //: GreenhouseControls.java
    // This produces a specific application of the
    // control system, all in a single class. Inner
    // classes allow you to encapsulate different
    // functionality for each type of event.
    package c07.controller;
    
    public class GreenhouseControls 
        extends Controller {
      private boolean light = false;
      private boolean water = false;
      private String thermostat = "Day";
      private class LightOn extends Event {
        public LightOn(long eventTime) {
          super(eventTime);
        }
        public void action() {
          // Put hardware control code here to 
          // physically turn on the light.
          light = true;
        }
        public String description() {
          return "Light is on";
        }
      }
      private class LightOff extends Event {
        public LightOff(long eventTime) {
          super(eventTime);
        }
        public void action() {
          // Put hardware control code here to 
          // physically turn off the light.
          light = false;
        }
        public String description() {
          return "Light is off";
        }
      }
      private class WaterOn extends Event {
        public WaterOn(long eventTime) {
          super(eventTime);
        }
        public void action() {
          // Put hardware control code here
          water = true;
        }
        public String description() {
          return "Greenhouse water is on";
        }
      }
      private class WaterOff extends Event {
        public WaterOff(long eventTime) {
          super(eventTime);
        }
        public void action() {
          // Put hardware control code here
          water = false;
        }
        public String description() {
          return "Greenhouse water is off";
        }
      }
      private class ThermostatNight extends Event {
        public ThermostatNight(long eventTime) {
          super(eventTime);
        }
        public void action() {
          // Put hardware control code here
          thermostat = "Night";
        }
        public String description() {
          return "Thermostat on night setting";
        }
      }
      private class ThermostatDay extends Event {
        public ThermostatDay(long eventTime) {
          super(eventTime);
        }
        public void action() {
          // Put hardware control code here
          thermostat = "Day";
        }
        public String description() {
          return "Thermostat on day setting";
        }
      }
      // An example of an action() that inserts a 
      // new one of itself into the event list:
      private int rings;
      private class Bell extends Event {
        public Bell(long eventTime) {
          super(eventTime);
        }
        public void action() {
          // Ring bell every 2 seconds, rings times:
          System.out.println("Bing!");
          if(--rings > 0)
            addEvent(new Bell(
              System.currentTimeMillis() + 2000));
        }
        public String description() {
          return "Ring bell";
        }
      }
      private class Restart extends Event {
        public Restart(long eventTime) {
          super(eventTime);
        }
        public void action() {
          long tm = System.currentTimeMillis();
          // Instead of hard-wiring, you could parse
          // configuration information from a text
          // file here:
          rings = 5;
          addEvent(new ThermostatNight(tm));
          addEvent(new LightOn(tm + 1000));
          addEvent(new LightOff(tm + 2000));
          addEvent(new WaterOn(tm + 3000));
          addEvent(new WaterOff(tm + 8000));
          addEvent(new Bell(tm + 9000));
          addEvent(new ThermostatDay(tm + 10000));
          // Can even add a Restart object!
          addEvent(new Restart(tm + 20000));
        }
        public String description() {
          return "Restarting system";
        }
      }
      public static void main(String[] args) {
        GreenhouseControls gc = 
          new GreenhouseControls();
        long tm = System.currentTimeMillis();
        gc.addEvent(gc.new Restart(tm));
        gc.run();
      } 
    } ///:~

    有了这种框架的思想,下面就容易做到“把稳定和变化分离开”,做到封装变化。

    细化架构的时候,需要确定各模块的接口和数据结构。一个好的数据结构会让你的架构增光不少。一个原则,就是要把数据结构设计好,让其适应变化。

    这个时候就可以开始基类的定义了,画类图、时序图等等。文档也是必不可少。

    这方面我还没有好好做就开始编码了,而且框架也在适当的修改着。

    这只是一个开始,以后还能有机会做设计,就不会想这次这样痛苦和难堪了。






沪ICP备19023445号-2号
友情链接