注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

秒大刀 博客

好好学习 天天向上

 
 
 

日志

 
 
 
 

读《Microsoft .NET企业级应用架构设计》  

2014-03-22 15:30:50|  分类: 读书 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
Microsoft .NET企业级应用架构设计 - 秒大刀 - 秒大刀 博客
 
正文之前
  1. 正确的判断来自于经验,而经验则来自于错误的判断——Fred Brooks

第一部分 设计原则
  1. 完美的设计不是包罗万象无所不有,而是完整自洽不可精简

第1章 当代的架构师和架构
  1. 软件工程的目的在于控制复杂性,而不是增加复杂性
  2. 如果软件系统缺少良好的架构设计支持,失败的可能性就会很大。具有丰富经验、良好教育以及相应资格的优秀架构师是团队所必需的
  3. 当代系统需要很多的工程以及理解,但不需要太多艺术和主观的猜测,这正是优秀架构师应当努力的方向
  4. 无论对于何种系统,一些重要的决定必须在开发的初期决定
  5. 没有什么系统是不可拆分的
  6. 如何判断一个架构的好坏呢?在好的架构中,所有给出的不会轻易改变的决定都是正确的
  7. 软件系统中总会有一些方面和功能不会轻易改变(仅仅是不会轻易改变,而不是不能改变)
  8. 领域驱动设计建议总是使用工厂来创建复杂的对象
  9. ISO/IED 9126中定义的软件6大类质量特征
    属性描述
    功能表示软件符合需求所必需的条件。功能基于诸如适用性、准确性、安全性、互操作性等需求,并满足必要的标准和规则
    可靠性表示软件在某些特定情况下满足指定级别性能的能力。可靠性基于诸如完备性、容错性和可恢复性等需求。
    完备性是指当软件内部出现错误时,不会影响软件操作。
    容错性是指控制错误的能力并维持一定程度上功能的可用。
    可恢复性是指在出现错误后可以自行恢复的能力
    可用性表示软件能够被用户理解、使用并吸引用户的能力。它要求软件必须满足可用性标准和规则
    有效性表示软件提供特定级别性能的能力,需要考虑响应时间和资源占用等方面
    可维护性表示软件支持修改(如改正、改进、改写)的能力。可维护性基于诸如可测试性、稳定性、可被分析、可被修改等需求
    可移植性表示软件能够从一个平台迁移到另一个平台,以及在同一环境中与其他软件共存并共享同样资源的能力
  10. 质量和安全需要在设计时就考虑到
  11. 时至今日,分析师和架构师的角色有了很大的区别
  12. 软件开发是一个用来处理复杂性,并保证程序得到预期结果的流程。软件工程的目的在于控制复杂性,而不是增加复杂性
  13. 敏捷方法不过是一些列较小的瀑布流程,每个瀑布中的工作少一些,时间短一些,不过瀑布会多一些,也许会根据需求添加。与瀑布相比,这更像是一个淋浴器
  14. 架构师的角色,以及架构师和开发团队处理需求的态度在很大程度上依赖于使用的开发方法——敏捷方法或者传统方法
  15. 本章的墨菲法则(若一件事情有可能搞砸,那么它就一定会被搞砸):
    1. 为一个赶不上进度的软件项目增加人手只能让其更加落后于进度
    2. 程序的复杂性会一直增加,直到负责维护的程序员力不从心为止
    3. 若建筑师按照程序员写程序那样造房子,那么史上出现的第一只啄木鸟也许会毁掉整个文明。(If builders built buildings the way programmers write programs, then the first woodpecker that came along would destroy civilization.)

第2章 UML必要知识
  1. 所有的模型都不甚完备,有些模型却有些用处
  2. 若想设计一个系统——任何领域中的任何系统,都需要首先对其进行抽象
  3. 建模对于任何软件项目来说都是个核心步骤。在高复杂度的情况下,建模是必不可少的。
  4. UML草稿模式:帮助交流想法,选择设计方式,关注特定问题。为开发者表述迭代的趋向,但不是完整的系统。设计和代码之间有明确的界限
  5. UML蓝本模式:给开发者留下的决策空间很少,甚至没有。开发过程即为将UML转化为编程语言
  6. 本章的墨菲法则:
    1. 真正的程序员从不添加注释。若代码难以编写,那么也会难以阅读
    2. 程序员90%的错误来自于其他程序员提供的数据
    3. 编写符合需求的程序和在水面行走一样简单,前提是需求已确定(frozen),水面已结冰(frozen)

