可实现的是架构,空谈是概念 So don't tell me the concepts show me the code!  “不懂编码的架构师不是好架构师” 好架构师都是超级代码控。

 

代码是最好的老师

 
从代码中学习设计的思想、方法是提升类库设计能力、印证你所了解的概念与理论这就是架构师看代码的观点。
 

基本准备

一个类库可能有数千个类上万个方法,应该如何去看呢? 在看代码前我们需要进行一些什么样的准备呢 ?
 
  • 设计模式 - 最标准的23种设计模式基本上要有一个了解,可能一下子不能理解他们的用法,但一定要记下他们的英文名字和基本的用途,如:Factory, Wrapper (Decorator), Command,  Builder等 。
  • 语言规范 - 熟读语言本身的官方编码规范与命名规则,这是共同的标准,也是从官方得到写代码的第一指导。
  • 要看懂UML中对类的图形表示方法(类、接口、抽象类、继承关系、使用关系)
 

看代码的方法

这里所提供的方法就先以C#作为语言基础,因为C#有极为规范的的语法规则。.net 的文档在类库方面的文档是最完整也是最易读的。以.net framework作为起点会是一个很好的练习入口。在开始前我还推荐一下大家需要有一个反编译工具我用的是.NET Reflector, 用反编译工具不是让你去抄代码(代码本身是没有多大价值的,价值的核心在于设计)而是可以更深入地了解到代码是怎样实现的。用反编译工具看微软的代码会看到很多的不同的,你会发现大最设计得非常有意思的内部类 (Internal) 。从中大至可以推断出微软的开发方法,“在外部接口完全一至的情况下,让程序员编写的自由度最大边界就是内部类与内部方法” 你可以马上动手先看看 System.Web.Mvc.dll 的实现
 
要点:多问为什么,带着问题看代码——为什么这样写(存在理由)?为什么这样设计(出发点)? 由你来写又将如何实现?
 

看命名

    以面向对象的语言为例,大多会在名字内带有具体的用法信息,从名称推算可能使用的模式及实现
 
带有模式印记的类:
  • TagBuilder - 以Builder模式实现的Html标记的构建器
  • StringBuilder - 以Builder模式实现的字符串构造建器
  • XXXXWriter - 以构建器模式实现的各种写入器
  • ConnectionFactory - 数据库连接对象构造工厂
 
XXX+模式名 是惯用的对模式类的一种命名规则
 
找到了模式实现如果你看不懂,那恭喜你这就是学习的机会到了,马上翻开设计模式与实现类进行对照印证,这个过程可以加速模式在你大脑中的印象与加深理解。(模式是架构师的大杀招,能不能上档次就看对模式的理解与认识了,一有机会就应该学)
 
 
带有家族印记的类:
 
XXX+Base - 抽象类
基类名+XXX - 某抽象类的子类 
 
是继承关系一种常见的命名规则。
 
注:每一种基础语言会有自身的命名规则,所以必须对官方提供的命名规则烂熟于胸,既可以学习别人怎么写代码也可以规范自己的代码写法。
 
 做完这两个练习基本上你可以在不看 Classes References(类手册)的情况下一下子了解一大堆类的存在与用法。
 

看接口

   接口在设计中有着极为重要的地位,结构再复杂的系统到了接口级别基本上都会很简单。而且也是判定这个类库设计是否成熟的一种标准。接口与接口间的定义就定义整个系统的基本框架。看接口的最基本意义就是深入理解类库设计者的设计思路与了解类库最核心的能力。
 
这里我们以 IRepository 为例来讲讲怎么去看接口 (如果想深入了解IRepostiory的朋友可以阅读我之前的文章:“Repository模式与UnitOfWorks模式的运用” )
我以 IRepository 为例是因为它的共识度很大,而实现起来可以很庞大也可以很小,众所周知IRepository提供的就是对某个实体的CURD(增加、更新、读取、删除)的一个接口。那么当我们看到它的存在时,应该可以推断出另一个接口:IUnitOfWork 因为它们往往会是孪生兄弟般的存在,再进一步推断是否会存在IRepositoryFactory 和 IUnitOfWorkBuilder 呢? 那么就可以带着这些问题在类库中找答案。    
 
通过IRepository我会可能会发现一大堆的Repository类,
如抽象类:EntityRepositoryBase, FiledRepositoryBase ,JSONRepositoryBase 等
具体类:BlogRepository, PostRepository, UserRepository 等
 
 
注:作为练习大家可以去下载我在NuGet上发布的一个名为 DotNetAge Document Storage 类库,里面就有Repository的实现
 
