zoukankan      html  css  js  c++  java
  • Veil框架设计理念

    项目地址:http://github.com/honovation/veil

    做为框架:改不改得动是检验一切架构的唯一标准

    我们认为框架不仅仅是为了节省开发人员的时间,能够让你五分钟写一个博客系统。更重要的是给应用程序的逻辑提供一个组织的方式。因为我们知道,软件开发就是管理复杂度的艺术。管理好软件业务逻辑的复杂度,就需要代码有一个良好的组织。这么多年来,人们总结出来的金玉良言就是“高内聚,低耦合”的模块化设计方式。Veil框架仅仅是我们对于践行模块化设计的一个努力和尝试。

    模块化设计并不是一个新概念。甚至C的module也可以称自己为模块化。Veil的特点在于彻底的模块化,比如有的时候我们会把东西放到不同的地方

    • 安装程序如果是集中管理的,那么每个模块的一部分实现还是要外泄到安装程序里
    • 运行脚本如果时集中管理的,那么集中的运行脚本还需要知道每个模块是如何运行的
    • 代码如果是分层管理的,每个模块实现的功能需要跨越多个层次,被割裂在几个分开的目录内
    • 页面和代码如果不是搁一块的,那么模块还是要分为代码和页面两块
    • javascript和css如果是单独存放的,那么模块的改动还要不停地在相关的javascript和页面之间跳来跳去

    而有的时候我们又不把东西分开来

    • 使用相同表的方法和实现哪怕是为了完成不同功能,我们也会把这些代码放到同一个“Model”,不管它已经有多大了
    • 同一层的代码可以肆无忌惮的彼此引用,哪怕有的时cms有的是交易代码,风马牛不相及
    • 调用web service等外部服务的代码散落到代码的各个角落,可以随意引用

    所以Veil从某种意义上来说是对传统”秩序“的反思。我们把很多应该放在一起的东西出于种种困难没有能够放在一起,并且已经视之为理所当然。而有些完全不该放在一起的东西,打着”分层“,”OO“等旗号被堆砌到了一起,使得代码庞杂而难以管理。Veil无视我们已经习惯的秩序,单纯地从”高内聚,低耦合“的角度出发,来评判什么应该被放在一起,而什么又不应该放在一起。

    最终的目标不是为了OO,不是为了达成什么架构上的理想,甚至实现“高内聚,低耦合”也不能称之为目标。最终一个框架,以及其背后的架构设计思想的检验标准只能是响应变化的能力。也就是说,同样堆砌功能,用架构A和架构B当然都可以实现。而实现的质量除了静态的检验(功能性需求和非功能性需求是否满足),更重要的时动态的检验,就是“动”的能力。当我们需要对功能进行增删,把模块的职责互相移动的时候,代码能不能改,怕不怕改乱来,才是真正体现功力的地方。没有任何设计能够在一开时预见所有的需有,好的架构就是要让设计需要改动的时候,改得动不怕改。而在我们看来,要实现这一目标就是一个很简单的原则,就是要分而治之,同时保证被分治的部分之间保持“高内聚,低耦合”的关系。在Veil的设计过程中,就是秉着这样的目标,把模块化追求到极致。至于是否能够帮到你,是否真的能够达到前面所说的帮助你提高响应需求变化的能力,还有待实际使用中的检验。

    做为库:出来混迟早是要还的

    框架与应用的关系是,框架提供骨骼(所谓架构),应用提供肉(所谓业务逻辑)。但是不管是什么框架,最终还是会提供一些库来给以用使用,作者总是会期待能够把“公共”的“重复性“的劳动帮助应用完成了。而这种简便性,往往成了一个框架宣传时候的所谓亮点。但是我们知道物质是守恒的,代码的复杂度也是守恒的。实现同样的功能,不是应用程序多写一点代码,就是使用的库的多实现一些功能。从长远的角度来看,出来混迟早是要还的。所有库帮应用实现的功能,最终仍然是应用的一部分,从依赖的角度来看,你使用的语言的运行时(比如python的标准库),再下面的c运行时环境,操作系统的api,硬件驱动,乃至cpu指令都是你应用的一部分。一旦一个功能出错了,它可能是cpu出错了,也可能是你代码写错了,也可能是从你的代码到cpu中的每一个环节。

    既然认识到库也是应用的一部分,那么我们就需要思考什么时候需要用库,我们需要什么样的库。Veil自身需要提供什么样的库api给应用使用。我们认为影响库的设计与使用取舍有三条:

    • 问题域本身的复杂度。 如果问题本身过于复杂,无法让库的用户安心使用库提供的api,那么这样的场合可能就不适合封装成库。比如说SQL就一个很复杂的问题域,经过ORM的封装,它事实上重新发明了一种查询语言。带来的结果是,做为ORM的用户,不但要了解ORM封装之后提供的新的查询语言,还要知道SQL(事关执行效率),而且还要知道ORM封装后的查询语言与SQL之间的翻译关系(要不然我怎么让在性能出问题的时候,让ORM翻译出想要的SQL呢)。
    • 库自身api设计是否良好,有没有泄漏内部实现。 如果问题本身不复杂,比如计算一个字符串的md5值之类的。那么就只需要api设计良好,一般用户都不用去关心起内部实现了。
    • 库的代码质量。 但是有的时候我们还是被迫去了解一些库的内部实现。比如曾经用过的一版.net的hibernate,其处理并发情况下的lazy load list的时候,从连接池有取到不同连接的问题。在彻底检查了自己的代码之后悲惨地发现是库的代码有bug。

    对于以上三条,无论是哪条有问题,都会让我们进入一个还债的状态,以十倍地时间去了解我们不甚了解而又往往过于复杂的代码。因为库面对的用户是千千万万的,解决的问题也是形形色色的。比如说linux的进程调度有林林总总的实现,满足不同计算场合的要求。如果哪天我们被迫需要知道我们的进程是如何被linux调度的,那需要耗费的时间可想而知。即便是库解决的是一个明确而又小的问题,设计有良好的api,而且自身代码也不出什么问题,我们仍然会有可能遇到,问题可能稍微发生了一些变化,库不完全能解决我们的问题,而又不失完全不能解决的时候。遇到这样的场合,不少人可能都会选择与修改使用的库,要么fork,要么提交回去。

    总之,就是那句话,出来混迟早是要还的。Veil的原则也很直白,就是简单粗暴。如果要封装,也尽量处理明确而又小的问题,api不泄漏实现,同时要保证质量。不要在应用的代码和最终实现之间插入太多的magic。

  • 相关阅读:
    Codeforces 1265A Beautiful String
    1039 Course List for Student (25)
    1038 Recover the Smallest Number (30)
    1037 Magic Coupon (25)
    1024 Palindromic Number (25)
    1051 Pop Sequence (25)
    1019 General Palindromic Number (20)
    1031 Hello World for U (20)
    1012 The Best Rank (25)
    1011 World Cup Betting (20)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2725943.html
Copyright © 2011-2022 走看看