第3章 设计原则和模式
  1. 有经验的设计者显然知道一些缺乏经验的设计者不知道的事情。这些事情是什么呢?
  2. 设计软件系统非常具有挑战性,因为这需要在满足需求的同时,也能保证最终系统足够的灵活,从而支持未来的变化或为其添加新功能
  3. 写出可以正常工作的代码是一回事,而写出可以正常工作的良好代码则是另一回事
  4. 导致变化的不是感性的决定,而是理性的思考
  5. 系统的变差通常是个缓慢的过程,需要相对较长的一段时间。也许是因为不停的为系统添加临时性的修复,而让越来越多的代码变得越来越难以维护和改进。最终你会发现,系统已经无药可救
  6. 设计应该着眼于解决目前的问题,但同时也要灵活的能够适应未来可能出现的问题和需求——《设计模式》
  7. OO设计的基本原则:找到合适的对象、尽量降低耦合、尽量保证代码重用
  8. 模块应该对扩展开放,但对修改关闭
  9. virtual方法中不应该访问任何私有成员,因对私有成员的访问无法在重写中实现,这会造成基类和派生类的语义有所差别
  10. 如何使用设计模式
    1. 设计模式并不是万能的,不能教条的使用
    2. 设计模式并不是超人,也不能魔术般的拯救一个陷入泥潭的项目
    3. 设计模式既不是原力的黑暗面,也不是光明面。设计模式也许会伴你左右,但并不能给你带来额外的能力
    4. 设计模式只不过是种有用的东西,仅此而已
  11. 某种设计模式并不是一开始就选用的,最合适的设计模式通常在重构的过程中会渐渐浮出水面
  12. 使用设计模式在本质上并不能让你的解决方案更有价值,真正的价值在于,在交付的时候你的解决方案是否能够正常工作并满足需求
  13. 设计模式的反模式
    1. 将架构作为需求(Architecture As Requirements):设计团队中的某个具有影响力的成员执意在项目中使用某个不成熟的技术或产品——即使尚无证据表明其作用或其是否适用于客户的上下文
    2. 将发布作为测试(Test By Release):软件产品发布时并没有太过考虑那些无聊耗时的单元测试或集成测试。用户是产品的最终使用者,因此软件质量就由他们来把关吧
  14. .NET中应该尽可能使用类,除非类型所占的存储空间低于16字节或类型是不可变的
  15. 不要在公开签名中使用List<T>,因List<T>并没有被设计成可通过继承扩展。应该采用IList<T>或其派生接口
  16. 若软件没有经过测试,那么肯定无法工作
  17. 单元测试和集成测试属于开发团队的工作。客户更关心的验收测试可以由客户自行书写,也可以由负责项目的团队和客户写作完成
  18. 测试是个严肃的问题。仅仅让最终用户随便试用几天系统并不是个可信或详细的测试方法
  19. 从安全的角度来看,目前感兴趣的只是某一层中提供服务的组件,而并不关注对象模型,因为对象模型将会被多层共享,仅仅用来表示数据以及数据上的行为
  20. 6种类型的安全威胁:
    1. 用户身份欺诈:指使用伪造的用户身份侵入系统。这个威胁可通过过滤非法IP地址来避免
    2. 篡改:指这模块通信过程中拦截或修改数据。这个威胁可通过保护通信渠道(例如SSL或IPSec等)来避免
    3. 抵赖:指某个操作的执行无法追本溯源至执行操作的用户。这个威胁可通过强化审计策略来避免
    4. 信息泄露:指将私密或敏感信息泄露给未经授权的用户。这个威胁可通过加强认证规则来避免
    5. 拒绝服务:指对系统发出大量请求直至其过载导致停止响应。这个威胁可通过过滤请求降低请求频率,并仔细检查当前占用带宽来避免
    6. 权限提升:指执行需要比当前权限更高的权限的操作。这个威胁可通过为组件指派尽可能小的权限来避免
  21. 优化讲究在最佳的时候进行——既不过早也不过晚
  22. 卓越的技术并不一定能保证最终的成功,一定程度的商业和市场技巧永远都是必需的
  23. 给软件从业者的实用建议
  24. 本章的墨菲法则:
    1. 软件可以正常工作的概率与其所需要的代码行数成反比
    2. bug出现的几率与正在查看该软件的人数及这些人的重要程度成正比
    3. 专家就是那些最后一刻赶到,陪众人一起挨骂的人

