我对前端开发中的 框架的理解
1
2
3
架和类库等概念的出现都是源于人们对复用的渴望。〝不要重复发明轮子”,成了软件界的一句经典名言。从最初的单个函数源代码的复
用,到面向对象中类的复用(通常以类库的形式体现),再到组件的复用, 项目架构的复用。。
人们复用软件的抽象层次越来越高。现在,框架复用是抽象层次的又一提升,框架的复用不仅仅是功能的复用,更是设计的复用。
1.框架和类库的区别
1
2
3
4
5
我们先来简单说说什么是类库 (Class Library)?望文生义,类库就是一些类的集合,只要我们将一些可以复用的类集中放到一个?望文生义,类库就是Library中,我们就可以称其为一个类库。类库中的许多元素(如类、结构、接口、枚举、委托等) 之间可能有一些关联,但这些关联通常用于支持一个类概念或接口概念的完整表达。如果我们从一个更高的视角来申视类库,可以发现类库中的一个个〝完整的概念“之间是无关的或是关系松散的。 -----------
再来说框架,框架的第一含义是一个骨架,它封装了某领域内处理流程的控制逻辑,所以我们经常说框架是一个半成品的应用。由于领域的种类是如此众多,
所以框架必须具有针对性,比如,专门用于解决底层通信的框架,或专门用于医疗领域的框架。
框架中也包含了很多元素,但是这些元素之间关系的紧密程度要远远大于类库中元素之间的关系。
框架中的所有元素都为了实现一个共同的目标而相互协作。
没有一个万能的框架可以应用于所有种类的领域和应用,框架的目标性非常强,它专注于解决某一特定领域的问题,并致力于为这一特
定领域提供通用的解决方案。
框架与类库的区别主要表现在以下几个方面:
- 从结构上说,框架内部是高内聚的,而类库内部则是相对松散的。
- 框架封装了处理流程的控制逻辑,而类库几乎不涉及任何处理流程和控制逻辑。
- 正是由于框架对处理流程的控制逻铜进行了封装,才使得框架成为一个应用的骨架。
框架中的处理流程和控制逻辑需要经过精心的设计,因为所有使用了该框架的应用程序都会复用该设计。
2.框架的应用
1
2
3
4
5
当一个应用系统选定了框架之后,我们需要做的就是在框架提供扩展点的地方 添加应用的具体逻辑,
也就是使用〝血“和〝肉“来填充这个骨架从而得到一个〝有机体”
由于框架通常都是在实践中经过反复使用和检验的,所以质量有一定的保证,这使得我们用更少的时间、
更少的编码来实现一个更稳定的系统成为可能。
当然,框架也不是〝银弹”,它不能解决软件复杂性的根本问题,但是我们却通过它向这个终极的理想目标又迈进了一步.
有一点需要注意,框架使得我们的系统在有所支撑的同时,它也给出了限制。因为通常当我们确定采用了某一个框架之后,我们就必须 在这个框架限制的〝框框“之内来构建我们的应用。大多数时候,这不是一个问题,但是如果因为框架的限制而严重影响了我们系统目标的 实现的时候,我们就需要考虑是否应该放弃这个框架,或者换一个其它的同类型的框架
3.框架的设计
1
2
3
框架使得我们开发应用的速度更快、质量更高、成本更低,这些好处是不言而喻的。
然而,面对万千变化日趋复杂的软件需求,设计和实现一个高度灵活可复用的框架又谈何容易!
框架源于应用,却又高于应用。
- 框架往往是这样产生的:
我们拥有了开发某种类型应用的大量经验,我们总结这种类型的应用中共性的东西,将其提炼到一个高的层次中,以备复用。
这个〝高层次”的东西便是框架的原型。随着我们经验的不断积累,框架也会不断地完善、发展。
有一点需要特别注意,正如所有的软件架构设计的要点在于权衡 (在这方面有点像艺术),框架的设计也不例外,正如前面提到,框架
在为应用提供了一个骨架的同时,也给我们的应用圈定了一个框框,我们只能在这个有限的天地内来发挥。
所以,一个好的框架设计应当采用了一个非常恰当的权衡决策,以使框架在为我们应用提供强大支持的同时,
而又对我们的应用作更少的限制。权衡,从来就不是一件简单的事情,但是有很多框架设计的经验可以供我们参考。
1)框架不要为应用做过多的假设!
关于框架为应用做过多的假设,一个非常具体的现象就是,框架越俎代庖,把本来是应用要做的事情揽过来自己做。
这是一种典型的吃力不讨好的做法。框架越俎代庖,也许会使得某一个具体应用的开发变得简单,却会给其它更多想使用该框架的应用增加了本没有必要的
束缚和负担,(封装抽离要适可而止,既要提高效能,又要防止过度耦合,臃肿,从而降低了应用性和可扩展性)
当然从事前端架构工作,个人还是比较希望把全流程需要规范的地方,组件,工具代码,业务代码范本,都要规范统一,提升项目的工程化、标准化指数。
2) 使用接口,保证框架提供的所有重要实现都是可以被替换的。
框架终究不是应用,所以框架无法考虑所有应用的具体情况,保证所有重要的组件的实现都是可以被替换的,这一点非常重要,它使得应 用可以根据当前的实际情况来替换掉框架提供的部分组件的默认实现。使用接口来定义框架中各个组件及组件间的联系,将提高框架的可 复用性。
3)框架应当简洁、一致、且目标集中。
框架应当简洁,不要包含那些对框架目标来说无关紧要的东西,保证框架中的每个组件的存在都是为了支持框架目标的实现。包含过多无 谓的元素(类、接口、枚举等),会使框架变得难以理解,尝试将这些对于框架核心目标不太重要的元素转移到类库中,可以使得框架更 清晰、目标更集中。
4)提供一个常用的骨架,但是不要固定骨架的结构,使骨架也是可以组装的。
比如说,如果是针对某种业务处理的框架,那么框架不应该只提供一套不可变更的业务处理流程,而是应该将处理流程〝单步”化,使得各 个步骤是可以重新组装的,如此一来,应用便可以根据实际情况来改变框架默认的处理流程。这种框架的可定制化能力可以极大地提高框 架的可复用性
5) 不断地重构框架。
如果说设计和实现一个高质量的框架有什么秘诀?答案只有一个:重构、不断地重构。重构框架的实现代码、甚至重构框架的设计。
重构的驱动力源于几个方面,比如对要解决的本质问题有了更清晰准备的认识,在使用框架的时候发现某些组件职费不明确、难以使用,框 架的层次结构不够清晰等
4 如何称得上一个优秀的框架?
一个优秀框架的最主要的特点是:简单。这种简单性不是轻而易举就可以获得的,正如优秀的框架不是一蹴而就的,达到这种简单性 需要对框架不断地抽丝、不断地提炼和完善。简单的真正原因在于它抓佳了要解决的问题的本质。 一个优秀的框架通常都具有如下特点
(1) 清晰的、简洁的、一致的。
〝清晰“指的是框架的结构是清晰的、框架的层次是清晰明朗的、框架中各个类和组件的职责是清晰明确的。 〝简洁“指的是框架中没有无关紧要多余的元素,而且各个类和组件的职责目标是非常集中的,这正是〝高内聚、低耩合“设计原则的体现 〝一致“通常会带来这样的好处,框架的使用者在熟悉了框架的一部分后,会非常容易地理解框架的另一部分。〝一致“通常体现在命名的规 则一致、命名的含义一致、组件的装配方式和使用方式一致等。
框架应该是易于使用的,把好多基础的逻辑代码进行封装抽离,使业务开发人员不用再花精力关注不该关注的代码逻辑。提高企业业务代码开发效率
(2) 易于使用的
只有易于使用的框架才会走得更远。 正是因为易于使用,框架使用者们才有可能试用这个框架,在试用满意后才有可能决定采用这个框架。一个框架功能即使再强大,如果 难以使用,那么框架使用者们很可能根本就不会有试用这个框架的念头, 框架的生命力源于框架一直在不断地完善和发展,如果没有人使用这个框架,这个框架便没有了发展和完善的源动力。正如友好的用户界 面是优秀应用程序不可或缺的重要部分,易于使用也是优秀框架的一个重要特性、
(3) 高度可扩展的、灵活的
框架通过高度可扩展性来应对应用程序的万千变化。
没有任何一个框架可以预料所有应用的需求,万能的框架是不存在的。企图设计、实现一个万能框架的想法是荒诞的。框架必须具有
〝以不变应万变^的基础性能力,框架可以通过为应用预留恰当的、足够的扩展点来做到这一点。
框架的灵活体现在框架可以根据不同的应用进行不同的组装和配置,就像框架是专门为当前的应用所订制的一样。
(4)轻量的
〝轻量〞,说的通俗点,就是只为自己需要使用的服务付费,而不需要为自己不需要的服务买单。一个重量级的框架有一个很明显的特 征就是,如果你需要一套完整的套餐服务,那是没有问题的,框架可以很好的满足你;但是,如果你只需要这份套餐中的一小块点心,对 不起,框架仍然会强加一个完整的套餐给你,你必须付一整份套餐的费用。 优秀的框架应当支持使用者〝按需所取“的原则,框架使用者可以随意〝点菜“进行组装来满足自己的需求
(5)弱侵入性的
所谓〝弱侵入性〞,采用了框架的应用程序可以尽可能的以普通的方式来编写应用逻辑,而不必为了适应框架不得不使用一些特殊的手法 这可能有点难以理解,我们可以举个例子来简单说明。在.NET中,实现AOP(面向方面编程)机制的两种主要方式是使用Proxy和动 态代理。使用Proxy实现的AOP框架通常要求那些需要使用AOP截获功能的类必须继承自ContexBoundObiject;而采用动态代理实现的 AOP框架则没有任何如此侵入性的要求,我们仍可以以最普通的方式来编写应用逻辑类,这类框架会在运行时根据配置动态地生成目标对 象的代理对象来实现AOP截获。所以我们可以说,采用动态代理方式实现的AOP框架相比采用Proxy实现的AOP框架,具有更弱的侵入 性 弱侵入性意味着框架对应用逻辑的干扰更少,由于应用逻辑类都是普通的类,这非常方便应用逻辑在另外一个程序中复用,而另外的程 序可能采用了一个完全不同的框架,