写一个框架的详细步骤

写一个框架的详细步骤
写一个框架的详细步骤

定位

所谓定位就是回答几个问题,我出于什么目的要写一个框架,我的这个框架是干什么的,有什么特性适用于什么场景,我的这个框架的用户对象是谁,他们会怎么使用,框架由谁维护将来怎么发展等等。

如果你打算写框架,那么肯定心里已经有一个初步的定位,比如它是一个缓存框架、Web MVC框架、IOC框架、ORM/数据访问框架、RPC框架或是一个用于Web开发的全栈式框架。

是否要重复造轮子?除非是练手项目,一般我们是有了解决不了问题的时候才会考虑不使用既有的成熟的框架而重复造轮子的,这个时候需要列出新框架主要希望解决什么问题。有关是否应该重复造轮子的话题讨论了很多,我的建议是在把问题列清后进行简单的研究看看是否可以通过扩展现有的框架来解决这个问题。一般而言大部分成熟的框架都有一定的扩展和内部组件的替换能力,可以解决大部分技术问题,但在如下情况下我们可能不得不自己去写一个框架,比如即使通过扩展也无法满足技术需求、安全原因、需要更高的生产力、需要让框架和公司内部的流程更好地进行适配、开源的普适框架无法满足性能需求、二次开发的成本高于重新开发的成本等等。

主打轻量级?轻量级是很多人打算自己写一个新框架的原因,但我们要明白,大部分项目在一开始的时候其实都是轻量级的,随着框架的用户越来越多,它必定需要满足各种奇怪的需求,在经过了无数次迭代之后,框架的主线流程就会多很多扩展点、检测点,这样框架势必变得越来越重(从框架的入口到框架的工作结束的方法调用层次越来越多,势必框架也就越来越慢),如果你打算把框架定位于一个轻量级的框架的话,那么在今后的迭代过程中需要进行一些权衡,在心中有坚定的轻量级的理念的同时不断做性能测试来确保框架的轻量,否则随着时间的发展框架可能会越来越重进而偏离了开始的定位。

特性?如果你打算写一个框架,并且只有轻量级这一个理由的话,你或许应该再为自己的框架想一些新特性,就像做一个产品一样,如果找不出两个以上的亮点,那么这个产品不太可能成功,比如你的新框架可以是一个零配置的框架,可以是一个前端开发也能用的后端框架。其它?一般来说框架是给程序员使用的,我们要考虑框架使用的频度是怎么样的,这可能决定的框架的性能需求和稳定性需求。还有,需要考虑框架将来怎么发展,是希望走开源路线还是商业路线。当然,这些问题也可以留到框架有一个大致的结构后再去考虑。

我们来为本文模拟一个场景,假设我们觉得现有的Spring MVC等框架开发起来效率有点低,打算重复造轮子,对于新框架的定位是一个给Java程序员使用的轻量级的、零配置的、易用的、易扩展的Web MVC框架。

调研

虽然到这里你已经决定去写一个框架了,但是在着手写之前还是至少建议评估一下市面上的类似(成熟)框架。需要做的是通读这些框架的文档以及阅读一些源码,这么做有几个目的:

通过分析现有框架的功能,可以制定出一个新框架要实现的功能列表。

通过分析现有框架的问题,总结出新框架需要避免的东西和改善的地方。

通过阅读现有框架的源码,帮助自己理清框架的主线流程为总体设计做铺垫(后面总体设计部分会更多谈到)。

如果能充分理解现有的框架,那么你就是站在巨人的肩膀上写框架,否则很可能就是在井底造轮子。

新开发一个框架的好处是没有兼容历史版本的包袱,但是责任也同样重大,因为如果对于一开始的定位或设计工作没有做好的话,将来如果要对格局进行改变就会有巨大的向前兼容的包袱(除非你的框架没有在任何正式项目中使用),兼容意味着框架可能会越来越重,可能会越来越难看,阅读至少一到两个开源实现,做好充分的调研工作可以使你避免犯大错。假设我们评估了一些主流框架后已经很明确,我们的MVC框架是一个Java平台的、基于Servlet的轻量级的Web MVC框架,主要的理念是约定优于配置,高内聚大于低耦合,提供主流Web MVC框架的大部分功能,并且易用方面有所创新,新特性体包括:

起手零配置,总体上约定由于配置,即使需要扩展配置也支持通过代码和配置文件两种方式进行配置。

除了Servlet之外不依赖其它类库,支持通过插件方式和诸如Spring等框架进行整合。

更优化的项目结构,不需要按照传统的Java Web项目结构那样来分离代码和WEB-INF,视图可以和代码在一起,阅读代码更便利。

拦截器和框架本身更紧密,提供Action、Controller和Global三个级别的"拦截器"(或者说过滤器)。

丰富的Action的返回值,返回的可以是视图、可以是重定向、可以是文件、可以是字符串、可以是Json数据,可以是Javascript代码等等。

支持针对测试环境自动生成测试的视图模型数据,以便前端和后端可以同时开发项目。

支持在开发的时候自动生成路由信息、模型绑定、异常处理等配置的信息页面和调试页面,方便开发和调试。

提供一套通用的控件模版,使得,并且支持多种模版引擎,比如Jsp、Velocity、Freemarker、Mustache等等。

嗯,看上去挺诱人的,这是一个不错的开端,如果你要写的框架自己都不觉得想用的话,那么别人就更不会有兴趣来尝试使用你的框架了。

解决难点

之所以把解决难点放在开搞之前是因为,如果实现这个框架的某些特性,甚至说实现这个框架的主流程有一些核心问题难以解决,那么就要考虑对框架的特性进行调整,甚至取消框架的开发计划了。有的时候我们在用A平台的时候发现一个很好用的框架,希望把这个框架移植到B平台,这个想法是好的,但之所以在这以前这么多年没有人这么干过是因为这个

平台的限制压根不可能实现这样的东西。比如我们要实现一个MVC框架,势必需要依赖平台提供的反射特性,如果你的语言平台压根就没有运行时反射这个功能,那么这就是一个非常难以解决的难点。又比如我们在某个平台实现一个类似于.NET平台Linq2Sql的数据访问框架,但如果这个目标平台的开发语言并不像C#那样提供了类型推断、匿名类型、Lambda 表达式、扩展方法的话那么由于语法的限制你写出来的框架在使用的时候是无法像.NET平台Linq2Sql那样优雅的,这就违背了实现框架的主要目的,实现新的框架也就变得意义不大了。

对于我们要实现的MVC框架貌似不存在什么根本性的无法解决的问题,毕竟在Java平台已经有很多可以参考的例子了。如果框架的实现总体上没什么问题的话,就需要逐一评估框架的这些新特性是否可以解决。建议对于每一个难点特性做一个原型项目来证明可行,以免在框架实现到一半的时候发现有无法解决的问题就比较尴尬了。

分析一下,貌似我们要实现的这8大特性只有第1点要研究一下,看看如何免配置通过让代码方式让我们的Web MVC框架可以和Servlet进行整合,如果无法实现的话,我们可能就需要把第1点特性从零配置改为一分钟快速配置了。

开搞

首先需要给自己框架取一个名字,取名要考虑到易读、易写、易记,也需要尽量避免和市面上其它产品的名字重复,还有就是最好不要起一个侮辱其它同类框架的名字以免引起公愤。如果将来打算把项目搞大的话,可以提前注册一下项目的相关域名,毕竟现在域名也便宜,避免到时候项目名和域名差距很大,或项目的.com或.org域名对应了一个什么不太和谐的网站这就尴尬了。

然后就是找一个地方来托管自己的代码,如果一开始不希望公开代码的话,最好除了本地源代码仓库还有一个异地的仓库以免磁盘损坏导致抱憾终身,当然如果不怕出丑的话也可以在起步的时候就使用Github等网站来托管自己的代码。

总体设计

对于总体设计我的建议是一开始不一定需要写什么设计文档画什么类图,因为可能一开始的时候无法形成这么具体的概念,我们可以直接从代码开始做第一步。框架的使用者一般而言还是开发人员,抛开框架的内在的实现不说,框架的API设计的好坏取决于两个方面。对于普通开发人员而言就是使用层面的API是否易于使用,拿我们的MVC框架举例来说:

最基本的,搭建一个HelloWorld项目,声明一个Controller和Action,配置一个路由规则让Get方法的请求可以解析到这个Action,可以输出HelloWorld文字,怎么实现?

如果要实现从Cookie以及表单中获取相关数据绑定到Action的参数里面,怎么实现?

如果要配置一个Action在调用前需要判断权限,在调用后需要记录日志,怎么实现?

我们这里说的API,它不一定全都是方法调用的API,广义上来说我们认为框架提供的接入层的使用都可以认为是API,所以上面的一些功能都可以认为是MVC框架的API。

框架除了提供基本的功能,还要提供一定程度的扩展功能,使得一些复杂的项目能够在某些方面对框架进行增强以适应各种需求,比如:

我的Action是否可以返回图片验证码?

我的Action的参数绑定是否可以从Memcached中获取数据?

如果出现异常,能否在开发的时候显示具体的错误信息,在正式环境显示友好的错误页面并且记录错误信息到数据库?

一般而言如果要实现这样的功能就需要自己实现框架公开的一些类或接口,然后把自己的实现"注册"到框架中,让框架可以在某个时候去使用这些新的实现。这就需要框架的设计者来考虑应该以怎么样的友好形式公开出去哪些内容,使得以后的扩展实现在自由度以及最少实现上的平衡,同时要兼顾外来的实现不破坏框架已有的结构。

要想清楚这些不是一件容易的事情,所以在框架的设计阶段完全可以使用从上到下的方式进行设计。也就是不去考虑框架怎么实现,而是以一个使用者的身份来写一个框架的示例网站,API怎么简单怎么舒服就怎么设计,只从使用者的角度来考虑问题。对于相关用到的类,直接写一个空的类(能用接口的尽量用接口,你的目的只是通过编译而不是能运行起来),让程序可以通过编译就可以了。你可以从框架的普通使用开始写这样一个示例网站,然后再写各种扩展应用,在此期间你可能会用到框架内部的20个类,这些类就是框架的接入类,在你的示例网站通过编译的那刹那,其实你已经实现了框架的接入层的设计。

这里值得一说的是API的设计蕴含了非常多的学问以及经验,要在目标平台设计一套合理易用的API首先需要对目标平台足够了解,每一个平台都有一些约定俗成的规范,如果设计的API能符合这些规范那么开发人员会更容易接受这个框架,此外还有一些建议:

之所以我们把API的设计先行,而不是让框架的设计先行是因为这样我们更容易设计出好用的API,作为框架的实现者,我们往往会进行一些妥协,我们可能会为了在框架内部DRY 而设计出一套丑陋的API让框架的使用者去做一些重复的工作;我们也可能会因为想让框架变得更松耦合强迫框架的使用者去使用到框架的一些内部API去初始化框架的组件。如果框架不是易用的,那么框架的内部设计的再合理又有什么意义?

尽量少暴露一些框架内部的类名吧,对于框架的使用者来说,你的框架对他一点都不熟悉,如果要上手你的框架需要学习一到两个类尚可接受,如果要使用到十几个类会头晕脑胀的,即使你的框架有非常多的功能以及配置,可以考虑提供一个入口类,比如创建一个ConfigCenter类作为入口,让使用者可以仅仅探索这个类便可对框架进行所有的配置。

一个好的框架是可以让使用者少犯错误的,框架的设计者务必要考虑到,框架的使用者没有这个业务来按照框架的最佳实践来做,所以在设计API的时候,如果你希望API的使用者一定要按照某个方式来做的话,可以考虑设置一个简便的重载来加载默认的最合理的使用方式而不是要求使用者来为你的方法初始一些什么依赖,同时也可以在API内部做一些检测,

