zoukankan      html  css  js  c++  java
  • 一个简单的领域模型的建模过程

    一个简单的领域模型的建模过程

    系统需求来源于一套大型系统的一小部分。
    基本需求是:
    用户选择图片文件,系统一系列验证(文件大小,数量,格式等)后,压缩,发送。
    并记录发送结果。
    通过需求分析得知,这个用例里面,除了用户需要向系统输入文件外,
    剩下的工作都是系统来做,系统要经过一系列的步骤来完成指定任务。
    所以这是一个工作流的问题,我们得到下面这个模型:

    这是维持一个指向自身的链,通过Next可以访问链中的下一个节点。

    其代码的实现大致如下:

    复制代码
     public abstract class Processer
        {
            protected Processer next;
            protected abstract bool process();
            private List<Image> images;
    public void Run() { bool r = process(); if (next != null) { if (r == true) { next.Run(); } } } }
    复制代码

    这只是建模了一个链的模型,下面是根据我们的需求添加具体的链节点,通过需求描述发现,我们需要“验证”、“压缩”、“发送”等具体的处理。所以模型应该是这样:

    我们从一个链模型继承了三个具体的链节点,用来处理“检查”、“压缩”、“发送”的具体工作。从模型上我们能看出来,当需要新的处理要求出现时,我们仅需要继承一个新的处理节点,比如发送前需要“加密”,那么我们进需要在继承一个新的类:encryptor即可。

    其实真正的系统中还有一个必须添加到节点,那就是处理持久化的相关工作。我们应该再继承一个新的类:DBAccesser。

    通过分析我们发现,我们的这一设计在增加处理链的方向上满足了OCP原则。
    作为一个设计洁癖(当然这不是一个好习惯)者,我发现Checker类有一些另我不安。
    因为他一个人干了好几件事儿(大小检查,数量检查,格式检查),那么如果增加新的检查项目,势必需要修改Checker类,这不符合我刚刚提到的OCP原则。所以我决定把Checker的职责分开,得到下面的模型。

    这样增加新的检查类型,只需要继承新的Checker即可,这又一次符合了OCP。
    上面的模型暂时看一切顺利,那么下一步就是考虑一下UI的问题了。
    我们重点考虑一下处理结果向UI反馈的问题。因为链是封闭式处理的,每个链节点处理的结果如果反馈给UI呢?最简单的方法就是每个节点都生成一个记录处理结果的对象,模型如下:

    这是一个简单而直接的设计。当然正在的项目这么做也许就足够了。理论上细究起来,他存在一个问题,就是UI代码直接依赖于CheckerResult,CompressResult,SendResult这些具体的类,这样的设计不符合DIP原则,最直接的影响就是如果新追加节点,比如Encryptor,这个节点会产生一个处理结果对象,类型为:EncryptResult,UI为了反映这一个节点的处理结果。需要手动更改代码以添加对EncryptResult类的对象的访问。

    老办法,看看添加一个接口好不好用:

    通过添加一个IResult接口,这样每一个节点下的蛋(处理结果)都是同一类型了,在ResultProcessor类里可以统一处理每个节点的处理结果。

    如果在进一步,可以把ResultProcessor变成一个接口,由具体的类来做具体的处理工作。

    上面的模型看上去完全符合OCP,DIP,SRP这上个主要的设计原则。只是在创建处理链的代码中,可能有些不爽,
    这个简单,抽象工厂好了,世人皆知的处理方法:

    题外话,如何才能产生一个好的设计呢,其实我也不知道。但是最起码的两点:

    1.掌握基本的设计方法,平时多思考多总结。
    2.分离职责。

    我不建议一上来照搬各种设计模式,设计模式只是某个场景下的优美设计方案,并不是放之四海皆准的灵丹妙药。

    即使使用了设计模式,你也要看交流电对象,对于熟练掌握设计模式的人来说,模式可以作为通用词汇,用于方便快速准确的交流设计思想,
    对于不懂模式的人来说,简直是对牛弹琴,甚至可以能引起对方的反感,

    其实这个不成熟的设计方案中,我运用了:职责链模式,模板方法模式,桥接模式,抽象工厂模式,适配器模式。试着找找看…

     
     
    分类: 领域建模
  • 相关阅读:
    SQL 行转列查询汇总
    c#中的委托是什么,事件是不是一种委托
    添加动画(两种)
    Follow 在地图中使地图和人物一起运动
    动作加速度Speed
    动作回调函数 (CallFunc,CallFuncN,CCCallFuncND)
    精灵沿着正方形路线运动暂停2秒后然后再将自己放大4倍
    CardinalSpline样条曲线(沿着正方形路线走)
    cocos2dx 3.2 Scale9Sprite点九图
    Label(标签)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2870791.html
Copyright © 2011-2022 走看看