第二部分 系统设计
  1. 首先解决问题,随后编写代码

第4章 业务层
  1. 任何人都可以写出计算机能够理解的代码。而只有优秀的程序员才能写出别人可以理解的代码
  2. 分层带来的好处主要是条理清晰,且有利于重用以及分离关注点。逻辑分层可以很大程度上缩短开发周期,并允许不同的团队并行开发
  3. 通常出现的一个问题是:对可伸缩性的追求会影响到平时的性能
  4. 不要让对象分布使用
  5. 远程软件最好不要提供太过详细的接口,而进程内的软件最好有细粒度的接口
  6. 让业务层逻辑位于服务器端将极大简化日后的维护
  7. 通常你应该尝试把所有的事情都放在业务逻辑层中完成。分散在表现层和数据访问层中的逻辑有可能只是出于性能方面的考虑才进行的重复
  8. 重复数据将带来更多的测试、更大的错误风险
  9. 你应该仅仅把存储过程当作一个数据库工具,而不是作为业务逻辑的表达工具
  10. 经验能让你的目光敏锐,思维清晰,并且让你走在正确的道路上
  11. .NET Framework中,静态方法和实例方法从效率的角度没有任何区别
  12. “微软技术第一法则”:微软试图提供一个低层次的框架和一些高层次的工具。这些工具的功能无法和第三方厂商提供的功能相媲美,不过这些工具的目标是一般的常见场景,并能在大多数常见情况下完美的实现目标
  13. 以数据为中心的方法在大规模复杂系统中的局限性:随着系统复杂性的提高,关注数据的劣势也逐渐显露出来,因此你就需要开始同时关注于数据和行为。当然,若从以数据为中心的方法开始,随后对组件进行扩展增强,添加各种方法来表达所需的逻辑,这样做也没什么问题。不过从长远来看,以数据为中心的方法并不能很好的适应规模的增加,因为当系统的复杂性达到某个极限之后,哪怕是再添加一些新的需求,都会成为一个难以处理的问题
  14. 领域模型模式力求让对象模型能够与系统的概念匹配起来。领域模型完全与数据库独立,是一个尽可能贴近真实流程的模型,而不是去切近架构师希望的流程
  15. 软件架构师不过是个观察者,因此不应该对进行建模的流程好坏进行评价,软件架构师的工作是对流程进行建模
  16. 软件架构师不应该评价业务流程的好坏
  17. 最大的优势往往也会成为最显著的劣势
  18. 实现领域模型的一个主要障碍是对象和关系型数据库之间的不匹配
  19. 架构师的职责并不是强迫分析师或用户来学习编程,而是根据领域专家的描述设计出一个可以编程实现的模型
  20. 本章的墨菲法则:一个成功的业务层需要观察力和建模,也需要一种天生的、能够化繁为简的做事能力。“简单但不过分简单”一直是我们信奉的箴言
    1. 一个可以工作的复杂系统一定是始于一个可以工作的简单系统
    2. 人们会一直增加软件的可靠性,直到提高的成本已经大于处理错误的代价为止
    3. 在理论上,理论和实践之间没有差别;不过在实践中,二者截然不同