如果发现开发人员可能会犯错进行一些提示或抛出异常。好的框架无需过多的文档,它可以在开发人员用的时候告知它哪里错了,最佳实践是什么,即便他们真的错了也能以默认的更合理的方式来弥补这个错误。

建议所有的API都有一套统一的规范,比如入口都叫XXXCenter或XXXManager,而不是叫XXXCenter、YYYManager和ZZZService。API往往需要进行迭代和改良的,在首个版本中把好名字用掉也不一定是一个好办法,最好还是给自己的框架各种API的名字留一点余地,这样以后万一需要升级换代不至于太牵强。

下一步工作就是把项目中那些空的类按照功能进行划分。目的很简单,就是让你的框架的100个类或接口能够按照功能进行拆分和归类,这样别人一打开你的框架就可以马上知道你的框架分为哪几个主要部分,而不是在100个类中晕眩;还有因为一旦在你的框架有使用者后你再要为API相关的那些类调整包就比困难了,即使你在创建框架的时候觉得我的框架就那么十几个类无需进行过多的分类,但是在将来框架变大又发现当初设计的不合理,无法进行结构调整就会变得很痛苦。因此这个工作还是相当重要的,对于大多数框架来说,可以有几种切蛋糕的方式:

分层。我觉得框架和应用程序一样,也需要进行分层。传统的应用程序我们分为表现层、逻辑层和数据访问层,类似的对于很多框架也可以进行横向的层次划分。要分层的原因是我们的框架要处理的问题是基于多层抽象的,就像如果没有OSI七层模型,要让一个HTTP应用去直接处理网络信号是不合理的也是不利于重用的。举一个例子,如果我们要写一个基于Socket的RPC的框架,我们需要处理方法的代理以及序列化,以及序列化数据的传输,这完全是两个层面的问题,前者偏向于应用层,后者偏向于网络层,我们完全有理由把我们的框架分为两个层面的项目(至少是两个包),rpc.core和rpc.socket,前者不关心网络实现来处理所有RPC的功能,后者不关心RPC来处理所有的Socket功能,在将来即使我们要淘汰我们的RPC的协议了,我们也可以重用rpc.socket项目,因为它和RPC的实现没有任何关系,它关注的只是socket层面的东西。

横切。刚才说的分层是横向的分割,横切是纵向的分割(横切是跨多个模块的意思,不是横向来切的意思)。其实横切关注点就是诸如日志、配置、缓存、AOP、IOC等通用的功能,对于这部分功能,我们不应该把他们和真正的业务逻辑混淆在一起。对于应用类项目是这样,对于框架类项目也是这样,如果某一部分的代码量非常大,完全有理由为它分出一个单独的包。对于RPC项目,我们可能就会把客户端和服务端通讯的消息放在common包内,把配置的处理单独放在config包内。

功能。也就是要实现一个框架主要解决的问题点,比如对于上面提到的RPC框架的core

部分,可以想到的是我们主要解决是客户端如何找到服务端,如何把进行方法调用以及把方法的调用信息传给目标服务端,服务端如何接受到这样的信息根据配置在本地实例化对象调用方法后把结果返回客户端三大问题,那么我们可能会把项目分为routing、client、server 等几个包。

如果是一个RPC框架,大概是这样的结构:

对于我们的Web MVC框架,举例如下:

我们可以有一个mvc.core项目,细分如下的包:

common:公共的一组件,下面的各模块都会用到

config:配置模块,解决框架的配置问题

startup:启动模块,解决框架和Servlet如何进行整合的问题

plugin:插件模块,插件机制的实现,提供IPlugin的抽象实现

routing:路由模块,解决请求路径的解析问题,提供了IRoute的抽象实现和基本实现controller:控制器模块,解决的是如何产生控制器

model:视图模型模块,解决的是如何绑定方法的参数

action:action模块,解决的是如何调用方法以及方法返回的结果,提供了IActionResult 的抽象实现和基本实现

view:视图模块,解决的是各种视图引擎和框架的适配

filter:过滤器模块,解决是执行Action,返回IActionResult前后的AOP功能,提供了IFilter 的抽象实现以及基本实现

我们可以再创建一个mvc.extension项目,细分如下的包:

filters:一些IFilter的实现

results:一些IActionResult的实现

routes:一些IRoute的实现

plugins:一些IPlugin的实现

这里我们以IXXX来描述一个抽象,可以是接口也可以是抽象类,在具体实现的时候根据需求再来确定。

这种结构的划分方式完全吻合上面说的切蛋糕方式,可以看到除了横切部分和分层部分,作为一个Web MVC框架,它核心的组件就是routing、model、view、controller、action(当然,对于有些MVC框架它没有route部分,route部分是交由Web框架实现的)。

如果我们在这个时候还无法确定框架的模块划分的话,问题也不大,我们可以在后续的搭建龙骨的步骤中随着更多的类的建立,继续理清和确定模块的划分。

经过了设计的步骤,我们应该心里对下面的问题有一个初步的规划了:

我们的框架以什么形式来提供如何优雅的API?

我们的框架包含哪些模块,模块大概的作用是什么?

搭建龙骨

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

建龙骨也就是搭建一套抽象层。这么说可能有点抽象,我们还是来想一下如果要做一个Web MVC框架,需要怎么为上面说的几个核心模块进行抽象(我们也来体会一下框架中一些类的命名,这里我们为了更清晰,为所有接口都命名为IXXX,这点不太符合Java的命名规范):

routing MVC的入口是路由

每一个路由都是IRoute代表了不同的路由实现,它也提供一个getRouteResult()方法来返

回RouteResult对象

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

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

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

controller 路由下来是控制器

我们有IControllerFactory来创建Controller,提供createController()方法来返回IController IController代表控制器,提供一个execute()方法来执行控制器

我们实现一个框架自带的DefaultControllerFactory来以约定由于配置的方式根据约定规则

以及路由数据RouteResult来找到IController并创建它

我们为IController提供一个抽象实现,AbstractController,要求所有MVC框架的使用者创建的控制器需要继承AbstractController,在这个抽象实现中我们可以编写一些便捷的API

以便开发人员使用,比如view()方法、file()方法、redirect()方法、json()方法、js()方法等

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

我们有IActionResult来代表Action返回的结果,提供一个execute()方法来执行这个结果

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

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

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

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

刚才提到了IFilter,代表的是一个过滤器,我们提供IActionFilter对方法的执行前后进行过滤,提供IResultFilter对IActionResult执行前后进行过滤

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

我们的框架可以实现一些自带的IFilterProvider,比如AnnotationFilterProvider通过扫描Action或Controller上的注解来获取需要执行的过滤器信息;比如我们还可以实现GlobalFilterProvider,开发人员可以直接通过配置或代码方式告知框架应用于全局的IFilter 既然我们实现了多个IFilterProvider,我们自然需要有一个类来管理这些IFilterProvider,我们实现一个FilterProviders类并提供getFilters()方法(这和我们的Routes类来管理IRoute 是类似的,命名统一)

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

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

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

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

我们的框架可以实现常见的一些模版引擎,比如FreemarkerViewEngine、VelocityViewEngine 等,VelocityViewEngine返回的ViewEngineResult自然包含的是一个实现IView的VelocityView,不会返回其它引擎的IView

同样的,我们是不是需要一个ViewEngines来管理所有的IViewEngine呢,同样也是实现findViewEngine()方法

common 这里可以放一些项目中各个模块都要用到的一些东西

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

比如各种helper或utility

接下去就不再详细阐述model、plugin等模块的内容了。

看到这里,我们来总结一下,我们的MVC框架在组织结构上有着高度的统一:

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

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

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

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

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

实现各种IyyyProvider和Izzz接口来完善支线流程

走通主线流程

所谓走通主线流程,就是让这个框架可以以一个HelloWorld形式跑起来,这就需要把几个核心类的核心方法使用最简单的方式进行实现,还是拿我们的MVC框架来举例子:

从startup开始,可能需要实现ServletContextListener来动态注册我们框架的入口Servlet,暂且起名为DispatcherServlet吧,在这个类中我们需要走一下主线流程

调用Routes.findRoute()获得IRoute

调用IRoute.getRouteResult()来获得RouteResult

使用拿到的RouteResult作为参数调用DefaultControllerFactory.createController()获得IController(其实也是AbstractController)

调用IController.execute()

在config中创建一个IConfig作为一种配置方式,我们实现一个DefaultConfig,把各种默认实现注册到框架中去,也就是DefaultRoute、DefaultControllerFactory、DefaultActionInvoker,然后把各种IViewEngine加入ViewEngines

然后需要完成相关默认类的实现:

实现Routes.findRoute()

实现DefaultRoute.getRouteResult()

实现DefaultControllerFactory.createController()

实现AbstractController.execute()

实现DefaultActionInvoker.invokeAction()

实现ViewResult.execute()

实现ViewEngines.findViewEngine()

实现VelocityViewEngine.getViewEngineResult()

实现VelocityView.render()

宅男福利社www.zhainan.hk申博官网https://www.360docs.net/doc/1f10697453.html,澳门金沙官网https://www.360docs.net/doc/1f10697453.html,

在这一步,我们并不一定要去触碰filter和model这部分的内容,我们的主线流程只是解析路由,获得控制器,执行方法,找到视图然后渲染视图。过滤器和视图模型的绑定属于增强型的功能,属于支线流程,不属于主线流程。

虽然在这里我们说了一些MVC的实现,但本文的目的不在于教你实现一个MVC框架,所以不用深究每一个类的实现细节,这里想说的是,在前面的龙骨搭建完后,你会发现按照这个龙骨为它加一点肉上去实现主要的流程是顺理成章的事情,毫无痛苦。在整个实现的过程中,你可以不断完善common下的一些context,把方法的调用参数封装到上下文对象中去,不但看起来清楚且符合开闭原则。到这里,我们应该可以跑起来在设计阶段做的那个示例网站的HelloWorld功能了。

在这里还想说一点,有些人在实现框架的时候并没有搭建龙骨的一步骤,直接以非OOP的方式实现了主线流程,这种方式有以下几个缺点:

不容易做到SRP单一指责原则,你很容易把各种逻辑都集中写在一起,比如大量的逻辑直接写到了DispatcherServlet中,辅助一些Service或Helper,整个框架就肥瘦不匀,有些类特别庞大有些类特别小。

不容易做到OCP开闭原则,扩展起来不方便需要修改老的代码,我们期望的扩展是实现新的类然后让框架感知,而不是直接修改框架的某些代码来增强功能。

很难实现DIP依赖倒置原则,即使你依赖的确实是IService但其实就没意义,因为它只有一个实现,只是把他当作帮助类来用罢了。

实现各种支线流程

我们想一下,对于这个MVC框架有哪些没有实现的支线流程?其实无需多思考,因为我们在搭建龙骨阶段的设计已经给了我们明确的方向了,我们只需要把除了主线之外的那些龙骨上也填充一些实体即可,比如:

实现更多的IRoute,并注册到Routes

实现更多的IViewEngine,并注册到ViewEngines

实现必要的IFilterProvider以及FilterProviders,把IFilterProvider注册到FilterProviders 增强DefaultActionInvoker.invokeAction()方法,在合适的时候调用这些IFilter

实现更多的IActionResult,并且为AbstractController实现更多的便捷方法来返回这些IActionResult

……实现更多model模块的内容和plugin模块的内容

实现了这一步后,你会发现整个框架饱满起来了,每一个包中不再是仅有的那些接口和默认实现,而且会有一种OOP的爽快感,爽快感来源于几个方面:

