zoukankan      html  css  js  c++  java
  • 一道笔试题和UML思想 ~

    一句软件工程界的名言,让我想起了一个和一道笔试题有关的故事。希望更多的人了解 UML 背后的思想比他的语法更重要,是笔者写作本文的一点小愿望。

    一、从一句软件工程名言说起

      对很多事情的处理上,东西方都大相径庭。究其根底,往往是东西方文化的差异使然。 “ 有工具的傻子还是傻子!( A Fool with a Tool is Still a Fool! ) ” 这句在软件工程界颇为有名的话,就体现了西方人说话不大客气的特点。作为中国人,您可能不大喜欢这句话的表达方式,但其内容的正确性是不容置疑的 —— 他强调了工具背后的思想才是最重要的。

      UML 作为 OMG 组织认可的一种标准化的可视化建模语言,近年来在国内外软件界很盛行 —— 相关的书籍不可谓不多,学习和使用 UML 的人不可谓不众。但是,笔者发现不少人犯了买椟还珠的毛病 —— 他们忘记了 UML 只是我们表达建模思想的工具,其背后的思想才是最重要的。

    二、一道笔试题的故事

    这道笔试题是这样的:

    写出下列程式的运行结果: 

     

    复制代码
        public class Test
        
    {
            
    static void Main(string[] args) 
            
    {
                Child child 
    = new Child();
            }

        }


        
    class Parent
        
    {
            
    public Parent()
            
    {
                Console.WriteLine(
    "to construct Parent.");
            }

        }


        
    class Child : Parent
        
    {
            
    public Child()
            
    {
                Console.WriteLine(
    "to construct Child.");
            }


            Delegatee delegatee 
    = new Delegatee();
        }


        
    class Delegatee
        
    {
            
    public Delegatee()
            
    {
                Console.WriteLine(
    "to construct Delegatee.");
            }

        }
    复制代码

     

    这道题很简单,就是考构造函数的执行顺序,输出结果如下:

    to construct Delegatee. 
    to construct Parent. 
    to construct Child.

    然而,应试者没有写出程式运行结果,倒是画了一张类图出来:

    我问他:“您画的类图很好,用 UML 几年了?”

    他说:“ 2 年多了。”

    我说:“为什么不写程式运行结果呢?太简单了吗?”

    他嘿嘿一笑,说:“这道题考的是构造函数的执行,我记不大清了。”

    我说:“构造一个类时,他的父类和成员变量所属类的构造函数都会被自动执行,具体顺序是先 Parent 后 Delegatee 最后 Child ,是吧?”

    他说:“对对对。但是,我不喜欢这些细节性的东西,还是图像化的类图更能表达程式的思想。”

    我说:“是呀,那么请您谈谈这个简单的类图中的思想好吗?”

    他无言。

    三、 UML 背后的思想

      真是可惜,我本以为他会说出上面类图中的依赖思想呢。 UML 图里真的充满了思想,哪怕是上面那个如此简单的类图!

    1、 继承的箭头为何指向父类

      相信至今更有人会画出类似下面的类图,小小的一个错误却叫人不禁扼腕!其实,大师们把继承的箭头方向规定为指向父类,是有深刻的设计思想的——他代表了依赖的方向!

      举个著名的面向对象原则——依赖倒置原则——的例子吧。依赖倒置原则( Dependency-Inversion Principle )规定:抽象不应依赖于细节,细节应该依赖于抽象。本原则几乎就是软件设计的正本清源之道。因为人解决问题的思考过程是先抽象后具体,从笼统到细节的,所以我们先生产出的势必是抽象程度比较高的实体,而后才是更加细节化的实体。于是,“细节依赖于抽象”就意味着后来的依赖于先前的,这是自然而然的重用之道。而且,抽象的实体代表着笼而统之的认识,人们总是比较容易正确认识他们,而且他们本身也是不易变的,依赖于他们是安全的。依赖倒置原则适应了人类认识过程的规律,是面向对象设计的标志所在。

      下图是著名的观察者模式的一个变体,我们研究一下这个例子中的继承关系。 Braodcaster 和 Listener 是 Framework 层的两个类,负责完成我们在研发的前期就抽象出来的“订阅-通知”机制。而 ConcreteBroadcaster 和 ConcreteListener 是使用“订阅-通知”机制的类,是通过继承实现的。显而易见,依赖倒置原则规定的“细节依赖于抽象”,在这里表现为“继承的箭头从子类指向父类”。

    2 、回到笔试题

      其实,构造函数的执行顺序,何尝不是唯“依赖关系”马首是瞻呢?具体而言,就是“被依赖的先构造,依赖于人的后构造”。唯一可能的猫腻是:“跨层依赖”优先于“同层依赖”构造,如下图所示。

    3、 买椟还珠

      春秋时代,楚国有一个商人,专门卖珠宝的,有一次他到齐国去兜售珠宝,为了生意好,珠宝畅销起见,特地用名贵的木料,造成许多小盒子,把盒子雕刻装饰得很精致美观,使盒子会发出一种香味,然后把珠宝装在盒子里面。有一个郑国人,看见装宝珠的盒子既精致又美观,问明了价钱后,就买了一个,打开盒子,把里面的宝物拿出来,退还给珠宝商。

      呜呼,买椟还珠的故事在我们身边重演,可惜呀!

  • 相关阅读:
    信息化与信息系统4
    信息化与信息系统3
    信息化与信息系统2
    信息化与信息系统1
    ASP.NET Core教程:ASP.NET Core 程序部署到Windows系统
    C#几种单例模式
    SQL查询优化
    动态类型dynamic(ExpandoObject)
    PV(访问量)、UV(独立访客)、IP(独立IP)
    Spring Boot 2.配置
  • 原文地址:https://www.cnblogs.com/gates/p/3408749.html
Copyright © 2011-2022 走看看