第5章 服务层
  1. 在表现层中留下少量的逻辑代码也并非十恶不赦
  2. 一般来说,无状态组件的可伸缩性更好,其整体实现也相对简单,且能应用在更多的不同场景中
  3. 将某个类升级成服务并不是个大动作,只是一个普通的重构过程。服务归根到底就是一个附加了一些东西的类。
  4. 查看用例,然后使用常识
  5. 代码层数较多并不一定会导致性能低下的系统
  6. 若仅有一条路可选,那么也就无所谓开销大小了
  7. 从客户的角度来看,架构上的任何选择都无法带来丝毫的好处。为客户带来好处的是对某个良好设计的架构的成功实现,而不是架构本身。
  8. 服务契约应该设计成静态的,且在服务发布之后不应该再有修改
  9. SOA的一个目标就是互操作性。基于这点考虑,我们知道没有平台专有的细节可以穿过服务边界,因此,类并不是服务中的首选,这也是选用基于消息的语义来定义服务的原因之一
  10. SOA模型从整体上看并不是分层的,而更像是分组的
  11. SOA是有关服务的,但并不是一种服务技术,使用了服务的应用程序并不叫做SOA应用程序,SOA只是指导良好的服务建模技术的一些原则
  12. SOA不再远程调用对象的方法,而是使满足了几个核心原则的服务彼此之间传递消息。
  13. 作为架构师,我们首先应该关注问题本身,然后力求找到有效的解决方案
  14. SOA实用规则:
    1. 服务层中的服务并不实现任何业务逻辑
    2. 服务层中的服务将协调并使用业务逻辑,无论业务逻辑属于工作流、领域对象还是应用程序服务
    3. 应用程序服务(即实现了一段业务的服务)有可能会实现SOA
    4. 数据交换是通过数据迁移对象(使用数据契约),而不是使用领域模型中的类
    5. 服务并不分发或共享对象,且服务方法也不操作于对象之上,服务仅用来以固定格式接受并返回值的集合
    6. 服务层中的服务应该力求满足UI的需求
    7. 应用层中的服务应该力求满足业务的需求
    8. 任何带有基于实体接口的服务都倾向于暴露普通的CRUD操作,这些服务叫做CRUDy服务,且不能算作SOA
    9. 服务的部署和版本控制应该与使用该服务的系统及该系统的部署完全独立
    10. 尽可能的避免修改服务契约和数据契约,若确实无法避免,则使用新的版本
  15. 在服务中,应该避免提供比业务事件更加细粒度的方法
  16. 服务不过是一系列HTTP接入点的集合,推荐使用Json格式接受并返回HTTP包。之所以放弃XML和SOAP而选用Json,是因为JavaScript客户端中Json要比XML更加易于处理。
  17. Json优于XML的最主要原因可以总结为Json要比发展成熟的XML更加简单,且在所有支持JavaScript的浏览器中都有免费的内建反序列化引擎。
  18. Json在设计时并没有想达到如XML一般的复杂性和可移植性,而是简单到就像是让XML仅支持节点和属性那样的功能。
  19. 服务层一般总是有必要提供的,因为它能够解除应用程序接口和中间层之间的耦合。唯一可能不会考虑使用服务层的情况是,你非常确信程序有且仅有一个表现层
  20. 本章的墨菲法则:
    1. 提供了接口说明文档的软件模块中仍有一些未在文档中提到的功能
    2. 足够好并不是足够好,除非项目有明确的期限
    3. 仅观察铁轨永远都不能告诉你火车行驶的方向