面对接口编程抽象和多态的放心安心的爽快感

为抽象类实现具体类享受到父类大量实现的满足的爽快感

实现了大量的接口和抽象类后充实的爽快感

我们再来总结一下之前说的那些内容,实现一个框架的第一大步就是:

设计一套合理的接口

为框架进行模块划分

为框架搭建由抽象结构构成的骨架

在这个骨架的基础上实现一个HelloWorld程序

为这个骨架的其它部分填充更多实现

经过这样的一些步骤后可以发现这个框架是很稳固的,很平衡的,很易于扩展的。其实到这里很多人觉得框架已经完成了,有血有肉,其实个人觉得只能说开发工作实现了差不多30%,后文会继续说,毕竟直接把这样一个血肉之躯拿出去对外有点吓人,我们需要为它进行很多包装和完善。

单元测试

在这之前我们写的框架只能说是一个在最基本的情况下可以使用的框架,作为一个框架我们无法预测开发人员将来会怎么使用它,所以我们需要做大量的工作来确保框架不但各种功能都是正确的,而且还是健壮的。写应用系统的代码,大多数项目是不会去写单元测试的,原

因很多:

项目赶时间,连做一些输入验证都没时间搞,哪里有时间写测试代码。

项目对各项功能的质量要求不高,只要能在标准的操作流程下功能可用即可。

项目基本不会去改或是临时项目,一旦测试通过之后就始终是这样子了,没有迭代。

……

对于框架,恰恰相反,没有配套的单元测试的框架(也就是仅仅使用人工的方式进行测试,比如在main中调用一些方法观察日志或输出,或者运行一下示例项目查看各种功能是否正

常,是非常可怕的)原因如下:

自动化程度高,回归需要的时间短,甚至可以整合到构建过程中进行,这是人工测试无法实现的。

框架一定是有非常多的迭代和重构的,每一次修改虽然只改了A功能,但是可能会影响到B 和C功能,人工测试的话你可能只会验证A是否正常,容易忽略B和C,使用单元测试的话只要所有功能都有覆盖,那么几乎不可能遗漏因为修改导致的潜在问题,而且还能反馈出来因为修改导致的兼容性问题。

之前说过,一旦框架开放出去,框架的使用者可能会以各种方式在各种环境来使用你的框架,环境不同会造成很多怪异的边界输入或非法输入,需要使用单元测试对代码进行严格的边界测试,以确保框架可以在严酷的环境下生存。

单元测试还能帮助我们改善设计,在写单元测试的时候如果发现目标代码非常难以进行模拟难以构建有效的单元测试,那么说明目标代码可能有强依赖或职责过于复杂,一个被单元测试高度覆盖的框架往往是设计精良的,符合高内聚低耦合的框架。

如果框架的时间需求不是特别紧的话,单元测试的引入可以是走通主线流程的阶段就引入,越早引入框架的成熟度可能就会越高,以后重构返工的机会会越小,框架的可靠性也肯定会大幅提高。之前我有写过一个类库项目,并没有写单元测试,在项目中使用了这个类库一段

时间也没有出现任何问题,后来花了一点时间为类库写了单元测试,出乎我意料之外的是,

我的类库提供的所有API中有超过一半是无法通过单元测试的(原以为这是一个成熟的类库,其实包含了数十个BUG),甚至其中有一个API是在我的项目中使用的。你可能会问,为什么在使用这个API的时候没有发生问题而在单元测试的时候发生问题了呢?原因之前提到过,我是框架的设计者,我在使用类库提供的API的时候是知道使用的最佳实践的,因此我在使用的时候为类库进行了一个特别的设置,这个问题如果不是通过单元测试暴露的话,那么其它人在使用这个类库的时候基本都会遇到一个潜在的BUG。

示范项目

写一个示例项目不仅仅是为了给别人参考,而且还能够帮助自己去完善框架,对于示例项目,

最好兼顾下面几点:

是一个具有一定意义的网站或系统,而不是纯粹为了演示特性而演示。这是因为,很多时候只有那些真正的业务逻辑才会暴露出问题,演示特性的时候我们总是有一些定势思维会规避很多问题。或者可以提供两个项目,一个纯粹演示特性,一个是示例项目。

覆盖尽可能多的特性或使用难点,在项目的代码中提供一些注释,很多开发人员不喜欢阅读文档,反而喜欢看一下示例项目直接上手(模仿示例项目,或直接拿示例项目中的代码来修改)。

项目中的代码,特别是涉及到框架使用的代码一定要规范,原因上面也说了,作为框架的设计者你不会希望大家复制的代码粘帖的代码一团糟吧。

如果你的项目针对的不仅仅是Web项目,那么示例项目最好提供Web和桌面两个版本,一来你自己容易发现因为环境不同带来的使用差异,二来可以给予不同类型项目不同的最佳实践。

完善日志和异常

一个好的框架不但需要设计精良,日志和异常的处理是否到位也是非常重要的标准,这里有

一些反例:

日志的各种级别的使用没有统一的标准,甚至是永远只使用某个级别的日志。

几乎没有任何的日志,框架的运行完全是一个黑盒。

记录的日志多且没有实际含义,只是调试的时候用来观察变量的内容。

异常类型只使用Exception,不使用更具体化的类型,没有自定义类型。

异常的消息文本只写"错误"字样,不写清楚具体的问题所在。

永远只是抛出异常,让异常上升到最外层,交给框架的使用者去处理。

用异常来控制代码流程,或本应该在方法未达到预期效果的时候使用异常却使用返回值。其实个人觉得,一个框架的主逻辑代码并不一定是最难的,最难的是对一些细节的处理,让框架保持一套规范的统一的日志和异常的使用反而对框架开发者来说是一个难点,下面是针对记录日志的一些建议:

1、首先要对框架使用的日志级别有一个规范,比如定义:

DEBUG:用于观察程序的运行流程,仅在调试的时候开启

INFO:用于告知程序运行状态或阶段的变化,可以在测试环境开启

WARNING:用于告知程序可以自己恢复的错误或异常,或不影响主线流程执行的错误或问题,可以在正式环境开启

ERROR:用于告知程序无法恢复,主线流程中断,需要开发或运维人员知晓干预的错误或异常,需要在正式环境开启

2、按照上面的级别规范,在需要记录日志的地方记录日志,除了DEBUG级别的日志其它日志不能记录过多,如果框架总是在运行的时候输出几十个WARNNING也容易让使用者

忽略真正的问题。

3、日志记录的消息需要是明确的,最好包含一些上下文信息,比如"无法在xxx下找到配置文件xxx.config,框架将采用默认的配置",而不是"加载配置失败!"

下面是一些针对使用异常的建议:

框架由于配置错误或使用错误或运行错误,不能完成API名字所表示的功能,考虑抛出转

化后的异常,让调用者知道发什么了什么情况,同时框架可以建立自己的错误处理机制

对于可以预料的错误,并且错误类型可以枚举,考虑以返回值的形式告知调用者可以根据不同的结果来处理后续的逻辑

对于框架内部功能实现上遇到的调用者无能力解决的错误,如果错误可以重试或不影响返回,可以记录警告或错误日志

可以为每一个模块都陪伴自定义的异常类型,包含相关的上下文信息(比如ViewException 可以包含ViewContext),这样出现异常可以很方便知晓是哪个模块出现问题并且可以得到出现异常时的环境信息

如果异常跨了实现层次(比如从框架到应用),那么最好进行一下包装转换(比如把文件读取失败的提示改为加载配置文件失败的提示),否则上层人员是不知道怎么处理这些内部问题的,内部问题需要由框架自己来处理

异常的日志中可以记录和当前操作密切相关的参数信息,比如搜索的路径,视图名等等,有关方法的信息不用过多记录,异常一般都带有调用栈信息

如果可能的话,出现异常的时候可以分析一下为什么会出现这样的问题,在异常信息中给一些解决问题的建议或帮助链接方便使用者排查问题

异常处理从坏到好的层次是,出现了严重问题的时候:

使用者什么都不知道,程序的完整性和逻辑得到破坏

使用者既不知道出现了什么问题也不知道怎么去解决

使用者能明确知道出现了什么问题,但无法去解决

使用者不但知道发生了什么,还能通过异常消息的引导快速解决问题

完善配置

配置的部分可以留到框架写的差不多了再去写,因为这个时候已经可以想清楚哪些配置是:需要公开出去给使用者配置的,并且配置会根据环境不同而不同

需要公开出去给使用者来配置的,配置和部署环境无关

仅仅需要在框架内供框架开发人员来配置的

无需是一个配置,只要在代码中集中存储这个设定即可

一般来说配置有几种方式:

通过配置文件来配置,比如XML文件、JSON文件或property文件

通过注解或特性(Annotation/Attribute)方式(对类、方法、参数)进行配置

通过代码方式进行配置(比如单独的配置类,或实现配置类或调用框架的配置API)

很多框架提供了多种配置方式,比如Spring MVC同时支持上面三种方式的配置,个人觉得

对配置,我们还是应该区别对待,而不是无脑把所有的配置项都同时以上面三种方式提供配置,我们要考虑高内聚和低耦合原则,对于Web框架来说,高内聚需要考虑的比低耦合更

多,我的建议是对不同的配置项提供不同的配置方式:

如果配置项目是需要让使用者来配置的,特别是和环境相关的,那么最好使用配置方式来配置,比如开放的端口、内存、线程数配置,不过要注意:

所有配置项目需要有默认值,如果找不到配置使用默认值,如果配置不合理使用默认值(你不会希望使用你框架的人把框架内部的线程池的min设置为999999,或定时器的间隔设置为0毫秒吧?)

框架启动的时候检测所有配置,如果不合理给予提示,大多人只会在启动的时候看一下日志,使用的时候根本就不管

不知道大家对于配置文件的格式倾向于XML呢还是JSON呢还是键值对呢?

对于所有仅在开发时进行的配置,都尽量不要去使用配置文件,并且让配置尽量和它所配置的对象靠在一起:

如果是对框架整体性进行的设置扩展类型的配置,那就可以提供代码方式进行配置,比如我们要实现的MVC框架的各种IRoute、IViewEngine等,最好可以提供IConfig接口让开发人员可以去实现接口,这样他们可以知道有哪些东西可以配置,代码就是文档

如果是那种对模型、Action进行的配置,比如模型的验证规则、Filter等一律采用注解的方式进行配置

有的人说使用配置文件进行配置非常灵活,使用代码方式和注解方式来配置不灵活而且可能有侵入性。我觉得还是要权衡对待,我的建议是不要把太多框架内在的东西放在配置文件中,增加使用者的难度(而且很多时候,大多数人只是复制配置为了完成配置而配置,并不是为了真正的灵活性而去使用配置文件来配置你的框架,看看网上这么所SSH配置文件的抄来抄去就知道了)。

最后,我建议很多太内部的东西对于轻量级的应用型框架可以不去提供任何配置选项,只需要在某个常量文件中定义即可,让真正有需求进行二次开发的开发人员去修改,对于一个框架如果一下子暴露上百个"高级"配置项给使用者,他们会晕眩的。

提供状态服务

所谓状态服务就是反映框架内部运作状态的服务,很多开源服务或系统(Nginx、Mongodb 等)都提供了类似的模块和功能,作为框架的话我觉得也有必要提供一些内部信息(主要是配置、数据统计以及内部资源状态)出来,这样使用你框架的人可以在开发的时候或线上运作的时候了解框架的运作状态,我们举两个例子,对于一个我们之前提到的Web MVC框

架来说,可以提供这些信息:

路由配置

视图引擎配置

过滤器配置

