架构超能特训连

口号

目标人群

⚠ 警告:

❤️ 收获

🎒 预备知识

🔧 预备工具

课程介绍

这正是本课程要分享和探讨的问题。

我们调查发现,很多软件企业特别是中小企业根本就没有架构师这个职位;有部分软件公司可能有架构师,架构师却没有真正承担架构设计这一职能。

这种职位或职能的缺失对公司会有什么影响呢?

代码内部质量管理的缺失

商业软件需要良好的代码质量。代码质量有两类:代码实现客户需求,从而表现为软件外在的功能,我们称之为外部质量;另外一类,代码设计,系统架构关系到软件一致性,健壮性,我们称之为内部质量,这些东西不会直接影响到软件功能,却会影响软件的维护和发展。 作为公司的管理层,关心内部质量多与外部质量。外部质量已经有项目经理,测试人员乃至客户都在时刻盯着;而内部质量却几乎是个空白。架构师就是扛起这个这个责任的主角,这个空白就体现了架构职能的缺失。

团队开发指导的缺失

一个团队应该用什么样统一的代码风格;什么是目前开发技术的最佳实践;团队当前所使用的架构有应该使用哪些最佳实践的子集。 作为第一线的开发人员,这些问题是不可能自行解决的。架构师的缺失就造成这些方面的混乱。各自为阵的开发人员“共享”自己的解决方案,最后软件系统形成一个庞大而混合体,反过来带个开发人员更大的痛苦。

架构师是与程序开发员完全不同的职业吗 (TODO:淹没)

架构师从初级、中级、高级程序员,一路走过来的另一个职业层面。不是完全等同程序员,也不能完全隔离他们之间的联系。架构设计的技能在作为程序员时,也是需要用到,从而得到磨练和提高的。不可想象,一个程序员从来不曾关心和应用架构设计,只是在熟练编程十年之后,一夜之间变成一个架构师。

本课程分四部分,称之为四大乐章。循序渐进诠释一个优雅软件架构的炼成。

🎵 第一乐章《初识》

从语法层面出发,使用大量小代码片段,邀请学员参与写出传统代码,然后解析传统代码的弊病,同时引入优雅代码的风格。从而,变代(密)码为自然语言,展现一个全新的代码世界。这是一个可以立即实现也应用的技能,很大程度上可以减轻一线开发人员读写代码的恐惧感和厌倦感(TODO:从调查中找到合适的描述)。同时,这种方式也是为后面良好架构的一个有力支持,是代码即文档的基石,也是对需求描述的最遥远的呼应。

🎵 第二乐章《缚茧》

我们之前的开发经验是一个厚重的茧,束缚了我们的能力,束缚了我们的想象力。 给出一个真实的需求案例:《考官抽签系统》,同样要求学员试图给出他们的代码实现。对他们代码进行审查和分析。

痛点

通过对代码的分析,引出现在一线开发人员、架构师和公司技术管理层的痛点(TODO:列出这些痛点)。各种各样的痛,来源于我们思维上的局限性,我们已有的经验变成了一个厚重的茧,束缚了我们的能力,束缚了我们的想象力。

架构师的缺失

没有人对架构设计负责,这种情况不是说软件没有架构,它仍然有一个自然的结构,这种场景的弊病在于,这时候的软件架构是自然形成的,是各自为阵的开发人员甚至是开发小团队架构设计的简单混合,因而是无序的, 不一致的,不可控的。

架构职能的缺失

我们看到更多的公司情况是,他们设置了架构师这个岗位,可是这个架构师只是一个超能开发人员,大家把他当作一个无所不能、精力无限的超人。这种情况,我把他看作是架构职能的缺失。不会比上一个情况好多少,甚至更糟。一方面,架构师本人疲惫不堪,四处救火,而开发人员还不支持;另一方面,其它开发人员又觉得被关的很死,没有设计的自由和动力。

目前对架构的认识
期待一种解决方案

🎵 第三乐章 《涅槃》

从优雅代码到架构优雅的升华,类似也有旧思维的突破和新思维的建立。这个过程是痛苦的,如同凤凰涅磐,但只有会有一个重生。

这个乐章痛过对实际案例《考官抽签系统》的全新实现,一步一步诠释正交设计,测试驱动开发和良好架构的炼成。用实际的代码展示抽象的架构,架构并不难。

🎵第四乐章 《化蝶》

全面介绍一个基于DDD的实际项目结构。自主开发实现的框架,综合使用和实现了IOC, MVC和Repository。 展示一个真实项目的开发全过程:需求收集,任务提交,冲刺划分,代码实现,修改提交,自动集成,回归测试,系统发布,任务完成,燃尽图的展示。

一个完整的项目结构和流畅的开发流程,展现涅槃再生之美。

🎵 第一乐章 初识

自然语法:高大上的业务领域语言(DSL)的简单实现 (50分钟)

.Net Extension改变代码风格 (25分钟)

案例1:
写一段程序生成IEnumerable<int>对象,让它包含1到10的数字。

Fluent Interface 和DSL (25分钟)

案例2:
写一段程序实例化多层次业务对象
计算机: Lenovo
    CPU: i5
    硬盘:
        品牌:希捷
        类型:机械硬盘
        容量:500G
    内存:4G

简约:代码噪音与魔幻代码 (25分钟)