一但掌握了从接口看结构的方法,就可以快速地在无文档的情况下理解类库的核心与设计理念。
 

参考“最佳实践”

      一般上来说,流行的语言都会提供官方的“最佳实践”提供下载学习。这是一个必修项目,同一个需求,我们可以采用各种的设计方法来实现,但哪一种最好的? “最佳实践”就提供了方法选择的指导。“最佳实践”会有大量文档辅助讲解,在此时使用上述两个方法去学习那将会更大地提高你在设计上的提升。
 
随着不断的积累与大量的代码阅历,你可能就会得到这样一种能力:随便拿个Dll,在一个短时间内你可以如数家珍般说出整个Dll中的特点与功能。
 
这,就是“看”的练习方法,与练习后的效果
 

 要成为架构师就需要突破语言的障壁,不同的语言有不同的优势,设计应该是因势利导,好的架构可用任何语言实现,反过来优秀的架构则应尽可能地发挥语言的特性。应用此方法前首先你至少已掌握或精通一门语言。
  

学习多种语言的动机

  • 开拓视野,从不同语言中学习特有的设计理念
  • 寻找与更新自己的 “最佳实践”
  • 规避语言被淘汰的风险
 

开拓视野

    我最近在不少网站上看到这样的一种论调:“学语言只学一门就好,不需要多只需要精”。咋一看,似乎是对的,而我认为仅限于初学者或不求进取者。这是一种语言同质论,是一种误导与限制!如果学习语言能“窥一斑而见全豹”那就不需要有那么多的其它语言存在了,对吗? 
    当对某一门语言精通(我指的是精通类库而不是语法)后,这个时间大概也得几年,很容易进入到一种“思维定式”,以某种固定语言为基点想问题,或是设计。一旦进入这种状态也就意味着局限性的出现,程序员或是架构师就被限制在了一个局部的小范围,而且还是风险极高的范围内。
    IT的发展是飞速的,今天的宠儿明天的乞丐这种剧目屡屡上演着,你愿意被大浪淘沙吗?吊在一颗树上真是一条死路,这是技术发展的风险层面。又,你的设计工作对你还有挑战性吗?你是否仍然对设计和开发充满激情?你的设计是否在当下可以有什么让你自豪的特色或创建呢? 被同质化后这些答案都会被否定掉。 
   

我的论点是:不断学习各种语言,体验各种语言所带来的开发与设计的激情,开拓自我的视野才是一个架构师应走的路。架构师不单单是技术的选择者,而更应该是技术的整合者。

 

选择“最佳实践”

 
   我们长期会在某一领域内工作,自然而然会诞生出对此领域内的软件的设计理念与实现方法。但这仅是一种,举一个最简单的例子,同一个网站我们可以用ASP.NET MVC , Java, PHP 或是NodeJS来实现,固然实现方法与代码量就截然不同了。随便写个博客网站就能体验他们的区别所在:
 
  • ASP.NET 和 Java的思维方式与代码量差异不大,学习曲线最长、 Hosting 资源成本中等,但数据库Hosting成本高
  • Php 相对前两者简单而且资源众多,Hosting 资源最多,成本最低
  • NodeJS性能最高、学习曲线最短、代码量最少、资源也最多但Hosting 成本最高
 
从这个比较中可见,作为架构师不单要考虑设计方法与实现,还得考虑部署环境。如果只是某一方面的“能手”那只能干瞪眼,无可选择。
 
我不是要选择“最好”的而是要选择“最合适”的,因时制宜,因地制宜才是我们所需要的“最佳实践”
 
 

成为 “O” 型架构师

 开发是一个团队共同完成的,与真实社会一样,活在哪里就说哪里的话才会深入了解对方的文化。 架构师不是一个独立的个体,而是团队中不可或缺的成员,在行政与地位上与其它成员是对等的。开发队团就像是一个人,流着共同的血液。一个架构师,一份设计就应该是一种“O”型血,无论在哪个队团内都能融合,使用哪种语言都能实现与优化这才是一个好架构师的目标。
 
 

学习多种语言的方法

 学习语言的方法大家都会有各自的路径与方法,在这里我只是介绍一下我自己的学习方法仅供大家参考与给我建议。我从业也10多年了,经历了不少语言以下这些是一些记忆与状态:
 
  • Delphi (1-5) (Object pascal) - 这是初恋 , 拥有最多的界面组件和最简单的可视化开发环境,VCL算是当时最好的选择。
  • VB (2-6) - 最容易调用COM的语言也是做面向对象很苦B的一个了。
  • C++ - 学得最差的
  • java - 用来学面向对象的
  • C# - 算是我最擅长的,也是做项目最多的
  • Php - 只能算是懂一点
  • javascript - 我最喜欢的动态弱类型语言。
  • css/less - 最让我头疼 (有了Less会好一点)
  • html/xml/xslt - 最容易建立方法论的标记性语言是最容易建立发散性思维与抽象思维的工具
  • Objective-C 和 Swift - 现在在学的
 
 