对于一个Socket框架来说,有一些不同,Socket框架是有状态的,其状态服务提供的信息

除了当前生效的配置信息之外,更多的是反映当前框架内部一些资源的状态以及统计数据:各种配置(池配置、队列配置、集群配置)

Socket相关的统计数据(总打开、总关闭、每秒收发数据、总收发数据、当前打开等等)

各种池的当前状态

各种队列的当前状态

状态服务可以以下面几种形式来提供:

代码方式,比如如果开发人员实现了IXXXStateAware接口的话,就可以为它的实现类来推送一些信息,也可以直接在框架中设立一个StateCenter来公开框架所有的状态信息

自动日志方式,比如如果在配置中开启了stateLoggingInterval=60s的选项,我们的框架就会自动一分钟一次输出日志,显示框架内部的状态

接口方式,比如开放一个Restful的接口或额外监听一个端口来提供状态服务,方便使用者可以拿原始的数据和其它监控平台进行整合

内部外部工具方式

比如我们可以直接为框架提供一个专门的页面(/_route)来呈现路由的配置(甚至我们可以在这个页面上让开发人员可以直接输入地址来测试路由的匹配情况,状态服务不一定只能看),这样在开发和测试的时候可以更方便调试

我们也可以为框架提供一个专有工具来查看框架的状态信息(当然,这个工具其实可能就是连接框架的某个网络服务来获取数据),这样即使框架在多个机器中使用,我们可能也只有一个监控工具即可

如果没有状态服务,那么在运行的时候框架就是一个黑盒,反之如果状态服务足够详细的话,可以方便我们排查一些功能或性能问题。不过要注意的一点是,状体服务可能会降低框架的性能,我们可能需要对状态服务也进行一次压测,排除状态服务中损耗性能的地方(有些数据的收集会意想不到得损耗性能)。

检查线程安全

框架对多线程环境支持的是否好,是框架质量的一个重要的评估标准,往往可以看到甚至有一些成熟的框架也会有多线程问题。这里涉及几个方面:

1,你无法预料框架的使用者会怎么样去实例化和保存你的API的入口类,如果你的入口类被用成为了一个单例,在并发调用的情况下会不会有单线程问题?

这是一个老话题,之前已经说过很多次,你在设计框架的时候心里如果把一个类定位成了单例的类但却没有提供单例模式,你是无法要求使用者来帮你实现单例的。这其中涉及的不仅仅是多线程问题,可能还有性能问题。比如见过某分布式缓存的客户端的CacheClient在文档中要求使用者针对一个缓存集群保持一个CacheClient的单例(因为其中有了连接池),但是用的人还是每一次都实例化了一个CacheClient出来,几小时后就会产生几万个半死的Socket导致网络奔溃。又见过某类库的入口工厂的代码注释中写了要求使用的人把XXXFactory作为单例来使用(因为其中缓存了大量数据),但是用的人就没有注意到这个注释,每一次都实例化了一个XXXFactory,造成GC的崩溃。所以我觉得作为框架的设计者开发人员,最好还是把框架的最佳实践直接做到API中,使得使用者不可能出错(之前说过一句话,再重复一次,好的框架不会让使用的人犯错)。你可能会说对于CacheClient 的例子,不可能做成单例的,因为我的程序可能需要用到多个缓存的集群,换个思路,我们完全可以在封装一层,通过一个CacheClientCreator之类的类来管理多个单例的CacheClient。即使在某些极端的情况下,你不能只提供一条路给使用者去走,也需要在框

架内做一些检测机制,及时提醒使用者"我们发现您这样使用了框架,这可能会产生问题,你本意是否打算那样做呢?"

2,如果你的入口类本来就是单例的,那么你是类中是否持有共享资源,你的API在并发的情况下被调用是否可以确保这些资源的线程安全?在解决多线程问题的时候往往有几个难点:

百密难有一疏,你很难想到这段代码会有人这样去并发调用。比如某init()方法,某config()方法,你总是假设使用者会调用并且仅调用一次,但事实不一定这样,有的时候调用者自己也不清楚我的容器会调用我这段代码多少次。

好吧,解决多线程问题各种烦躁,那就对各种涉及到共享资源的方法全部加锁。对方法进行粗犷(粒度)的锁可能会导致性能急剧下降甚至是死锁问题。

自以为使用了优雅的无锁代码或并发容器但却达不到目的。我们往往在大量使用了并发集合心中暗自窃喜解决了多线程问题的同时又达到了极佳的性能,但你以为这样是解决了线程安全问题但其实根本就没有,我们不能假设A和B都方法是线程安全的,但对A和B方法调用的整个代码段是线程安全的。

对于多线程问题,我没有好的解决办法,不过下面的几条我觉得可以尝试:

需要非常仔细的过一遍代码,把涉及到共享资源的地方,以及相关的方法和类列出来,不要去假设什么,只要API暴露出去了则假设它可能被并发调用。共享资源不一定是静态资源,哪怕资源是非静态的,在并发环境下对相同对象的资源进行操作也可能产生问题。

一般而言对于公开的API,作为框架的设计者我们需要确保所有的静态方法(或但单例类的实例方法)是线程安全的,对于实例方法我们可以不这么做(因为性能原因),但是需要在注释中明确提示使用者方法的非线程安全,如果需要并发调用请自行处理线程安全问题。可以看看是否有可能让这些资源(字段)变为方法内的局部变量,有的时候我们并不是真正的需要类持有一个字段,只是因为多个方法要使用相同的东西,随手一写罢了。

对于使用频率低的一些方法相关的一些资源没有必要使用并发容器,直接采用粗狂的方式进行资源加锁甚至是方法级别加锁,先确保没有线程安全,如果以后做压测出现性能问题再来解决。

对于使用频率高的一些方法相关的一些资源可以使用并发容器,但需要仔细思考一下代码是否会存在线程安全问题,必要的话为代码设计一些多线程环境的单元测试去验证。

性能测试和优化

之前也提到过,你不会预测到你的项目会在怎么样的访问量下使用,我们不希望框架和同类的框架相比有明显的性能差距(如果你做的是一个ORM框架或RPC框架,这个工作就是

必不可少的),所以在框架基本完成后我们需要做Benchmark:

确定几个测试用例,尽量覆盖主流程和一些重要扩展

找几个主流的同类型框架,实现相同的测试用例,实现到时候要单纯一点,尽量不要再依赖其它外部框架

为这些框架和自己的框架,使用压力测试工具在相同的环境和平台来跑这些测试用例,使用图表绘制在不同的压力下的执行时间(以及内存和CPU等主要资源的消耗情况)

如果出现明显的差距则用性能分析工具进行排查和优化,比如:

优化框架内的线程安全的实现方式

为框架内的代码做一些缓存(缓存反射得到的元数据等等)

减少调用层次

这些调整可能会打破原来的主线流程或让代码变得难以理解,需要留下相关注释

不断重压力测试和优化的过程,每次尝试优化5%~20%的性能,虽然越到后来可能会越难,如果发现实在无法优化的话(性能分析工具显示性能的分布已经很均匀了),可以看一下其它框架对于这部分工作实现的代码逻辑

封装和扩展

个人觉得一个框架如果只是能用那是第一个层次,能很方便的进行扩展或二次开发那是另外一个层次,如果我们龙骨阶段的工作做的足够好,框架是一个立体饱满的框架,那么这部分

的工作量就会小很多,否则我们需要对框架进行不少的重构以便可以达到这个层次。

我们需要纵览一下框架的所有类型,看看有哪些类型我们是打算提供开发人员进行增强、扩展或替换的,对这些类型进行响应的结构调整。

比如希望被增强,则需要从继承的角度来考虑

比如希望被扩展,则需要从Provider的角度来考虑

比如希望被替换,则需要在配置中提供组件的替换

我们需要再为这些类型进行精细化的调整:

检查是否该封闭的封闭了,该开放的开放了

增强扩展或替换是否会带来副作用

对于新来的外来类型,接收和使用的时候做足够的检查

相关日志的完善

重构还是重构

光是重构这个事情其实就可以说一本书了,其实我有一点代码的洁癖,这里列一些我自己写

代码的时候注重的地方:

格式:每次提交代码的时候使用IDE来格式化你的代码和引用(当然,实现可能需要配置IDE为你喜欢的代码风格)

命名:保持整个类和接口命名统一,各种er,Provider、Creator、Initializer、Invoker、Selector 代表的是一件事情,不要使用汉语拼音命名,如果英文不够好的话多查一下字典,有的时候我甚至会因为一个命名去阅读一些源代码看看老外是怎么命名这个对象或这个方法的

访问控制修饰符:这是一个非常难做好的细节,因为有太多的地方有访问控制修饰符,究竟是给予什么级别的修饰符往往又取决于框架的扩展。可以在一开始的时候给尽量小的权限,在必要的时候慢慢提升,比如对于方法除了一定要给public的地方(比如公共API或实现接口),尽量都给private,在有继承层次关系的时候去给到protected,对于类可以都给默认包/程序集权限,产生编译错误的时候再去给到public

属性/getter、setter:对于非POJO类字段的公开也要仔细想一下,是否有必要有setter,因为一旦外部可以来设置类的某个内部字段,那么不仅仅可能改变了类的内部状态,你还要考虑的是怎么处理这种改变,是不是有线程安全问题等等,甚至要考虑是否有必要开放getter,是否应该把类内部的信息公开给外部

方法:思考每一个方法在当前的类中存在是否合理,这是否属于当前类应该做的事情,方法是否做了太多事情太少事情

参数:需要思考,对于调用每一个方法的参数,应该是传给方法,还是让方法自己去获取;应该传多个参数,还是封装一个上下文给到方法

常量:尽量用枚举或静态字符串来代替框架使用到的一些常量或幻数,需要为常量进行一个分类不能一股脑堆在一个常量类Consts中

除了上面说的一些问题,我觉得对于重构,最重要的一句话就是:不要让同一段代码出现两

遍,主要围绕这个原则进行重构往往就会解决很多设计问题,要实现这个目标可能需要:干差不多活的类使用继承来避免代码重复(提炼超类),使用模版方法来把差异留给子类实现

构造方法可以层次化调用,主构造方法只要一个就可以了,不要在构造方法中实现太多逻辑如果方法的代码有重复可以考虑对方法提取出更小的公共方法来调用(提炼方法),也可以考虑使用Lambda表达式进行更小粒度重复代码的提取(提炼逻辑)

可以使用IDE或一些代码分析工具来分析重复代码,如果你能想尽一切办法来避免这些重复的话,代码质量可以提高一个层次

其实也不一定是在重构的时候再去处理上面所有的问题,如果在写代码的时候都带着这些意识来写的话那么重构的负担就会小一点(不过写代码思想的负担比较大,需要同时考虑封装问题、优雅问题、日志异常问题、多线程问题等等,所以写一套能用的代码和写一套好的代码其实不是一回事情)。

项目文档

如果要别人来使用你的框架,除了示例项目来说提供和维护一份项目文档是很有必要的,我

建议文档分为这几个部分:

特性Features:

相当于项目的一个宣传手册,让别人能被你项目的亮点所吸引

每一个特性可以是一句话来介绍

新手入门Get started:

介绍框架的基本定位和作用

从下载开始,通过一步一步的方式让用户了解怎么把框架用起来

整个文档的阅读时间在10分钟以内

新手教程Tutorials:

提供5~10篇文章站在使用者的角度来介绍项目的主要功能点

还是通过一步一步的方式,教大家使用框架完成一个小项目(比如CRUD)

介绍框架使用的最佳实践

整个文档的阅读时间在8小时内

手册Manual:

介绍项目的定位和理念

详细介绍项目的每一个功能点,可以站在框架设计者的角度多介绍一些理念