第6章 数据访问层
  1. 高层次的思考必须借助于高层次的语言
  2. 请牢记“客户永远是对的”
  3. 持久化方法是类中的实例方法,而读取方法则通常以类的静态方法形式暴露出来
  4. 在一个良好设计的数据访问层中,应该有一种机制来跟踪在一个工作单元内对应用程序数据的所有修改,这样即可在稍后将这些修改一次性的持久化回数据库中保存。这个工作单元就是一个逻辑(业务)上的事务,它包含一系列的数据库调用
  5. 为事务中每一次遇到的修改都发起一次数据库交互是不切实际的
  6. 在表现层中直接调用数据访问层的关键并不在于你能“投机取巧”地为某个特定问题找到快速的解决方案,更加重要的是你必须意识到你正在“投机取巧”
  7. 控制反转(IoC)的基本想法是功能的使用者并不自己管理所需要的依赖,而是将这些工作交给专门的组件完成
  8. 策略模式允许调用者重新定义整个算法,而模板方法模式只允许你重定义其中的某些步骤,而不是整个算法。模板方法模式中可以使用继承,而在策略模式中一般使用委托
  9. 惯用法是设计模式中的技术实现部分。惯用法就是语言中内建的设计模式,并通过专门的语法元素暴露出来
  10. 实际上并不是所有的程序都如此在意性能,慢了几毫秒也无伤大雅
  11. 处理大量的数据库细小操作将会在产品环境中引发性能问题
  12. 数据访问层的4种主要职责:持久化、查询、管理事务、维护并发
  13. 存储过程并不是绝对不能使用,而是应该在必要也确定有所帮助时才使用
  14. SQL代码——无论是硬编码的字符串还是存储过程,应该由SQL领域中的专家编写,而不是由C#开发者兼做。若想编写出良好的存储过程和数据表访问代码,必须对数据库的实现由足够的了解。这些可以交给LINQ-to-SQL等O/RM工具来完成,这并不应该让C#中间层开发人员负责
  15. 主流的O/RM工具:
    1. Entity Framework
    2. EntitySpaces
    3. Genome
    4. LINQ-to-SQL
    5. LLBLGen Pro
    6. NHibernate
  16. 存储过程并不会因为节省了SQL语句的编译过程而比普通SQL更高效,主流数据库都会对所有SQL编译结果进行缓存
  17. 应该竭力避免在存储过程中实现业务逻辑
  18. 数据库的主要用途:
    1. 作为集合数据的仓储
    2. 保证数据规则
    3. 保证数据完整性
    4. 在多个应用程序之间共享数据
  19. 应用软件的主要用途:
    1. 提供了与最终用户交互的表现层
    2. 提供了处理用户请求的业务逻辑
    3. 提供了数据访问层,用来以持久化的方式管理数据
  20. 建议仅在存储过程中包含CRUD相关操作,且尽可能让CRUD进操作在一个数据表上。若对CRUD操作优化有帮助,而并不是让存储过程参与到业务实体和业务逻辑中,那么也可适当的使用条件判断和循环。存储过程位于数据访问层中,负责返回或更新数据,而不是解释数据。不要在存储过程中包含数据规则之外的东西,仅在有明确证明的情况下(一般是性能提升,或完成某个工作更加简单)再使用存储过程
  21. 修改数据模型不会不带来任何影响,不过作为领域模型和数据模型的中间层,O/RM工具可以帮你尽量减小影响的波及范围
  22. 业务逻辑放在数据库中是错误的,甚至要比将其放在表现层中更不好(因为更难以维护)
  23. O/RM映射工具是实现领域驱动设计中不可缺少的资源。随着O/RM的出现,用存储过程作为数据访问逻辑的主要组织方式的日子已经一去不复返了
  24. 本章的墨菲法则:数据访问领域中正在悄悄发生着一些事——或许是理念上的根本变化。我们正逐渐远离存储过程和传统的SQL编程,而是转向可以提供(或支持)对象模型,并提供自动生成SQL代码功能的工具。
    1. 唯一完美确定的科学就是事后诸葛
    2. 在将某事放在内存中时,不要忘了存放的位置
    3. 你永远没时间正确的做一件事,但总是有时间去重做