注释(10分钟)

案例3:
要求听众给出一个需要有注释的案例。
我自己的案例:
*******

命名:用实现命名 PK 业务价值命名 (10分钟)

案例4:
要求听众给出方法的命名。
我自己的案例(龙登攀):
...扣钱,钱不够,把钱分两部分...

####实例:多个参数的问题 (魔数)(5分钟) 案例4: 定义: void do(int arg1, int arg2, int arg3) 调用: do(1,3,5) 怎么知道每一个参数是做什么用的。虽然不是代码噪音,却是魔幻代码

苹果园的优雅之旅

案例5: 苹果的挑选:集合的查询

    public class YourClass
    {
        public int Property1 {get;set}
        public string Property2 {get;set;}
        public string Property3 {get;set;}
    }

今年圣诞流行苹果,

    public class Apple
    {
        public int Size {get;set;}
        public Color Color {get;set;}
        public decimal Weight {get;set;}

    }

怎么样挑选好苹果? 需求:

代码,密码?5分钟

我给出的第一个版本:

public class TraditionalPicker
{
    public IEnumerable<Apple> pick(IEnumerable<Apple> source)
    {
        var result = new List<Apple>();
        foreach (Apple apple in source)
        {
            if (apple.Color == Color.Bright)
            {
                if (apple.Size >= 3 && apple.Size <= 5)
                {    
                    if (apple.Weight > 50)
                   {
                           result.Add(apple);
                   }
                }
            }
        }
        return result;
    }
}

版本二

public class TraditionalPicker
{
    public IEnumerable<Apple> pick(IEnumerable<Apple> source)
    {
        var result = new List<Apple>();
        foreach (Apple apple in source)
        {
            if ( apple.Color == Color.Bright  &&  apple.Size >= 3 && apple.Size <= 5 && apple.Weight > 50)                       
               result.Add(apple); 
        }
        return result;
    }
}
简约 5分钟
public class SlightImprovePicker
{
    public IEnumerable<Apple> pick(IEnumerable<Apple> source)
    {
        var result = new List<Apple>();
        foreach (Apple apple in source)
        {
            if (apple.Color != Color.Bright) continue;
               if (apple.Size <3 || apple.Size > 5) continue;
            if (apple.Weight <50 ) continue;
            result.Add(apple);
        }
        return result;
    }
}
代码要表达业务知识

💭 思考5分钟甚至试着实现,如何解构以上代码,让代码:

0. 更单元化
0. 更能表达业务
用注释来传达业务知识

注释:💭如果要写注释,你会如何写 5分钟

public class SlightImprovePicker
{
    public IEnumerable<Apple> pick(IEnumerable<Apple> source)
    {
        var result = new List<Apple>();
        foreach (Apple apple in source)
        {
            /// 剔除颜色不鲜艳 filter not bright 
            if (apple.Color != Color.Bright) continue;
            /// 剔除大小不适中 filter not proper size 
            if (apple.Size <3 || apple.Size > 5) continue;
            ///剔除不够分量 filter not heavy
            if (apple.Weight <50 ) continue;
            result.Add(apple);
        }
        return result;
    }
}
用代码本身来传达业务知识

我们的口号:代码即注释,为什么不这么写:提炼出一个方法替代注释。 5分钟

[FriendlyName("颜色不鲜艳")]
bool not_bright(Apple apple)
{
    return apple.Color != Color.Bright
}
...

public class SlightImprovePicker
{
    public IEnumerable<Apple> pick(IEnumerable<Apple> source)
    {
        var result = new List<Apple>();
        foreach (Apple apple in source)
        {
            if (not_bright(apple)) continue;
            if (not_proper_size(apple)) continue;
            if (not_heavy(apple) ) continue;
            result.Add(apple);
        }
        return result;
    }
}

来一次飞跃,单项挑选独立成一个类

[FriendlyName("挑取颜色鲜艳")]
public class BrightColorPicker
{
    public IEnumerable<Apple> pick(IEnumerable<Apple> source)
    {
        var result = new List<Apple>();
        foreach (Apple apple in source)
         {
             if (apple.Color == Color.Bright)
             {
                 result.Add(apple);
             }
         }
        return result;
    }
}

那么,原来的主类就变成:

public class GroupProcessor
{
    public IEnumerable<Apple> pick(IEnumerable<Apple> source)
    {
        var result =
            new BrightColorPicker().pick(
                   new ProperSizePicker().pick(
                        new HeavyPicker().pick(source)
                    )
                )
            );
        return result;
    }
}
得墨忒耳定律 (Law of Demeter)又称:最少知识原则

为了避免将一个客户端同间接对象发生信息耦合和避免直接对象的内部描述。 直接对象是一个客户端的“常客”,间接对象是“陌生人”,并且一个客户端只需要同常客对话而不需要同陌生人对话。执行这些限制意味着直接对象可能需要新的操作来完成中间者的操作。

DDD:业务域建模是解决噪音与魔幻的根本之道
完全可以独立成一个话题

🎵 第二乐章 缚茧

正交设计

抽签规则

🎵 第三乐章 涅槃

DSL

测试即文档

行为测试驱动

对象的状态 vs 对象的行为

( 本文版权属于© 2015 卓逸天成 | 转载请注明作者和出处:卓逸知识文库 http://kb.skight.com )