详细介绍项目的每一个配置,以及默认配置和典型配置

详细介绍项目的每一个扩展点和替换点

文档最好不是带格式的,方便以后适配各种文档生成器和开源网站

开源

开源的好处是有很多人可以看到你的代码帮助你改进,你的框架也可能会在更多的复杂环境下使用,框架的发展会较快框架的代码质量也会有很大的提升。

要把框架进行开源,除了上面的各种工作之外可能还有一些额外的工作需要做:

选择一个合适的License,并且检测自己选择的License与使用到的类库的License是否兼容,在代码头的地方标记上License。

要确保每一个人都可以在自己的环境中可以构建你的代码,尽量使用Maven等大家熟悉的构建工具来管理依赖和构建。

选择诸如Github等平台来管理源代码,并以良好的格式上传你的文档,有条件的话对示例子网站进行部署。

如果你希望你的代码让更多的人一起来参与开发,那么需要制定和公开一些规范,比如风格、命名、提交流程、测试规范、质量要求等等。

开源后时刻对项目进行关注,对各种反馈和整合请求进行及时的反馈,毕竟开源是让别人来帮你一起改进代码,不是单纯让别人来学习你的代码也不是让别人来帮你写代码。

看到这里你可能相信我一开始的话了吧,框架可以使用到完善可以商用差距还是很大的,而且还要确保在迭代的过程中框架不能偏离开始的初衷不能有很大的性能问题出现,任重道远。

用Dreamweaver建立框架页面

实验8 用Dreamweaver建立框架页面 实验目的:通过实验,掌握如何如何创建和应用框架页面,了解框架的基本分布结构和各个框架页面之间的相互联系。 实验步骤: 1. 启动Dreamweaver程序,选择菜单“文件”“新建”命令,打开“新建文档”对话框。在对话框中“常规”标签下选择“类别”列表中的“框架集”选项,然后再右边的“框架集”列表中选择“上方固定”选项,如图8-1所示。单击“创建”按钮创建框架网页。 2. 选择菜单“窗口”“框架”命令,打开框架控制面板。 3. 用鼠标单击框架控制面板中的下部分,选中mainFrame框架。如图8-2所示: 图8-1 套用框架图11-2 选择框架集的子框架 4. 将鼠标放在选中的边框上,使鼠标变成双向箭头,然后拖动鼠标将该框架分成左右两个子框架。如图8-3所示。

图8-3 把主框架切分为子框架 5. 在框架编辑窗口中,单击顶部框架,选择菜单“文件”→“保存框架”命令,保存框架为页面。 6. 将光标停放到下部分框架的左边框家中,选择菜单“文件”→“保存框架”命令,保存框架为页面。 7. 按同样的方法,将右边的框架保存为页面。 8. 单击框架面板上最外层的边框,或单击页面编辑窗口中的最外层边框,使外框出现虚线。如图8-4所示: 图8-4选中整个框架

说明鼠标单击所选中的框架, 页面中的框架边框会出现虚线,所选 中的框架就是当前正在编辑的页面. 9. 选择菜单“文件”—>“保存 全部”命令,保存所有框架和框架集, 框架集文件名称为.如图8-5所示. 10. 单击框架面板上的topFrame框架,选中网页. 11. 打开属性面板,在属性面板上的“滚动”下拉菜单中选择“否”, 然后勾选旁边的“不能调整大小”复选框;在“边界宽度”和“边界高度”的文本框中都输入0,参数设置如图8-6所示. 图8-6 top框架的属性设置 说明框架属性面板上的“滚动”下拉菜单中有“是”.“否”.“自动”.和“默认”四项,其中选择“是”表示允许页面左右.上下出现滚动条;选择“自动”.“默认”表示根据网页内容,需要时自动显示滚动条;选择“否”表示不允许出现滚动条. 12. 单击top框架页面,在属性面板中单击“页面属性”按钮。 13. 打开“页面属性”对话框,在“左边框.右边框.上边框.下边框”各文本框中输入0,使网页边距都为0.单击“确定”返回框架页编辑窗口. 14. 单击“插入”面板上的“表格”按钮,插入2行4列,宽为100%的表格. 15. 打开属性面板,设置第2列两个表格背景颜色为“浅蓝色”(色标值为#E0E4F4),然后选择第4列单元格,设置同样的背景颜色;设置第3列单元格的背景颜色为“深蓝色”(色标值为#3A4593)

钢结构课程设计

中南大学 《钢结构基本原理》 课程设计 设计名称:钢框架主次梁设计 专业班级:土木1112班 姓名:周世超 学号: 指导老师:龚永智 设计任务书 (一)、设计题目 某钢平台结构(布置及)设计。 (二)、设计规范及参考书籍 1、规范 (1)中华人民共和国建设部. 建筑结构制图标准[S](GB/T50105-2001) (2)中华人民共和国建设部. 房屋建筑制图统一标准[S](GB/T50001-2001) (3)中华人民共和国建设部. 建筑结构荷载规范[S](GB5009-2001)(4)中华人民共和国建设部. 钢结构设计规范[S](GB50017-2003)(5)中华人民共和国建设部. 钢结构工程施工质量验收规范[S](GB50205-2001) 2、参考书籍

(1)沈祖炎等. 钢结构基本原理[M]. 中国建筑工业出版社,2006 (2)毛德培. 钢结构[M]. 中国铁道出版社,1999 (3)陈绍藩. 钢结构[M]. 中国建筑工业出版社,2003 (4)李星荣等. 钢结构连接节点设计手册(第二版)[M]. 中国建筑工业出版社,2005 (5)包头钢铁设计研究院?中国钢结构协会房屋建筑钢结构协. 钢结构设计与计算(第二版)[M]. 机械工业出版社,2006 (三)、设计内容 某多层图书馆二楼书库楼面结构布置示意图如图一所示,结构采用横向框架承重,楼面板为120mm厚的单向实心钢筋混凝土板。荷载的传力途径为:楼面板—次梁—主梁—柱—基础,设计中仅考虑竖向荷载与动荷载的作用。框架按照连续梁计算,次梁按照简支梁计算。其中框架柱为焊接H型钢,截面尺寸为H600X300X12X18,楼层层高取3.9米 采用的钢材为Q345,焊条为E50 柱网尺寸9 ×9,永久荷载5,活荷载10 活荷载分项系数为1.4 恒荷载分项系数为1.2 (四)、设计内容要求 1)验算焊接H型钢框架柱的承载能力,如不满足请自行调整 2)设计次梁截面CL-1(热轧H型钢)。 3)设计框架主梁截面KL-1(焊接工字钢)。 4)设计框架主梁短梁段与框架柱连接节点,要求采用焊缝连接,短

框架结构设计步骤

砼框架结构设计手算步骤 一.确定结构方案与结构布置 1.结构选型是否选用框架结构应先进行比较。根据何广乾的模糊评判法,砼结构8~18层首选框剪结构,住宅、旅馆则首选剪力墙。对于不需要电梯的多层采用框架较多。 2.平面布置注意L,l,l’,B的关系。 3.竖向布置注意高宽比、最大高度(分A、B两大类,B类计算和构造有更严格的要求),力求规则,侧向刚度沿竖向均匀变化。 4.三缝的设置按规范要求设置,尽量做到免缝或三缝合一。 5.基础选型对于高层不宜选用独立基础。但根据国勤兄的经验,对于小高层当地基承载力标准值300kpa 以上时可以考虑用独基。 6.楼屋盖选型 高层最好选用现浇楼盖 1)梁板式最多的一种形式。有时门厅,会议厅可布置成井式楼盖,其平面长宽比不宜大于1.5,井式梁间距为2.5~3.3m,且周边梁的刚度强度应加强。采用扁梁高度宜为1/15~1/18跨度,宽度不超过柱宽50,最好不超过柱宽。 2)密肋梁方形柱网或接近方形,跨度大且梁高受限时常采用。肋梁间距1~1.5m,肋高为跨度的1/30~1/20,肋宽150~200mm。 3)无梁楼盖地震区不宜单独使用,如使用应注意可靠的抗震措施,如增加剪力墙或支撑。 4)无粘结预应力现浇楼板一般跨度大于6m,板厚减薄降低层高,在高层中应用有一定技术经济优势。在地震区应注意防止钢筋端头锚固失效。 5)其他 二.初步确定梁柱截面尺寸及材料强度等级 1.柱截面初定分抗震和非抗震两种情况。对于非抗震,按照轴心受压初定截面。对于抗震,Ac=N/(a*fc) N=B*F*Ge*n B=1.3(边柱),1.2(等跨中柱),1.25(不等跨中柱)Ge=12~15kN/m2 a为轴压比fc为砼抗压强度设计值F为每层从属面积n为层数。框架柱上下截面高度不同时,每次缩小100~150为宜。为方便尺寸标注修改,边柱一般以墙中心线为轴线收缩,中柱两边收缩。柱截面与标号的变化宜错开。 2.梁截面初定梁高为跨度的1/8~1/14,梁宽通常为1/2~1/3梁高。其余见前述。对于宽扁梁首先应注意满足挠度要求,否则存在梁板协调变形的复杂内力分析问题。梁净跨与截面高度之比不宜小于4。框架梁宽不宜小于1/2柱宽,且不小于250mm。框架梁的截面中心线宜与柱中心线重合,当必须偏置时,同一平面内的梁柱中心线间的偏心距不宜大于柱截面在该方向的1/4。 3.砼强度等级一级现浇不低于C30,其余不低于C20。 三.重力荷载计算 1.屋面及楼面永久荷载标准值分别计算各层 2.屋面及楼面可变荷载标准值 3.梁柱墙门窗重力计算 4.重力荷载代表值=自重标准值+可变荷载组合值+上下各半层墙柱等重量 可变荷载组合值系数:雪、屋面积灰为0.5,屋面活荷载不计,按实际考虑的各楼面活荷载为1。将各层代表值集中于各层楼面处。 四.框架侧移刚度计算 计算梁柱线刚度,计算各层D值,判断是否规则框架。分别计算框架纵横两个方向。 五.计算自振周期 T1=(0.6或0.7)X1.7Xsqrt(Ut) Ut___假想把集中在各层楼面处的重力荷载代表值作为水平荷载而算得的结构顶点位移。0.6或0.7为考虑填充墙的折减系数。对于带屋面局部突出的房屋,Ut应取主体结构顶点位移,而不是突出层位移。此时将

多层混凝土框架结构设计文献综述