第7章 表现层
  1. 如果没有用户界面,哪个程序都不能运行。哪怕是中间层代码堪称完美,用户也无法使用到
  2. 你的态度、偏好和自身的专业技能决定了你为每个层制定的“优先级”,也导致了你对各层的关注顺序。不过无论如何安排,结果都要一样,即每一层都必须足够优秀
  3. 表现层必须保证图形化用户界面的任意修改都不会影响到数据流和表现层逻辑。只要变化属于纯粹的图形化修改,那么表现层都必须支持以透明的方式对待
  4. 单元测试工具并不能验证某个方法是否产生了所需要的图形化结果。不过,你可以为视图构造出一个抽象的描述,随后输出到表示该视图的对象中,再验证其中的数据是否正确即可。抽象是使表现层提高可测试性的关键工具,抽象可以通过分离关注点实现,即将视图和表现层逻辑分开
  5. 将数据映射到UI组件上需要很多琐碎的代码,你当然需要正确编写。不过一旦编写完成,就不会再有什么会影响到这些代码。这正是被动视图(Passive View)最为重要的出现动机和设计理念
  6. 在表现层的特定情况下,让其与数据模型之间存在一些依赖是可以接受的,不过这样做必须是因为可以带来明显的(或者虽然不明显,但也基本没有风险)性能或维护上的优势
  7. 一般来说,架构师并不直接参与到图形化界面设计的细节中,架构师的主要职责是保证产品满足了所有的重要质量特征(特别是可用性和可访问性)
  8. 将要给大众使用的应用程序都要有精致的用户界面,因为软件的第一个目标就是抓住用户的注意,并给用户留下好的印象。而对于那些公司内部使用的应用程序来说,其界面则倾向于实现功能而不是视觉效果上的震撼
  9. 对于大型的企业级系统来说,RAD并不是一个理想的表现层开发选择
  10. 确保操作表现层的代码仅操作表现层。将所有领域和数据源的逻辑放在程序中的其他分开位置
  11. 摒弃自治视图(Autonomous View, AV)。
    1. 自治视图是在UI中包含了表现层逻辑、业务逻辑,甚至还有数据访问逻辑。
    2. 自治视图是一个包含了视图中显示和状态信息的类,其中也会从开始到结束完整的处理用户操作。对于这种庞大的组件,我们很难让其满足表现层需求。此外,这样的表现层也非常难以(近乎不可能)的是,用户界面和表现层逻辑之间也没有分离开来
  12. MVC:
    1. MVC仅仅给出了目标的方向,不过在实现细节上给架构师留出了很多空间,这也正是很多不同你给的实现都可以称作MVC的原因
    2. MVC模式的主要目标是将应用程序分为各司其职的部分——模型、视图和控制器
      1. 模型是指应用程序的状态,封装了应用程序的功能,并通知视图其状态发生了变化
      2. 视图是指将要展示给用户的图形化元素的生成,视图还需要不活并处理用户操作
      3. 控制器将把用户操作映射成程序操作,并负责选择下一个视图
    3. MVC带来的优势:
      1. 简化了对用户界面的测试
      2. 修改图形界面不会影响到用户界面的行为
      3. 尽可能的将代码从视图中移走有助于代码更加结构化,并在逻辑上分层
      4. 将表现层分为不同的对象使不同团队同时开发应用程序的不同部分变成了可能
    4. MVC中的视图应该尽可能的dumb(哑)、humble(卑微低下)和passive(被动)。在编码过程中,这意味着图示应该仅仅负责处理将内容呈现给用户。
    5. 理想情况下,视图非常简单,没有任何逻辑,以致于无需进行测试
    6. 在MVC实现中,控制器将通过执行被触发的操作来更新模型。随后,模型将通知视图其状态发生了变化。最后视图将决定是否把该变化反映到用户界面上。若需要的话,视图将读取模型,并提供更新后的界面
    7. 控制器不会关注其对视图的修改将会对视图造成何种影响。控制器并不负责更新视图,控制器也不是为了分离视图和模型而存在的。视图直接了解模型,而模型仅通过观察者模式与视图保持关系。控制器将从视图中获取输入,然后以单向的方式操作模型。控制器并不是视图和模型之间的协调者,而更像是用户和应用程序之间的些调整。
    8. 经典的MVC实例图:
      Microsoft .NET企业级应用架构设计 - 秒大刀 - 秒大刀 博客 
    9. 经典MVC的两大不足:
      1. 模型需要与视图通信,从而告知模型状态的变化——通常使用观察者模式
      2. 视图会隐式的对模型有所了解。视图需要用其自身的逻辑来从模型中选择数据,并在处理后显示在UI元素中。这些代码很难从视图中移除,也就造成了视图仍不够被动
  13. 清晰的解释实际上要比抽象的图表更有说服力
  14. 最基础的原则永远都不会过时,模式只是提供了一个快速的解决方案而已
  15. MVP和经典MVC中的参与者:
    Microsoft .NET企业级应用架构设计 - 秒大刀 - 秒大刀 博客 
  16. MVP特点:
    1. 视图并不了解模型
    2. 展示器将忽略视图中使用的具体UI技术
    3. 视图可被模拟,以便测试
  17. MVP中若再为模型抽象出接口,则可以展示器为中心进行开发,视图和模型都可以在测试时模拟。如此让MVP的可测试能力有了很大的增强
  18. 分离关注点在大型应用程序中已经成为人们的共识
  19. 软件复杂性守恒定律说明,软件系统中的复杂性是守恒的,可以从一层中转到另一层中。
    1. 最终产品的复杂性是固定的,不过在开发过程中有可能发生变化(大多数是变得更复杂)
    2. 软件复杂性永远都不会比最初给出的功能性需求少
    3. 与能量不同的是,软件复杂性是可以凭空创造的。这通常是由哪些狂热、偏执、喜欢过度设计的开发者和架构师造成的
  20. 理论是个好东西,不过若不能恰当的应用,那么等待我们的通常会是一场灾难
  21. 若你选择被动视图,那么系统将更易于测试,因为视图中的逻辑已被尽可能的减少。
  22. 被动视图将不可避免的带来更加复杂的展示器,选择被动视图其实就是选择高可测试性,同时带来展示器中的高度复杂性。这种做法就是Passive View模式
  23. Supervising Controller相比Passive View使用功能更加丰富的视图,其中包含一些诸如数据绑定和数据格式化之类的逻辑。这种带有更多功能的视图更易于开发,实际上将所需要的复杂性分散在视图和展示器中。视图需要进行一些同步和转换工作,以便让输入数据可以由用户界面元素使用。选用Supervising Controller方式表示你在可测试性和开发难度之间进行了权衡。使用Supervising Controller并不意味着你彻底放弃了测试。这种做法同样有良好的可测试性,且还能大大加快开发速度
  24. 有没有通用的办法可以测试图形化UI呢?一般性的指导理念就是让视图生成非图形化的输出,从而让单元测试可以判断UI正确与否
  25. WPF/Silverlight设计上参考的是Presentation Model(PM)模式,并称之为Model-View-ViewModel(MVVM)
  26. 表现层模式的演化及其适用平台
    Microsoft .NET企业级应用架构设计 - 秒大刀 - 秒大刀 博客 
  27. 开发人员通常有着一种虽可以理解,却是灾难性的倾向。让其工作朝着越来越高的复杂度和需要越来越多的创造力方向发展。若没有机会设计比这个程序更大的东西,那么开发者将让这个程序不停的复杂下去,直至超过他们的专业能力
  28. 本章的墨菲法则:
    1. 不怕用户没有想法,就怕用户的想法错误且不切实际
    2. 若让软件处理了所有可能的愚蠢错误,那么也会同时造就出更加愚蠢的用户
    3. 若想编写出一个连傻瓜都能用的软件,那么也就只有傻瓜才想使用了

