在软件开发中,架构是一个很抽象的词汇,在我看来,架构是指系统在明确了前期需求理解
后,架构工作人员对于系统决策的一种规定. 架构可以分成两类:
业务上的架构:也就是我们通常说的设计,它面向的是系统的业务,这项工作一般由系统设计师(SE)来完成.
考虑的问题首先是业务实体的设计,需要决定是以数据库为中心进行设计还是以面向对象为中心.因为随着面向对象思想的不断普及,关系型数据库已经成为仅仅是为了存放数据的地方,人们往往更喜欢以对象的观念来考虑客观事物,此时需要根据需求抽象出若干实体对象,并且决定对象之间的关系诸如关联,依赖,聚合等,再利用ORM工具将对象实体转化为关系数据库中的表. 但由于经验上的不成熟,真正在设计中以对象为中心的项目还是比较少,大多项目还是传统的以关系数据库为中心,然后如果需要持久化,再将表转化为对象. 此时需要抽象的不是对象,而是表和表之间的关系如一对多,多对多等. 业务实体设计的是否合理往往对系统的性能起决定作用
在设计好业务实体后,接下来要考虑的问题是将需求模块化,此项工作往往在实体设计中已经基本明确. 接着要考虑每个模块需要实现哪些功能,为这些功能设计对外的接口,并且合理的定义接口的粒度.此外还要为一些通用的部分设计一个合理的类继承结构,将通用的功能抽象到最高层次,提高系统的可维护性和可扩展性. 业务上的架构直接指导开发人员的编码.
技术上的架构:往往以层次的观念来考虑问题, ,这项工作一般由系统架构师来完成.
企业开发通常被分成表示层,业务层,数据访问层和后台数据库层.
表示层:我们需要考虑的问题首先是是否需要一个合适的表示层开源框架,由于目前开源的不断繁荣,它们对于模式的运用已经达到了如火纯青的境界,不使用任何的开源而仅仅利用JSP/Servlet来进行开发往往是不明智的选择,因为那意味着我们需要按照模式自己实现一个通用的Front Controller,自己封装请求数据,并且自己来将请求转发给具体的处理器.开发人员的水平掺差不齐,这样的项目往往很难维护.当然你也可以不使用任何模式,完全的跟着感觉走,那意味着你的能力也是跟着感觉走...其次我们需要考虑选择哪一种框架更适合自己的系统. Struts? Webwork? JSF? or others,此时需要架构师对各种开源框架的特点比较熟悉,以便决定哪个才是自己最需要的.
业务层:我们首先要考虑的问题如何组织你的业务对象之间的关系,以便做到功能的接口与具体的实现分离,这是最重要也是最基本的,如果连这点都做不到,你的程序也就是死的,丝毫不具备可扩展性.传统的解决方式是利用工厂模式来间接创建对象,但技术发展到今天工厂模式已经显得过了时,无论JNDI式的组件查询或者spring式的组件注入都能很好的解决此问题.具体使用什么由我们的架构师来决定. 其次应该考虑业务组件应该以怎样的方式来为表示层提供服务,此处是指单实例,多实例还是需要缓冲池. 处于性能上的考虑,此时应该优先使用单实例,如果业务对象确实存在线程不安全的因素,我们可以适当的使用同步,此时注意同步的范围应尽可能的小. 如果不安全的因素太大,以至于我们没有把握同步的很恰当,此时为每个线程单独提供一个对象也是不错的选择,因为JVM发展到现在对象的创建和回收已经不会过分影响性能. 至于实例池,就像工厂模式一样,也显得有些过了时. 接下来,在业务层我们要考虑系统究竟需要哪些企业级服务,事务? 安全?分布式? 线程池... 企业服务往往由系统框架负责解决,使用EJB式的重量级解决方案或者spring式的轻量级,同样由我们的架构师来决定.
数据访问层:要考虑的问题首先是是否适合使用ORM, 在实际项目中我们往往看到项目经理未经大脑般的强迫开发者必须使用hibernate,JDO等工具,而实际我们是否需要它们却从未认真思考过. ORM除了解决对象和关系的不匹配,最大的作用就是在业务层和数据库之间加了一层缓存,数据从内存从获取显然比从数据库查找要快得多,这就说明了在读取数据较多的时候使用ORM是不错的注意,而在写入数据较多的时候,往往就没那么必要使用它. 而在一个系统中有很多模块,往往有的模块读多于写而有的写多于读,此时我个人认为甚至可以在某
些读的模块使用ORM,而写的模块不使用. 当然,在不使用的地方我们需要按照常用的设计模式,将数据访问的代码单独的抽离出来.
后台数据库:我们要思考整个系统是否要应对不断增长的负载请求,是否需要具有集群能力,如果是,我们有必要选择类似Oracle9i这种具有集群能力的数据存储设备,否则将会在数据库造成性能瓶颈. 我们还应该对存储过程的使用进行思考,网上也有很多关于存储过程的讨论帖子,这里我比较赞同一篇好象叫什么'存储过程是天使还是魔鬼'的贴子的观点:存储过程可以用来处理数据,但不适合处理业务.
除了以上层次的思考,对于一些常见的企业问题,也应该加以考虑:
1.客户状态的保存
究竟是保存在客户端?表示层? 业务层? 或者后台数据库.如果保存在客户端,对于C/S应用来说这不是问题,因为胖客户端的存储能力十分强大. 而对于目前大多数的浏缆器客户端,就成了问题,无论是页面隐藏字段还是Cookies都不能存储很大的数据量,而且Cookies更是面临安全问题. 其次客户端的数据往往需要网络传递到服务器,这也增加了网络负担. 状态保存在表示层或是业务层从本质上来说都是保存在内存中(排除某些高手保存在其他设备或文件里),因为在内存中,所以在访问性能上会更有优势,例如常用的HttpSession或有状态会话Bean. 有状态会话Bean我没用过,但口碑不是很好. 而如果在集群环境中内存中的状态往往需要在节点间复制,这会带来开销,所以如果是集群环境还是不介意把大量数据放在内存中. 此时应把数据尽量放在数据库中,虽然这会增加编程量并且降低性能(因为每次取状态到要查数据库),但伸缩性会得到显著的提高.
2.关于并发
我个人喜欢把并发分成三类:
数据库级别的并发:这发生在多个系统事务在同一时间试图操作同样的数据的
时候,此时往往通过事务的隔离级别来解决.隔离级别过小会使数据不安全,而隔离级别过大又会降低数据库性能.因此大部分数据库将隔离级别设置成Read Committed,意思就是说一个事务在执行过程中可以得到其他事务已经提交的更新(注意是更新而不是插入). 而此时为了在一个事务内的多次查询中获得同样的数据,我们往往还需要将这多个查询放在一个只读事务里.
代码级别的并发:这发生在某个类中具有不安全因素(例如具有多个线程都可以修改的类变量),而这个类又处在多线程访问的模式下. 此时我们往往通过具体语言提供的同步机制来解决,在安全的同时也降低了性能,因为一个线程在访问时其他线程必须等待.
应用程序级别的并发: 这发生在多个业务事务同一时间操作同样的数据的时候,这会带来丢失更新和不一致读,在对数据的实时性要求不是很高的系统中,不一致读往往不是问题,用户也不会觉得不合理. 而在用户操作数据时发生丢失更新往往不能忍耐. 此时我们的解决方案是应用程序级别的锁定. 一种是乐观锁,通过给记录加版本号,在操作提交时如果发现在操作期间其他人修改过该条记录,则提示用户更新失败. 这适合在并发机率很低的情况使用,因为用户很可能填了一堆东西你却告诉他失败需要重填,他会发疯. 另一种是悲观锁,通过严格限制来避免冲突. 悲观锁分为写锁和读锁,写锁很简单,一个人在操作一条记录的时候其他人只能读该记录,而不能操作. 而读锁很严格,它又分为共享读锁和独占读锁,共享读锁指一个人只要在读该记录的时候,其他人就也只能读不能操作.而独占读锁是所有锁中最严格的,他实现只要一个在正在读该记录,其他人就不能读,这是为了保证用户获得的一定是最新记录,它假定其他人只要在读一条记录,就可能会修改它. 因为悲观锁需要在操作期间不断的加锁解锁,会严重影响性能,并且实现起来很麻烦,所以尽量少使用.
注: 系统事务指数据库级别的事务,对应用程序来说是指在一次请求或一次方法调用的过程中发生的数据处理. 与数据库中的事务是一个概念. 而业务事务指用户完整执行一次业务相关的操作过程中的数据处理.一次业务事务往往包含多个系统事务,例如首先将数据查询出来,然后修改提交,这是一次业务事务,但包含了查询和修改两个系统事务.
3.关于分布式
在技术发展到今天关于分布式已经没有太多讨论价值,一句话,能不用就别用. 只有以下几种情况才需要用:一是C/S应用,没办法的事. 二是表示层和业务层被分配到不同机器上(彪子经常这么干). 三是业务组件被分配到不同机器上(以前大伙都这么干,说有伸缩性)
分享到:
相关推荐
通过对软件架构的深入理解,开发者能够设计出更高效、可扩展和易于维护的系统。本课程件主要探讨了软件架构的重要性、体系结构建模的必要性以及常见的架构风格和模式。 首先,软件体系结构建模是为了应对复杂系统的...
架构的核心任务就是对这样的系统进行有序化重构,通过合理的设计,让系统各部分按照特定的方式协同工作,减少熵增,让系统能够适应变化,持续进化。 架构实现无序到有序的方式可以总结为“分和合”两个基本手段。分...
架构漫谈(二):认识概念是理解架构的基础 架构漫谈(三):如何做好架构之识别问题 架构漫谈(四):如何做好架构之架构切分 架构漫谈(五):什么是软件 架构漫谈(六):软件架构到底是要解决什么问题? 架构...
首先,我们要理解什么是架构设计。架构设计是系统开发的早期阶段,它定义了系统的主要组件、它们之间的关系、接口和交互方式。这个过程包括选择适当的技术栈、确定系统架构模式,并确保这些设计决策符合业务需求和...
软件架构是构建软件系统的基础,它是从整体到部分的最高层次划分,决定了系统的基本结构和组织方式。...理解并掌握良好的架构设计原则和模式,对于创建可靠的、安全的、可扩展的软件系统至关重要。
深入理解Nginx模块开发与架构解析(完整版) pdf,nginx必备知识
深入理解OpenWRT架构 OpenWRT是一款基于Linux的嵌入式操作系统,主要应用于路由器、交换机、网关等网络设备。OpenWRT架构可以分为多个部分,包括安装、配置、编译、镜像生成等步骤。 安装准备 在安装OpenWRT之前...
架构师在处理架构问题时,会涉及到很多方面,例如技术选择、业务理解、系统性能、用户体验等。架构师需要在这些不同的方面找到平衡点,从而设计出既能够满足当前需求又具备良好扩展性的架构。 架构师在工作中面临的...
系统架构设计程序员向架构师转型之路是一项艰巨但充满挑战的任务,涉及到技术深度、广度、沟通能力以及业务理解等多个方面。以下是对这一主题的详细阐述: 首先,我们要明确架构师的角色。架构师并不仅仅是高级...
这三份PDF文档集成了理论与实践,为读者提供了全面的视角来理解架构师的工作,无论是对初入行业的新人,还是经验丰富的专业人士,都能从中获益。通过深入阅读,我们可以提升自己的架构设计能力,更好地理解和应对IT...
5. **质量属性**:分析和评估架构对关键质量属性的影响,如性能、安全性、可用性和可伸缩性。 6. **依赖关系**:描述组件之间以及组件与外部环境之间的依赖关系。 7. **架构决策**:记录在设计过程中做出的重要...
这种能力不仅源于架构师的专业技术知识和经验积累,还来自于他们对业务场景的理解、对人性的把握以及对世界的认知。 架构师应具备的自我驱动力、积极主动、持之以恒的精神,以及高效学习、发现自我、形成模式、目标...
完成第10至15章的学习后,应该对层次式架构、企业集成架构、面向切面的编程架构、嵌入式系统架构以及面向服务的架构等有深入的理解和实践。 系统架构师的学习笔记强调了“规划”在架构设计中的重要性,规划是架构的...
首先,我们要理解什么是软件架构。软件架构是软件系统的高层次结构,它描述了主要的组成部分(如模块或服务)及其相互作用。它为开发团队提供了一个共享的理解,明确了系统的整体结构和关键决策,以便于后续的设计、...