多层混凝土框架结构设计 1.前言 随着社会的发展,钢筋混凝土框架结构的建筑物越来越普遍.由于钢筋混凝土结构与砌体结构相比较具有承载力大、结构自重轻、抗震性能好、建造的工业化程度高等优点;与钢结构相比又具有造价低、材料来源广泛、耐火性好、结构刚度大、使用维修费用低等优点。因此,在我国钢筋混凝土结构是多层框架最常用的结构型式。近年来,世界各地的钢筋混凝土多层框架结构的发展很快,应用很多。 一般框架结构是由楼板、梁、柱及基础4种承重构件组成的,由主梁、柱与基础构成平面框架,各平面框架再由连续梁连接起来而形成的空间结构体系。文献[1]认为,在合理的高度和层数的情况下,框架结构能够提供较大的建筑空间,其平面布置比较的灵活,可适合多种工艺与使用功能的要求。 多层钢筋混凝土框架结构设计可以分为四个阶段:一是方案设计,二是结构分析,三是构件设计,四是绘施工图。结构分析和构件设计是结构设计中的计算阶段,在现代,已由电子计算机承担这一工作,常采用PKPM建模计算。但是,结构的计算并不能代替结构的设计。文献[2]中认为:良好的结构设计的重要前提,应该是合理组织与综合解决结构的传力系统、传力方式,良好的结构方案是良好结构设计的重要前提。2.关于框架结构设计文献回顾 2.1框架结构的优缺点 框架结构体系是由横梁与柱子连接而成.梁柱连接处(称为节点)一般为刚性连接,有时为便于施工和其他构造要求,也可以将部分节点做成铰接或者半铰接.柱支座一般为固定支座,必要时也可以设计成铰支座.框架结构可以分为现浇整体式,装配式,现浇装配式. 文献[3]中提到:框架结构的布置灵活,容易满足建筑功能和生工艺的多种要求.同时,经过合理设计,框架结构可以具有较好的延性和抗震性能.但是,框架结构承受水平力(如风荷载和水平地震作用)的能力较小.当层树较多或水平力较大时,水平位移较大,在强烈地震作用下往往由于变形过大而引起非结构构件(如填充墙)的破坏.因此,为了满足承载力和侧向刚度的要求,柱子的截面往往较大,既耗费建筑材料,又减少使用面积.这就使框架结构的建筑高度受到一定的限制.目前,框架结构一般用于多层建筑和不考虑抗震设防,层数较少的的高层建筑(比如,层数为10层或高度为30米以下) 2.3框架结构的布置 多层框架结构的平面布置形式非常的灵活,文献[4]中将框架结构按照承重方式的不同分为以下三类:(1)横向框架承重方案,以框架横梁作为楼盖的主梁,楼面荷载主要由横向框架承担.由于横向框架数往往较少,主梁沿横向布置有利于增强房屋的横向刚度.同时,主梁沿横向布置还有利于建筑物的通风和采光.但由于主梁截面尺寸较大,当房屋需要大空间时,净空较小,且不利于布置纵向管道. (2)纵向框架承重方案以框架纵梁作为楼盖的主梁,楼面荷载由框架纵梁承担.由于横梁截面尺寸较小,有

钢筋混凝土结构课程设计模板

网络教育学院 《钢筋混凝土结构课程设计》 题目:海天厂房单向板设计 学习中心:浙江电大仙居学院奥鹏学习中心[22] 专业:土木工程 年级: 2012 年春季 学号: 学生:张奇 指导教师:

1 基本情况 本章需简单介绍课程设计的内容,包括厂房的尺寸,板的布置情况等等内容。 一、设计资料 海天多层厂房为多层内框架结构,一层平面如图所示,露面周边支撑于外墙,采用现浇钢筋混凝土单向板,烧结承重多孔砖砌体承重外墙,钢筋混凝土内柱尺寸为400×400㎜。 1.楼面做法 20厚水泥砂浆地面,钢筋混凝土现浇板,20厚混合砂浆抹底。 2.荷载 楼面等效均布活荷载标准值为7KN/㎡,水泥砂浆容重为20KN/㎡,混合砂浆容重为17KN/㎡,钢筋混凝土容重为25KN/㎡. 永久荷载的分项系数按照永久荷载效应控制的组合,取为;活荷载的分项系数为。 3.材料 混凝土楼板采用 C25,梁内受力钢筋为 HRB400级,板内钢筋及箍筋为 HPB235 级。 二、楼板结构平面布置及截面尺寸确定 主梁沿横向布置,次梁按纵向布置。 主梁的跨度为6M,次梁跨度为6M,主梁每跨内布置两根次梁,板的跨度为 2M,l 2/l 1 ==3 按照单向板设计。 按高跨比条件,要求板的厚度h≥2000×1/40=50㎜,对工业建筑的楼板要求h≥80㎜,取板厚为80㎜。 次梁截面高度要求h= l 0/18 ~l /12 =6000 /18 ~ 6000 /12= 333 ~ 500 ,考虑到 楼面的活荷载比较大,取h=450 mm .截面宽度取为b=200mm 。 主梁截面高度要求 h= l 0/15 ~l /10= 6000 /15 ~ 6000 /10 =400 ~ 600 mm ,取 h=600mm。截面宽度取为 b=300mm 。楼板的结构平面布置图见图2

框架结构设计步骤及要点

框架结构设计步骤及要点 1. 结构设计说明: 主要是设计依据,抗震等级,人防等级,地基情况及承载力,防潮抗渗做法,活荷载值,材料等级,施工中的注意事项,选用详图,通用详图或节点,以及在施工图中未画出而通过说明来表达的信息。如混凝土的含碱量不得超过3kg/m3等等。 2. 各层的结构布置图:包括: (1).预制板的布置(板的选用、板缝尺寸及配筋)。标注预制板的块数和类型时, 不要采用对角线的形式。因为此种方法易造成线的交叉, 宜采用水平线或垂直线的方法, 相同类型的房间直接标房间类型号。应全楼统一编号,可减少设计工作量,也方便施工人员看图。板缝尽量为40, 此种板缝可不配筋或加一根筋。布板时从房间里面往外布板, 尽量采用宽板, 现浇板带留在靠窗处, 现浇板带宽最好≥200(考虑水暖的立管穿板)。如果构造上要求有整浇层时, 板缝应大于60。整浇层厚50, 配双向φ6250, 混凝土C20。纯框架结构一般不需要加整浇层。构造柱处不得布预制板。地下车库由于防火要求不可用预制板。框架结构不宜使用长向板,否则长向板与框架梁平行相接处易出现裂缝。建议使用PMCAD的人工布板功能布预制板,自动布板可能不能满足用户的施工图要求,仅能满足定义荷载传递路线的要求。 (2).现浇板的配筋(板上、下钢筋,板厚尺寸)。板厚一般取120、140、160、180四种尺寸或120、150、180三种尺寸。尽量用二级钢包括直径φ10(目前供货较少)的二级钢,直径≥12的受力钢筋,除吊钩外,不得采用一级钢。钢筋宜大直径大间距,但间距不大于200,间距尽量用200。(一般跨度小于6.6米的板的裂缝均可满足要求)。跨度小于2米的板上部钢筋不必断开,钢筋也可不画,仅说明钢筋为双向双排钢筋多少上下钢筋间距宜相等,直径可不同,但钢筋直径类型也不宜过多。顶层及考虑抗裂时板上筋可不断,或50%连通,较大处附加钢筋,拉通筋均应按受拉搭接钢筋。板配筋相同时,仅标出板号即可。一般可将板的下部筋相同和部分上部筋相同的板编为一个板号,将不相同的上部筋画在图上。当板的形状不同但配筋相同时也可编为一个板号。应全楼统一编号。当考虑穿电线管时,板厚≥120,不采用薄板加垫层的做法。电的管井电线引出处的板,因电线管过多有可能要加大板厚至180(考虑四层32的钢管叠加)。宜尽量用大跨度板,不在房间(尤其是住宅)加次梁。说明分布筋为φ8200。板顶标高不同时,板的上筋应分开或倾斜通过。现浇挑板阳角加辐射状附加筋(包括墙上的阳角)。现浇挑板阴角的板下宜加斜筋。顶层应建议甲方采用现浇楼板,以利防水,并加强结构的整体性及方便装饰性挑沿的稳定。外露的挑沿、雨罩、挑廊应每隔10~15米设一10mm的缝,钢筋不断。尽量采用现浇板,不采用予制板加整浇层方案。卫生间做法可为70厚+10高差(取消垫层)。8米以下的板均可以采用非预应力板。L、T或十字形建筑平面的阴角处附近的板应现浇并加厚,双向双排配筋,并附加45度的4根16的抗拉筋。现浇板的配筋建议采用PMCAD软件自动生成,一可加快速度,二来尽量减小笔误。自动生成楼板配筋时建议不对钢筋编号,因工程较大时可能编出上百个钢筋号,查找困难,如果要编号,编号不应出房间。配筋计算时,可考虑塑性力重分布,将板上筋乘以0.8~0.9的折减系数,将板下筋乘以1.1~1.2的放大系数。值得注意的是,按弹性计算的双向板钢筋是板某几处的最大值,按此配筋是偏于保守的,不必再人为放大。支承在外圈框架梁上的板负筋不宜过大,否则将对梁产生过大的附加扭距。一般:板厚>150时采用φ10200;否则用φ8200。PMCAD生成的板配筋图应注意以下几点:1.单向板是按塑性计算的,而双向板按弹性计算,宜改成一种计算方法。 2.当厚板与薄板相接时,薄板支座按固定端考虑是适当的,但厚板就不合适,宜减小厚板支座配筋,增大跨中配筋。 3.非矩形板宜减小支座配筋, .资料. . .

网站建设方案_网站框架及制作流程

栏目结构图(品牌形象站与餐吧服务展示站)

公司网站整体风格: 充分体现限公司的特点,以大气、直观、高档、新颖的个性化设计展现公司的品牌形象与主营产品,以求与贵公司网络营销和市场定位达成一致,符合企业形象标准和行业特色,充分展示企业实力和产品特点,展示企业产品营销的风采,能够捕捉客户的需求,双向交流,使客户在网站中充分发表见解,并加以吸收,并从中挖掘潜在的客户,结合行业特色和公司特点,打造一个全新的,符合公司现有发展趋势的网站。 (一)我们的设计宗旨 塑造客户良好的公司知名品牌形象;进行互联网招商引资,扩大销售网络及经 营渠道。 提高宣传力度;完善公司销售管理,增强公司内外部交流。 体现客户的独特风格;最大限度的发挥站点的实用性和美观性。 采用各种先进的数据库以提高公司网站的管理性、灵活性及方便性,并通过网站更好的实现公司信息化与无纸化办公。 首页:设计精美,形式新颖,利用FLASH动感的表达公司的产品内涵。充分体现贵公司的公司实力及品牌形象,大方,得体,不落俗套,给人耳目一新的感觉。. 网站内容包括公司公司介绍、产品展示、网上招聘、新闻动态、下载中心、留言版等栏目,根据贵公司的背景,详尽的介绍贵公司的情况。文字图片相结合形势展现,这样从气势上让人感觉是一个非常有实力的公司。此模块有采用“公司信息系统”完成,前台可实现信息的浏览、查找,后台可方便添加、删除、栏目维护(可添加图片)

网站建设费模块

人才招聘系统实现招聘单位在线发布、修改、删除人才招聘信息,招聘信息和在线注册简历、人才简历对不同服务对象有权限限制。为求职者提供职位人才信息订阅和详细人才信息查询等个性化增值服务。设有一个专门的人才库。 浏览统计分析系统记录网站和公司产品流览量及点击率并分析出每个上网者来源(可分析出IP地址的来访国家、地区、访问页面、停留时间、用的浏览器等) 时间安排: 网站建设进度及实施过程 项目实施方法 我们项目实施方法中的五个基本阶段是:1 规划定义:已完备

结构力学课程设计多层框架结构(DOC)

结构力学课程设计多层多跨框架结构内力计算 姓名: 班级: 学号: 任课教师: 日期:

多层多跨框架结构内力计算指导书 一. 任务 1. 求解多层多跨框架结构在竖向荷载作用下的弯矩。 2. 计算方法: (1)用近似法计算:手算竖向荷载作用下分层法计算; (2)最好用电算(结构力学求解器)进行复算。 (3) 最好对比手算与电算,就最大相对误差处,说明近似法产生误差的来源。 3. 将手算结果写成计算书形式。计算简图:如图(一)所示。 4. 基本计算参数 材料弹性模量:723.010/E kN m =? 竖向荷载: 恒载 21=21/g k N m ,22=17/g kN m 5 荷载分组: (1)只计算竖向恒载(见图二); 图一 图二 本组计算的结构其计算简图如图一所示,基本数据如下: 混凝土弹性模量:72 3.010/h E kN m =? 杆件尺寸:

