写框架思路进程(四)

来源:互联网 发布:oppo专用root软件 编辑:程序博客网 时间:2024/06/07 02:32

搭建整体骨架

经过初步设计后,为框架搭建一套整体的骨架,一套抽象的层次关系,也就是用抽象类、接口或者空的类实现框架,可以通过编译,让框架跑起来,就像造房子搭建房子的钢筋混泥土结构(添砖加瓦是后面的事,我们先要有一个结构)。对于开发应用程序来说,其实并没有什么撑起来的说法,因为应用程序中很多模块都是并行的,可能并没有一个主结构、主流程,而对于框架来说,它往往是一个高度面向对象的、高度抽象的一套程序,搭建整体骨架也就是搭建一套抽象层。

如果要做一个Web MVC框架,需要未上面所说的几个核心模块进行抽象:

1、routing MVC的入口是路由 (路由这一块可能很多会不熟悉或迷惑具体操作,后面会有详细介绍)

 1.1 每一个路由都是IRoute代表了不同的路由实现,也提供一个getRouteResult()方法来返回RouteResult对象。

 1.2 我们实现一个框架自带的DefaultRoute,使得路由支持配置,支持默认值,支持正则表达式,支持约束等等。

 1.3 需要有一个Routes类来管理所有的路由IRoute,提供一个findRoute()方法来返回RouteResult对象,自然我们这边调用的就是IRoute的getRouteResult(),返回能匹配到的结果。

 1.4 RouteResult对象就是匹配的路由信息,包含了路由解析后的所有数据。


2、controller 路由下来是控制器

 2.1 有IControllerFactory来创建Controller,提供createController()方法来返回IController

 2.2 IController代表控制器,提供一个execute()方法来执行控制器

 2.3 实现一个框架自带的DefaultControllerFactory来以约定优于配置的方式,根据约定规则以及路由数据RouteResult来找到IController并创建它

 2.4 为IController提供一个抽象实现,AbstractController,要求所有MVC框架的使用者创建的控制器需要继承AbstractController。在这个抽象实现中,我们可以编写一些便捷的API以方便开发人员使用,比如view()方法、file()方法、redirect()方法、json()方法、js()方法等等。


3、action 找到控制器后就是来找要执行的方法了

 3.1 有IActionResult来表带Action返回的结果,提供一个execute方法来执行这个结果

 3.2 框架需要实现一些自带的IActionResult,比如ContentResult、ViewResult、FileResult、JsonResult、RedirectResult来对应AbstractController的一些便捷方法

 3.3 再定义一个IActionInvoker来执行Action,提供一个inckeAction()方法

 3.4 实现一个DefaultActionInvoker以默认的方式进行方法的调用,也就是找到方法的一些IFilter按照一定的书序执行它们,最后使用反射进行方法的调用,得到上面说的IActionResult并执行它的execute()方法 


4、filter 框架很重要的一点就是便捷的过滤器

 4.1 IFilter,就是一个过滤器,提供IActionFilter对方法的执行前后进行过滤,提供IResultFilter对ActionResult执行前后进行过滤

 4.2 IActionInvoker怎么找到需要执行的IFilter呢,需要定义一个IFilterProvider来提供过滤器,它提供一个getFilter()方法来提供所有的IFilter的实例

 4.3 框架可以实现一些自带的IFilterProvider,比如AnnotationFilterProvider通过扫描Action或Controller上的注解来获取需要执行的过滤信息;比如还可以实现GlobalFilterProvider,开发人员可以直接通过配置或代码方式告知框架应用于全局的IFilter。

 4.4 实现了多个IFilterProvider,自然需要有一个类来管理这些IFilterProvider,我们实现一个FilterProvider类并提供gerFilters()方法。


5、view 各种IActionResult中最特殊最复杂的就是ViewResult,需要有一个单独的包来处理ViewResult的逻辑。

 5.1 需要有IViewEngine来代表一个模板引擎,提供一个getViewEngineResult()方法返回ViewEngineResult

 5.2 ViewEngineResult包含视图引擎寻找视图的结果信息,里面包含IView和寻找的一些路径等

 5.3 IView自然代表的是一个视图,提供render()方法(或者为了统一也可以叫做execute)来渲染视图

 5.4 实现常见的一些模板引擎,比如FreemarkViewEngine、VelocityViewEngine等,VelocityViewEngine返回的ViewEngineResult自然包含的是一个实现的IView的VelovityView,不会返回其它引擎的IView

 5.5 需要一个ViewEngines类管理所有的IViewEngine,实现findViewEngine()方法


6、common 放一些项目中各个模块都要用到的一些东西

 6.1 各种context,context代表的是执行某个任务需要的环境信息,我们可以定义HttpContext、ControllerContext、ActionContext和ViewContext,后者继承前者,随着MVC处理流程的进行,View执行时的上下文相比Action执行时的上下文信息肯定是多了视图的信息,其它同理。之所以把这个信息放在common里面而不是各个模块自己的包内,是因为这样更清晰,可一目了然各种对象的执行上下文有一个立体的概念。

 6.2 各种helper或utility


model、plugin......等模块内容



总结,MVC框架在组织结构上有着高度的统一

1. 如果xxx本身并无选择策略,但xxx的创建过程也不是一个new这么简单的,可以由xxxFactory类来提供一个xxx

2. 如果需要用到多个yyy,那么会有各种yyyProvider(通过getyyy()方法)来提供这些yyy,并且我们有一个yyyProviders来管理这些yyyProvider

3. 如果zzz的选择是有策略的,会按照需要选择zzz或zzzN,那么可能会有一个zzzs来管理这些zzz,并且(通过findzzz()方法)来提供合适的zzz


同时,我们框架的相关类的命名也是非常统一的,一眼可以看出这是实现、还是抽象类还是接口;是提供程序,是执行结果还是上下文。当然,在将来的代码实现过程中很可能会把很多接口变为抽象类提供一些默认的实现,这并不会影响项目的主结构。我们会在模式篇对框架常用的一些高层设计模式做更多的介绍。


到了这里,我们的项目里已经有几十个空的(抽象)类、接口了,其中也定义了各种方法可以把各个模块串起来(各种find()方法和execute()方法),可以说整个项目的骨架已经建立起来了,这种感觉很好,因为我们心里很有底,我们只需要在接下去的工作中做两个事情:
 

 1.实现各种DefaultXXX来走通主流程
 2.实现各种IyyyProvider和Izzz接口来完善支线流程

0 0
原创粉丝点击