正文之后
  1. 设计软件有两种方式。一种是让其足够简单,从而避免错误。另一种是让其足够复杂,借此掩盖错误——C.A.R. Hoare
  2. 悲观者抱怨风,乐观者期待风的结束,现实主义者却借风远航——William Arthur Ward
  3. 每个人都会抱怨在开发时没有足够的时间,但是每个人总是有时间花在出现问题后的修复上
  4. 软件就像一幢大楼,其中有很多层和很多房间,无论你处于什么原因住在这幢大楼中,Architecture(建筑/架构)都会在你周围
  5. 编程箴言:
    1. 凡事无绝对
    2. 需求是超越一切存在的
      1. 客户将说出他们需要什么
        1. 客户的需求才是最重要的部分,客户所需求的东西就叫做需求
        2. 当然,没有几个客户知道他自己真正需要的是什么,因此需求会不停的变化
      2. 若是客户不清楚自己的需求,那么需要分析师来引导直至得到明确的答案
      3. 项目经理将为这个已经正式确定的项目安排基础设施
      4. 架构师会得到所有的需求,并未开发者提供设计
      5. 开发者将按照架构的意图开发
      6. 数据库管理员也会尽力让数据库能良好的支持应用程序
    3. 根据接口编程
    4. 保持简单,但不过于简单
    5. 继承是为了多态,不是重用
    6. 不要在非数据访问层中使用SQL
    7. 首先考虑可维护性
      1. 最重要的是可维护性,有了可维护性,其他诸如可伸缩性、性能、可测试性、可用性等都可以在日后实现
    8. 所有的用户输入都是罪恶的
      1. “纸包不住火”,若是有某种途径让用户可以入侵,那么迟早会被用户发现。这似乎是墨菲法则,确实如此
    9. 事后优化
      1. 过早地优化是所有软件罪恶的根源
      2. 不要优化系统,而是让其设计尽可能的灵活面对改进和扩展,仅在系统完成之后,再关注纯粹的优化
    10. 在设计时就考虑安全性和可测试性
  评论这张
 
阅读(1844)| 评论(1)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017