每一种语言就像自己的女朋友一般天天在身边陪伴着我们,所以想学得快首先是爱上她。即使她不再受宠也她会给我们留下很多美好的记忆。
 

感性认知

   我学语言的第一步是不看语法的,因为面向对象的语言语法上基本是相似的,而且语法参考会很长读起来慢(这跟找老婆不要光看外貌是一个理)。我是从类库入手的,从主打的类库中可基本上快速了解整个语言的重要特色和常用的内容。就如iOS吧,一入手我会先看Cococa Layer中的UIKit,花两小时看完就知道XCode怎么用了然后就可以做个简单的移动应用跑一下,从感性上互相认识一下。
 

相互印证

   没有哪个语言是没有参照物凭空发明出来的,就像学java时如果学过c++会很快因为java就是在极大层面上改进C++而来的,学C#的时候学过java就一下能上手,因为C#是微软没买到java自己搞出来的同时也去改进了java。所以语言之间会有互通性存在,在学习的路径上可以先了前他们的前辈是谁,有什么特色通过双向的印证了解可以很快速地去掌握与深入理解一门语言。
 

长年的积累

    掌握一门语法很快,精通一门语言就是硬功了。这和我们学自然语言一样,词汇量是日积月累的成果。开发语言的词汇量就在于类库了,每一门语言的标准类库也是够我们喝一壶的,需要实践、学习与理解结合经验沉淀成我们的成果。在这方面我给出的建议就是要培养自己的耐心与毅力,罗马不是一天建成的,高手也不是一天就能修炼出来的。除了掌握官方类库还得将业界流行的类库和框架都能了解与熟悉这才算是“精通”。
 
 
 

写 - 疯狂的编码

 
“实践是检验真理的唯一标准” 能说不如能写。学到的知识是别人看不到的内容,作为程序员或是架构师将脑中的精华程序化呈现,然后成为产品这才是我们的终极目标。
 
学会一门语言并不代表写得好,作为一名架构师写的代码要求更是不同:
  • 易读 - 命名是否符合代码规范,所有接口是否全部代码都有注释
  • 易用 - 每一个类,每一个方法都是架构师与程序员的UI,少参数,容易理解的设计可以大大减少沟通成本。
  • 框架化 - 一个一个类写是很慢的事,要活用模式于代码中能同时构建出10几个或几十个类。
  • 参考性 - 架构师不是程序员,写代码为的是固定核心功能与公共用法,便于成员开发。面对复杂的场景需要多写示例同时也是测试设计的易用性的方法。
 
怎么才能达到这样的标准呢?
  • 为自己立项从现在起为自己而编码
  • 多写代码片 - 对局部的理论进行实践,多写一些小的代码片段或实验程序,而按正式项目一样来对待。完整的记录,共享源码获得Feedback,有良好的注释。
  • 模仿是学习与理解新事物的最佳捷径 — 可以去仿造某些项目,当深入其中可以更直接地理解设计者的最初设计想法,同时也可以得到一个仿造品(不是抄,仿造的目的是获得编码经验)
  • 尝试使用模式并控制类的规模
 
最后也就是时间的积累,疯狂地编码。同样的时间一个架构师的编码能力至少需要同等于五个以上程序员同时编码。

小结

架构师之路是一条很漫长而且需要不断学习、思考与实践积累的道路。我只是走了这条路的一小段,以此总结与更多的朋友分享共勉。在下一篇文章中我将会从另一个角度来谈架构师的修改项目:表达力。希望有兴趣的朋友能给予更多的关注与反馈。

 