m L 5.51= m L 7.22= m H 5.41= m H 6.32= 柱:底 层:25555b cm h ?=? 其它层:2 5050b cm h ?=? 梁:边 梁:2 4525b cm h ?=? 中间梁:2 3525b cm h ?=? 竖向均布恒载: 恒载: 2/211g m kN = 2 /172 g m kN =(见图二) 各杆件的线刚度: 12 3 h b I L EI i ?==,其中 边 梁:4 m 3 10 9.112 345 .025.01 -?=?= I m kN L EI i ?=-???= =103645 .53 109.17100.31 1 1 中间梁: 4 m 3 10 9.012 3 35 .025.02 -?=?= I m kN L EI i ?=-???= = 100007 .23 109.07100.32 2 2 底层柱: 4m 310 6.712 3 55 .055.03 -?=?= I ` m kN H EI i ?=-???= = 506675 .43 106.77100.31 33

多层框架结构中次梁设计论文

浅谈多层框架结构中次梁的设计 摘要:通过工程模型的对比分析,证明了多层框架结构的次梁布置对结构整体刚度的影响,进而影响结构的抗震。为框架结构尤其是平面狭长的框架结构设计提供参考。 关键词:次梁;刚度;抗震;结构布置 abstract: through the comparison of the engineering model, and prove the multilayer frame structure of the second beam layout of the influence of the whole structure stiffness, and affect the structure of earthquake. as a frame structure especially plane long and narrow frame structure provides reference for the design. keywords: second beam; stiffness; seismic; structure layout 【中国分类号】tu208.2 ;tu375 【文献标志码】a【文章编号】框架结构因为具有建筑平面布置灵活、房间空间大等优点,在工业厂房及公共建筑中有着广泛的应用。一般而言,框架结构就其承重方案一般有三种:横向承重,纵向承重和双向承重。对应的次梁布置方式分别为沿纵向布置,沿横向布置和双向布置(即十字梁或井字梁)。 当框架结构的主要结构构件框架柱、框架梁尺寸确定的情况下,次梁对结构整体抗震设计有何贡献呢?目前有不少的工程设计人

浅谈多层框架结构

浅谈多层框架结构 【摘要】在我国社会主义经济建设的良好发展形势下,我国建筑行业获取了前所未有的发展机遇与广阔前景。多层框架结构是我国近年才正式应用的结构形式之一,被广泛应用于现代建筑行业各领域中。本文主要阐述了有关多层框架结构相关的一系列问题。 【关键词】建筑,多层框架结构 1.前言 近些年来,建筑市场在我国可以说是蓬勃发展,钢筋混凝土多层框架结构的房屋结构设计有着明显的优势,已经在我国建筑领域得到广泛的使用,建筑房屋多层框架结构设计的科学性以及合理性对于建筑质量的要求以及使用有着决定性的巨大影响,针对建筑钢筋混凝土多层框架结构进行深入的研究和探讨。 2.多层框架结构的组成 框架结构由柱和梁组成。一般柱子垂直布置,梁水平布置;屋面由于排水或其他方面的要求,也可布置成斜梁;梁柱连结处一般为刚性连接;有时为便于施工或由于其他构造要求,也可将部分节点做成铰节点或半铰节点。当梁、柱之间全部为饺接时,也称为多层排架;刚性连接的梁比普通梁式结构要节约材料,结构的横向刚度较好,横梁的高度也较小,因而可增加房屋的净空,是一种比较经济的结构形式。 框架可以是等跨或不等跨,层高可以相等或不完全相等,有时因工艺要求而在某层抽柱或缺梁形成复式框架。框架结构为高次超静定结构,既承受竖向荷载,又承受侧向作用力(风荷载或地震作用等)。为利于结构受力,框架梁宜拉通、对直,框架柱宜上、下对中,梁柱轴线宜在同一竖向平面内,有时由于使用功能或建筑造型上的要求,框架结构也可做成抽梁、抽柱、内收、外挑等。 框架结构有实腹式、格构式以及横梁为格构式、柱为实腹式的混合式框架。实腹框架梁的横截面一般为矩形或梯形截面。混凝土框架柱的截面形式常为矩形或正方形,有时由于建筑上的要求,也可设计成圆形、八角形、T形等。钢框架柱的截面形式常采用H形或箱形。实腹式框架外形简捷美观,制造和施工简单,安装省工,但材料利用率低。当结构跨度较大时,可采用格构式框架。格构式框架刚度较大,用钢省,其外形与净空布置比实腹式框架灵活,但制造加工和安装较为复杂。混合式框架的目的主要是减轻横梁自重,增加结构刚度。当楼盖为现浇板时,可将楼板的一部分作为框架梁的翼缘予以考虑,即框架梁截面为T或r形;当采用预制板楼盖时,为减小楼盖结构高度,增加建筑净空,混凝土框架梁截面常为十字形或花篮形;这时也可将预制梁做成T形截面,在预制板安装就位以后,再现浇部分混凝土,使后浇混凝土与预制梁共同工作即成为叠合梁,这样一方面保证了梁的有效高度和承载力;另一方面可将梁板有效地连成整体,改善结构的抗震(振)性能。预

基于CSS框架的S7-1200Web页面制作

基于CSS框架的S7-1200Web页面制作 S7-1200有个web页面发布的功能,这个功能好像很少有人提及它的使用,我也只是偶尔用来监控一下PLC变量,因为打开TIA14确实有点慢。 但是这个功能绝对不是什么鸡肋,因为它可以发布用户自定义的页面,而且页面可以加载javascript,这就使得它的功能跟火箭一样一飞冲天了,不过官方文档也说了,最好不要靠这个功能来代替专业的HMI软件,毕竟它的实时性和安全性还是有待斟酌的。 但是在产品调试阶段还有测试阶段,这个功能确实很值得一用,因为它很方便实现也很容易让不懂PLC系统的测试人员无门槛上手,毕竟打开浏览器这个操作人人都会。 实现起来很简单,网上的英文文档也很多,介绍的很详细,所以这里就不详细说怎么实现了,只是说一说基于主流的CSS框架来使页面制作的更容易和更美观一些,还有就是在实际编写过程中遇到的一些问题 框架结构 在实际开始进行web功能编写前,需要先规划一下需要展示几个页面和页面的布局,这里介绍一个网站layoutit,这个完全可视化的网站可以进行拖放操作实现网页布局,布局后的html代码可以下载下来直接使用,使用的CSS框架是主流的bootstrap,可以说页面的美观程度完全不用操心,绝对主流,下面是我用它生成的一个网页结

构,之后下载到PLC后,浏览器中打开的样子. 放入变量 网页结构完成后,就可以放入PLC的变量了,这里其实没什么特别要说的,变量是通过在整个html文件开头通过AW P进行所谓的声明,之后在网页中进行使用 从PLC进行读操作的变量通过 从PLC进行写操作的变量通过 这里要注意引号的使用,如果是内存变量M,或者Q,I之类的输入输出变量,就是通过单引号外加双引号将它括起来,像这样 ‘“此处填写变量名”‘ 但是如果是DB块的变量,就需要像这样 ‘“DataBloack名称”.变量名称’ 实际的使用中,无非也就几种操作, 网页端按下按钮控制PLC的变量 在网页端显示PLC的某个变量 网页端输入某个数字到PLC内某个变量

网页设计与制作之框架结构

框架是什么,框架就好比我们的骨骼,支撑着整个网页,如果一个网页没了框架,那么就感觉像一盘散沙,因此为了更好的实现网页的效果,我们就要学会给网页制作一个框架,为了更好的理解什么是框架。我们画一张示意图来进行讨论。 这是一个左右型的框架,由三个网页文件组成的。首先外部的框架是一个文件,图中我们用index.htm命名。框架中左边命名为A,指向的是一个网页A.htm。右边命名为B,指向的是一个网页B.htm。 下面我们就来从头开始制作一个框架。 1、点“文件”菜单>新建,弹出“新建文档”对话框如下图: 或在插入栏>布局>选"框架:左框架"如下图:

Dreamweaver MX 2004生成一个空白的框架页面,如下图: 2、选择「窗口」菜单>“框架”,弹出“框架”面板如下图。从框架面板可知,系统对左右框架生成命名。左框架名为:leftFrame,右框架名为:mainFrame,当然您可以通过框架属性面板对框架重新命名,了解这一点非常重要。创建超级链接时,要依据它正确控制指向的页面。

3、保存框架。选择“文件”菜单点击“保存全部”。系统弹出对话框。这时,保存的是一个框架结构文件。我们按照惯例都命名为index.htm。 保存的时候如果虚线框笼罩的是周围一圈就是保存框架结构。(下图) 虚线笼罩在右边就是保存框架中右边网页。(如下图)

虚线笼罩在左边就是保存框架中左边的网页:(如下图) 三个页面保存完毕。

4、下面我们要实现按左边的超级链接,对应的页面出现在右边。在左边的页面中做上超级链接。指向一个已经存在的页面。注意做好链接以后,要在目标栏中设置为mainFrame。(如下图) 6、设置完毕,保存全部,按F12预览网页。链接指向的页面出现在右边框架中。 7、重复以上步骤,把左框架所有的链接做完,一个简单的网站导航结构创建完成。 更多Dreamweaver 教程请继续访问建站学的Dreamweaver教程专区。 实验七框架结构 【实验目的】: 通过本实验,使学生熟悉创建、编辑框架网页和利用框架来布局页面的基本方法。【实验要求】: 1. 掌握应用框架设计网页布局的方法; 2. 掌握创建、编辑框架网页及设置框架属性的方法; 3. 掌握链接框架网页的方法。

(完整版)混凝土框架结构毕业课程设计

温州大学瓯江学院WENZHOU UNIVERSITY OUJIANG COLLEGE 《混凝土结构课程设计(二)》 专业:土木工程 班级:08土木工程本一 姓名:王超 学号: 指导教师:张茂雨 日期:2011年6月10号 混凝土框架结构课程设计

一.设计资料 某三层工业厂房,采用框架结构体系。框架混凝土柱截面尺寸边柱为500mm×500mm,中柱600mm×600mm。楼盖为现浇钢筋混凝楼盖,其平面如图所示。(图示范围内不考虑楼梯间)。厂房层高分别为4.5,4.2,4.2米。地面粗糙度类别为B类。(L1=8100,L2=6600) 1. 楼面构造层做法:20mm厚水泥砂浆地面,钢筋砼现浇板,15mm厚石灰砂浆 刷。 2.可变荷载:楼面屋面标准值取5.0KN m2,活荷载分项系数1.3。 3.永久荷载:包括梁、板及构造层自重。钢筋砼容重25 KN m3,水泥砂浆容重 20KN m3,石灰砂浆容重17KN m3,分项系数为1.2。 材料选用:

混凝土采用C20(f c=9.6Nmm2,f t=1.10Nmm2)。 钢筋柱、梁受力筋采用Ⅱ级钢筋(f y=300 Nmm2),板内及梁内其它钢筋采用Ⅰ级(f y=210 Nmm2) 二.框架梁及柱子的线刚度计算 取①轴上的一榀框架作为计算简图,如图所示。 梁、柱混凝土强度等级为C20,E c =2.55×104Nmm2=25.5×106KNm2。框架梁惯性矩增大系数:边框架取1.5,中框架取2.0。 中框架梁的线刚度: i b 1=α b EI b l=2.0××25.5×106×0.3×0.736.6=66.28×103KN·m2 边框架梁的刚度: i b 2α b EI b l=1.5××25.5×106×0.3×0.736.6=49.70×103KN·m2

pkpm框架结构设计附上主要步骤

设计说明: 一、建模前的准备工作: 1、确定结构体系: 根据设计任务,本工程为一五层建筑,采用全钢筋混凝土框架结构,底层至顶层全部采用现浇楼板。 2、结构尺寸估算: 根据建筑图中的开间、进深及层高,结合各楼层采用的砼强度等级及受荷情况,根据设计规范及构造要求可以估算基本构件尺寸(单位:mm ) A 、柱:本工程可取400×400mm 。 B 、梁: 主梁:128 L h L ≥≥; 32h b h ≥ ≥; 本工程根据图纸得5700/12=475《h 《5700/8=712.5,取 h=600mm,b=300mm 次梁:1812 L h L ≥≥; 32h b h ≥ ≥; 本工程根据图纸得4200/18=233《h 《4200/12=350,取 h=350mm,b=200mm 悬挑梁:一般取为悬臂长的1/6, C 、板: 40/;80L h mm h ≥≥,本工程可取120mm ; 3、确定荷载 A 、楼面恒载(包括楼板自重): 一层~五层楼面:4KN/m 2,卫生间:3.5KN/m 2,楼梯间:5.5KN/m 2, 屋面:6KN/m 2,

B、楼面活载: 一层~五层楼面:2.0KN/m2,卫生间:2.0KN/m2,楼梯间:2.0KN/m2, 阳台:2.5KN/m2 不上人屋面:0.5KN/m2, C、墙荷载: 外横墙:9.4KN/m 外纵墙:4.0KN/m 内墙:6.0KN/m 女儿墙:4 KN/m 4、确定结构标准层和荷载标准层 根据建筑图及所采用的结构体系进行标准层划分,本工程根据建筑图及荷载情况,可分为3个结构标准层,2个荷载标准层。 三个结构标准层: 第一标准层为▽3.000楼板,层高4000(1000+3000=4000); 第二标准层为▽6.000、9.000、12.000楼板,层高均为3000; 第三标准层为▽15.000屋面板,层高3000。 二个荷载标准层: 第一标准层楼面恒载:4KN/m2,活载:2.0KN/m2, 第二标准层屋面恒载:6KN/m2,活载:0.5KN/m2, 二、结构建模基本步骤: 1、执行PMCAD主菜单1建筑模型与荷载输入 A、建立和生成网格,根据所给建筑图建立第一结构标准层的轴线 可用正交轴网进行,然后进行轴线命名

浅谈多层框架结构特点多层框架

浅谈多层框架结构特点 摘要:在我国,框架结构是目前应用较多的结构形式之一。本文主要说明了框架结构的特点和适用范围,对多层框架结构的布置原则及方法、框架设计中的梁柱截面、配筋率和梁裂缝宽度的调整等问题进行了分析。关键词:框架结构;配筋率;问题分析 1 概述、 框架结构体系具有建筑平面布置灵活,使用空间大、便于分隔、延性较好等特点。 选择框架结构应综合考虑建筑功能的要求,以及建筑高度、高宽比、抗震设防类别、抗震设防烈度、场地条件等因素。 框架结构体系是介于砌体结构与框架-剪力墙结构之间的结构体系。框架结构设计应符合安全适用、技术先进、经济合理、便于施工的结构设计原则。 框架结构是由横梁和立柱组成的杆件体系,节点全部或大部分为刚性连接。框架结构是最常见的竖向承重结构,具有以下优点:(1)结构轻巧,便于布置;(2)整体性比砖混结构和内框架承重结构好;(3)可形成大的使用空间;(4)施工较方便;(5)较为经济。 框架结构特别适合于在办公楼、教学楼、公共性与商业性建筑、图书馆、轻工业厂房、公寓以及住宅类建筑中采用。但是,由于框架结构构件的截面尺寸一般都比较小,它们的抗侧移刚度较弱,为了不使框架结构构件的截面尺寸过大和截面内钢筋配置过密,框架结构一般只用于不超过20层的建筑中。

2 结构布置方法 2.1结构布置的一般原则 结构布置在建筑的平、立、剖面和结构的形式确定以后进行。对于建筑剖面不复杂的结构,只需进行结构平面布置;对于建筑剖面复杂的结构,除应进行结构平面布置外,还须进行结构的竖向布置。进行结构布置是,应满足以下的一般原则: (1)满足使用的要求,并尽可能地与建筑的平、立、剖面划分相一致; (2)满足人防、消防要求,使水、电、暖各专业的布置能有效地进行; (3)结构应尽可能简单、规则、均匀、对称,构件类型少; (4)妥善地处理温度、地基不均匀沉降以及地震等因素对建筑的影响; (5)施工简便; (6)经济合理。 结构选型和结构布置在结构设计中起着至关重要的作用。结构选型好,布置合理,不但使用方便,而且受力好,施工简便,造价也低,反之,则情况相反。因此,要根据上述原则进行多个结构布置方案的比较,反复推敲,选择一个比较合理的结构布置方案。 2.2结构布置方法 框架结构有横向承重布置、纵向承重布置和双向承重布置三种常用的结构布置方法。

实验七 框架型网页的制作

实验七框架型网页的制作 一、实验目的 1、掌握框架集和框架的创建和保存; 2、掌握框架、框架集的编辑和属性的设置; 3、掌握框架超级链接。 二、实验内容 利用框架制作如下图所示的页面效果,框架集网页为index.html,其中:图2-9-1为打开index.html的效果图; 图2-9-2 单击左侧“勇敢的心”的网页效果图; 图2-9-3 单击左侧“肖申克的救赎”的网页效果图; 图2-9-4 单击左侧“阿凡达”的网页效果图; 图2-9-5 单击左侧“战马”的网页效果图; 图2-9-1 图2-9-2 图2-9-3 图2-9-4

图2-9-5 三、知识点分解 该实验主要涉及的知识点就是框架和框架集的保存以及设置超链接的目标框架。 四、实验步骤 1、选择[文件]/[新建]菜单命令。 2、在“新建文档”对话框“示例中的页”列表中选择“框架集”选项。 3、从“框架集”列表选择相应的框架集,如图2-9-8所示。 图2-9-8 “新建文档”对话框 4、单击按钮,则会弹出“框架标签辅助功能属性”对话框,为每一框架指定一个标题,单击“确定”按钮,则上方框架标题为“topFrame”,左侧框架标题为“leftFrame”,右侧框架标题为“mainFrame”。 5、选择[查看]/[可视化助理]/[框架边框]菜单命令,则在文档中就会出现框架的边框。 6、选择[文件]/[保存全部]菜单命令,将框架集文件保存为index.html,上方框架文 件保存为top.html,左侧框架文件保存为left.html,右侧框架文件保存为main.html。 注意:对于框架集和框架文件保存的文件名,一定要做的看到文件名就能知道该文件对应与 该框架集中的哪个框架。

多层框架结构课程设计

多层框架结构课程设计任务书 一、设计题目 某多层框架结构设计 二、设计条件 1.题号(TH×××××)后的数字对应上表中的设计条件中的数字,见附表所示。 设计主要条件见下表 2.其它条件 (1)房屋室内外高差0.45m,房屋安全等级为二级,设计使用年限为50年,抗震设防烈度为6度,拟采用框架结构。 (2)建筑构造 1)墙身做法±0.000标高一下墙体均为多空粘土砖,用M7.5水泥砂浆砌筑;±0.000标高以上外墙采用粘土多孔砖,内墙采用加气混凝土砌块,用M5混合砂浆砌筑。 内墙(乳胶漆墙面)刷乳胶漆 5mm厚1:0.3:3水泥石灰膏砂浆粉面(16 kN/m3) 12mm厚1:1.6水泥石灰膏打底(16 kN/m3) 刷界面处理剂一道 外墙(保温墙面——聚苯板保温) 喷涂料面层 5mm厚聚合物抹面抗裂砂浆(20 kN/m3) 耐碱玻纤网格布 界面剂一道,刷在膨胀聚苯板粘贴面上

25mm厚膨聚苯板保温层(0.3kN/m3) 界面剂一道,刷在膨胀聚苯板粘贴面上 3mm厚专用胶粘剂 20mm厚1:3水泥砂浆找平层(20 kN/m3) 界面处理剂一道 粘土多孔砖基层墙面 2)平顶做法(乳胶漆顶棚) 刷乳胶漆 20mm厚1:0.3:3水泥石灰膏砂浆打底(16 kN/m3) 刷素水泥浆一道 现浇混凝土板 3)楼面做法(水磨石地面) 15mm厚1:2白水泥彩色石子磨光打蜡(22 kN/m3) 刷素水泥结合层一道 20mm厚1:3水泥砂浆找平层(20 kN/m3) 100mm厚现浇钢筋混凝土楼板(25 kN/m3) 4)屋面做法(刚性防水屋面——有保温层) 50mm厚C20细石混凝土(25 kN/m3) 20mm厚1:3水泥砂浆找平层(20 kN/m3) 60mm厚挤塑聚苯板保温层(0.35 kN/m3) 20mm厚1:3水泥砂浆找平层(20 kN/m3) 合成高分子防水卷材一层(厚度大于12mm)(0.05kN/m2) 20—150mm厚轻质混凝土找坡(坡度2%)(7.0 kN/m3) 100mm厚钢筋混凝土屋面板(25 kN/m3) 5)门窗做法隔热断桥铝合金窗,木门 (3)可变荷载标准值 1)建设地点基本风压ω0=0.45kN/m2,场地粗糙度为B类,组合值系数ψc=0.6。 2)建设地点基本雪压S0=0.40kN/m2,组合值系数ψc=0.7。 3)不上人屋面可变荷载标准值0.5kN/m2,组合值系数ψc=0.7。 4)办公室楼面可变荷载标准值2.0kN/m2,组合值系数ψc=0.7。 5)走廊、楼梯可变荷载标准值2.5kN/m2,组合值系数ψc=0.7。 三、设计内容 1.结构平面布置(楼盖布置、估算构件截面尺寸)与材料选择。 2.横向框架结构分析(荷载计算、竖向荷载下内力计算、水平荷载下内力计算、水平荷载下侧移计算)。 3.框架梁、柱截面设计(选择材料、内力组合、配筋计算)。

框架讲解制作步骤

大部分框架网页出现在后台,管理系统的界面 制作步骤: 方法一:新建html ,插入--html-框架-选择其中一项 方法二:自定义框架 ①直接拖动边框可实现增加框架页面 ②反之也可以删除框架页面 ③按住ALT+SHIFT可实现选择其中的一个框架页面操作,可以拖拽其中的一个页 面 托错了,为什么撤销不了,是因为没有选中最外围的框架,即大框架 注意保存顺序: 保存的时候会保存四张页面,但是你要弄清楚保存的是哪个页面,为避免保存时不清楚那个是哪个的问题,保存的时候要能够给框架页面起名字不会无法在主框 架页嵌入不了页面,先保存三张内页,再保存框架页,以上两个保存顺序最好不要 颠倒 如何给框架命名:①在窗口---框架打开框架视图,这时的框架在程序的右下角; ②在框架视图上点击要命名的框架页,再在属性框架名称上输入框架名称,再在编 辑区域上相应的地方点击刚才命名的框架就好。 想要边框完全消失,就要设置边框为0,想要边框固定,那就框架四个页面都为否,想要页面不滚动,那就将框架的页面的滚动设置为否 框架页内部实现的超级链接,给要在显示的区域框架起名字,id =in和name=in 首页

<body> </body> 嵌入式框架页面,表格布局 在右侧单元格内插入代码自己敲,包括超链接时的目标in Src初始化界面,也就是第一次加载的页面 Width ,height 嵌入式的框架页面的宽度和高度

相关文档
最新文档