循证架构--寻找最适合自己的架构

本文介绍了一种基于循证的方法来确定软件项目的最佳架构方案。该方法适用于需求不确定且需快速迭代的情况,通过采用敏捷开发原则并利用特定的技术栈提高开发效率。

没有最好的架构,只有最合适的架构。循证架构是《Expert One-on-One J2EE Development without EJB》一书中推崇的架构思路,用俺们的话说就是摸着石头过河,找最适合自己的架构。

俺现在soho,大活不多,小活不断。我的工作具备以下特点:

(1) 根本没摸清楚需求的时间。需求都是从原型到Demo到版本1到版本2探索出来的。经常需求变化非常大,因此,必须以敏捷方法为基础;

(2) 一般没多少数据需要存储,顶多百万级;

(3) 需要极度的压榨开发效率。一个工作,10天完成和20天完成,那收益前者就是后者的两倍。

在上面(1)-(3)驱动下,俺摸索出的架构见下图:

myarch

从下往上,简单说说:

(1) 数据库:db4o。谁用谁知道,哈哈,爽。什么ORM,SQL,DataSet,统统是过眼云烟了。一切都是普通对象。数据库几乎是0设计。数据接入也非常非常的简单。

(2) Db4o之上得有一个逻辑层,来应付需求变化。这一层主要就是各种实体对象,需要良好的设计,否则,应付不了需求的变化。这一块我一般要设计比较完备的event体系,便于后期修改与组合。

(3) 服务层:主要是RIA应用需要。如果是Winform程序,不用这一层。

(4) UI逻辑层:最开始没弄这一层,最后鉴于在界面那一块太耗时间,就加了这么一层。这一层主要是:

a) 对于单个控件,将控件的常用操作逻辑封装成扩展方法;

例子: Winform程序中的Invoke方法使用起来很烦人,涉及到多个线程,还要判断多次 IsHandleCreated == true(经常忘记,导致bug)。于是,需要将它封装成扩展方法。

代码如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
    public class ControlFuncContext
ExpandedBlockStart.gifContractedBlock.gif    
{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public Control Control getprivate set; }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public Delegate Delegate getprivate set; }

        
public ControlFuncContext(Control ctl, Delegate d)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
this.Control = ctl;
            
this.Delegate = d;
        }


        
public void Invoke0()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (Control.IsHandleCreated == true)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                Delegate.DynamicInvoke();
            }

        }


        
public void Invoke1<T>(T obj)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (Control.IsHandleCreated == true)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                Delegate.DynamicInvoke(obj);
            }

        }


        
public void Invoke2<T0,T1>(T0 obj0, T1 obj1)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (Control.IsHandleCreated == true)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                Delegate.DynamicInvoke(obj0, obj1);
            }

        }

    }


    
public static class FormClassHelper
ExpandedBlockStart.gifContractedBlock.gif    
{
        
public static void InvokeFunc0(this Control ctl, Func0 func0)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (ctl.IsHandleCreated == true)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ControlFuncContext fc 
= new ControlFuncContext(ctl, func0);
                ctl.Invoke(
new Func0(fc.Invoke0));
            }

        }


        
public static void InvokeFunc1<T>(this Control ctl, Func1<T> func1, T obj)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (ctl.IsHandleCreated == true)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ControlFuncContext fc 
= new ControlFuncContext(ctl, func1);
                ctl.Invoke(
new Func1<T>(fc.Invoke1<T>), obj);
            }

        }


        
public static void InvokeFunc2<T0, T1>(this Control ctl, Func2<T0, T1> func2, T0 obj0, T1 obj1)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (ctl.IsHandleCreated == true)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                ControlFuncContext fc 
= new ControlFuncContext(ctl, func2);
                ctl.Invoke(
new Func2<T0,T1>(fc.Invoke2<T0,T1>), obj0, obj1);
            }

        }

    }

 

b) 对于多个控件,使用Mediator模式,将多个控件之间的组合抽象出Mediator类,方便重用。这一点我最开始是用户控件方式进行封装,结果发现太不灵活,最后改用Mediator,再配合扩展方法,开发速度biubiubiu的就上去了。

(5) UI:Html是万恶之源,能不用就不用。可以选择的话,我主要用Winform, Flex,SL作为前端。纯Web开发是不碰了(市面上做Web开发的太多,不趟这个混水了)。

以上架构,视项目而定。如果项目的数据部分比较关键,我现在还是保守的在用关系数据库。虽然db4o已经那么多年了,还是得保守一点用。

如果能完全按上面五点去做,那开发简直和在空中飞翔一样爽。

btw. 如果一切都OO起来,写程序真是享受,象写诗一样……

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值