架构师修练 I - 超级代码控的更多相关文章

  1. .NET 云原生架构师训练营(权限系统 代码实现 ActionAccess)--学习笔记

    目录 开发任务 代码实现 开发任务 DotNetNB.Security.Core:定义 core,models,Istore:实现 default memory store DotNetNB.Secu ...

  2. .NET 云原生架构师训练营(权限系统 代码实现 EntityAccess)--学习笔记

    目录 开发任务 代码实现 开发任务 DotNetNB.Security.Core:定义 core,models,Istore:实现 default memory store DotNetNB.Secu ...

  3. .NET 云原生架构师训练营(权限系统 代码实现 Store.EntityFramework)--学习笔记

    目录 开发任务 代码实现 开发任务 DotNetNB.Security.Core:定义 core,models,Istore:实现 default memory store DotNetNB.Secu ...

  4. .NET 云原生架构师训练营(权限系统 代码实现 Identity)--学习笔记

    目录 开发任务 代码实现 开发任务 DotNetNB.Security.Core:定义 core,models,Istore:实现 default memory store DotNetNB.Secu ...

  5. .NET 云原生架构师训练营(权限系统 代码实现 WebApplication)--学习笔记

    目录 开发任务 代码实现 开发任务 DotNetNB.Security.Core:定义 core,models,Istore:实现 default memory store DotNetNB.WebA ...

  6. .NET 云原生架构师训练营(权限系统 代码重构)--学习笔记

    目录 模块拆分 代码重构 模块拆分 代码重构 AuthenticationController PermissionController IAuthorizationMiddlewareResultH ...

  7. 架构师修炼 II - 表达思维与驾驭方法论

    开篇之前我想先说说当年开发的那点事儿:大约10年前吧,我还是一个程序员的时候经常都是遇到这样的项目开发流程: 解决方案 :满足客户目的和投标用的一堆文档(不少还是互联网上抄的) ,是以Word为主的纯 ...

  8. IT架构师介绍-软件架构设计学习第一天(非原创)

    文章大纲 一.架构师定义二.架构师分类与具备能力三.研发人员发展的技术路线四.架构师知识体系五.参考文章   一.架构师定义   什么是架构师,这个聊架构话题时永恒的问题.每个公司对架构师的定位也有所 ...

  9. iOS架构师之路:控制器(View Controller)瘦身设计

    前言 古老的MVC架构是容易被iOS开发者理解和接受的设计模式,但是由于iOS开发的项目功能越来越负责庞大,项目代码也随之不断壮大,MVC的模糊定义导致我们的业务开发工程师很容易把大量的代码写到视图控 ...

随机推荐

  1. 对EJB2.1几种接口的认识

    因为教学上的需要,重新梳理了下EJB几种接口的职能,讲的是EJB3,虽然按照课件也能做出一个运行良好的EJB程序来,但是要想比较好的理解EJB3的工作原理,只知道这些注解还是不够的,特别是涉及到的接口 ...

  2. MySQL优化之Explain命令解读,optimizer_trace

    简述: explain为mysql提供语句的执行计划信息.可以应用在select.delete.insert.update和place语句上.explain的执行计划,只是作为语句执行过程的一个参考, ...

  3. pycharm的放大和缩小字体的显示 和ubunt的截圖工具使用 ubuntu上安装qq微信等工具

    https://www.cnblogs.com/sui776265233/p/9322074.html#_label0 ubuntu: 截圖工具的使用 在ubuntu 10.04 的时候,还可以很方便 ...

  4. etc/skel目录介绍

    /etc/skel目录的作用: /etc/skel目录是用来存放新用户配置文件的目录,当我们添加新用户时,这个目录下的所有文件会自动被复制到新添加的用户家目录下,默认情况下,/etc/skel 目录下 ...

  5. linux开机步骤

    linux开机启动步骤: 1.bios自检 2.MBR引导 3.引导系统,进入grub菜单 4.加载内核kernel 5.运行第一个进程init 6.读取/etc/inittab 读取运行级别 7.读 ...

  6. 第 14 章 结构和其他数据形式(伸缩型数组成员C99)

    伸缩型数组成员C99 声明一个伸缩型数组成员的规则: 1.伸缩型数组成员必须是结构的最后一个成员: 2.结构中必须至少有一个成员: 3.伸缩数组的方括号是空的. 示例 struct flex { in ...

  7. 题解 P2701 【[USACO5.3]巨大的牛棚Big Barn】

    题面 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚. 他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方. 我们假定,他的农场划分成 N x N 的方格.输入数据中包括有树的 ...

  8. SDN期末作业-通过SDN的应用实现负载均衡

    负载均衡程序 1.程序链接:https://github.com/424baopu/software/tree/master/LoadBalance 2.场景 topo: 场景描述: 服务器host ...

  9. Tomcat设置虚拟目录的方法, 不修改server.xm

    所在小组使用的就是这样的形式开发,这样切换开发环境,测试环境,正式环境就只需要修改project.xml文件就行了.project.xml命名是随意的,访问的时候就使用这个名字来访问. 在tomcat ...

  10. Netty入门(九)空闲连接以及超时

    检测空闲连接和超时是为了及时释放资源.常见的方法是发送消息来测试一个不活跃的连接,通常称为“心跳”. Netty 提供了几个 ChannelHandler 来实现此目的,如下: 下面是 IdleSta ...