面向对象的应用服务层设计前言N层的应用软件系统,由于其众多的优点,早已沦为典型的软件系统架构,也早已为广大开发人员所熟悉。在一个典型的三层应用软件系统中,应用于系统一般来说被区分成以下三个层次:数据库层、应用服务层和用户界面层。其中,应用服务层集中于了系统的业务逻辑的处置,因此,可以说道是应用软件系统中的核心部分。
软件系统的健壮性、灵活性、可器重性、可升级性和可维护性,在相当大程度上各不相同应用服务层的设计。因此,如何建构一个较好架构的应用服务层,是应用软件开发者必须侧重解决问题的问题。
1/39为了使应用服务层的设计超过最差的效果,我们一般来说还必须对应用服务层作更进一步的职能分析和层次细分。很多开发者在建构应用服务层的时候,把数据库操控、业务逻辑处置甚至界面显示夹杂着在一起,或者,把业务逻辑处置等同于数据库操控,等等,这些,都是有缺陷的作法。本文,就在这个方面展开设计时可使用的方案展开一些探究。
为了使辩论更加具备针对性,本文不会辩论一些较为风行的系统架构,例如J2EE架构,以及JDO。在微软公司的.Net平台上,将以Websharp中间件为事例。Websharp中间件是笔者研发的一个建构在微软公司.Net平台之上的一个中间件系统,也是构建文章所述的系统架构的承托系统。
搭配这些架构做到例子,也是因为.Net经常出现的时间较为较短,目前在这个平台上没成熟期统一的架构,而J2EE是目前最成熟期的建构企业应用的平台。自本人的《利用.Net框架研发应用于系统》和《空战揭露:研发.Net平台应用于系统框架》两篇文章公开发表以来,接到很多对系统和写信,明确提出了很多问题。因为时间的关系,无法一一恢复,因此,也借本文给大家一些答案。必须解释的是,原本的Jobsinfo现在早已做到了升级,名称更改为Websharp。
2/39设计的原则和评判标准同软件工程的原则一样,应用服务层的设计,必需遵循的最重要的原则就是低内聚和较低耦合。软件分层的本来目的,就是提升软件的可维护性和可器重性,而低内聚和较低耦合正是达成协议这一目标必需遵循的原则。
尽可能减少系统各个部分之间的耦合度,是应用服务层设计中必须重点考虑到的问题。内聚和耦合,包括了纵向和横向的关系。功能内聚和数据耦合,是我们必须达成协议的目标。
纵向的内聚和耦合,一般来说反映在系统的各个模块、类之间的关系,而横向的耦合,反映在系统的各个层次之间的关系。系统的框架,一般来说包括了一系列规范、誓约和承托类库、服务。3/39对于如何辨别一个软件的系统框架的好坏,笔者指出,可以从以下几个方面来评判: ◆系统的内聚和耦合度这是确保一个系统的架构否合乎软件工程原则的首要标准。
◆层次的明晰和简洁性系统每个部分已完成功能和目标必需是具体的,某种程度的功能,应当只在一个地方构建。如果某个功能可以在系统有所不同的地方构建,那么,将不会给后来的研发和确保带给问题。系统应当简单明了,过分简单的系统架构,不会带给不必要的成本和确保可玩性。
在尽量的情况下,一个部分应当已完成一个分开并且原始的功能。4/39◆更容易构建性如果系统架构的构建十分艰难,甚至远超过团队现有的技术能力,那么,团队被迫花上很多的精力用作架构的研发,这对于整个项目来说,可能会得不偿失。非常简单就是美。◆可升级和可扩充性一个系统框架,不受设计时技术条件的容许,或者设计者本人对系统了解的局限,有可能会考虑到今后所有的变化。
但是,系统必需为将来有可能的变化作好打算,需要在今后,在目前有数的基础上展开演变,但会影响原先的应用于。接口技术,是在这个方面广泛应用于的技巧。
5/39◆否不利于团队合作开发一个好的系统架构,某种程度只是从技术的角度来看,而且,它还应当限于于团队研发模型,可以便利一个研发团队中各个有所不同角色的相互协作。例如,将Web页面和业务逻辑组件分离,可是使页面设计人员和程序员的工作分离来同步进行而会相互影响。◆性能性能对于软件系统来说是很最重要的,但是,有的时候,为了能让系统获得更大的灵活性,有可能被迫在性能和其他方面获得均衡。
另外一个方面,由于硬件技术的飞速发展和价格的上升,性能的问题往往可以通过用于用于更佳的硬件来取得提高。6/39应用服务层的内容应用服务层,一般来说也被称作业务逻辑层,因为这一层,是应用软件系统业务逻辑处置集中于的部分。然而,我将这一层称作应用服务层,而不称之为业务逻辑层,因为,这一层必须处置的某种程度是业务逻辑,还包括了其他方面的内容。
7/39从原始的角度来说,应用服务层必须处置以下内容:◆数据的回应方式数据,是软件处置的对象。从或许上来说,软件,就是数据结构特算法的众说纷纭,是有一定意义的。在面向对象的系统中,数据是用类来回应的,代表了现实世界实体对象在软件系统中的抽象化。考虑到所谓的MVC模式,这个部分的类归属于M--实体类的范畴。
由于应用软件一般来说不会用于数据库,数据库中的数据,可以看作是对象的长久化留存。由于数据库一般是关系型的,因此,这个部分,还必须考虑到类(对象)同关系型数据的同构,即一般来说所说的O-RMAP问题。
8/39◆数据的读取方式如同上述所说,软件系统处置的实体对象数据必须长久化留存数据库中,因此,我们必需处置系统同数据库的交互,以及数据的读取和切换方式的问题。◆业务逻辑的的组织方式在面向对象的系统中,业务逻辑展现出为对象之间的交互。有了上述的实体对象,以及对象的留存策略,就可以将这些对象人组一起,撰写我们的业务逻辑处理程序。
在业务逻辑的处置中,必需确保处置的正确性和完整性,这将不会牵涉到到事务处理。一般来说,我们也不会把业务逻辑PCB成组件的形式,以获得仅次于的可器重性。9/39◆业务服务的获取方式在我们已完成系统的功能后,如何向客户获取服务,是我们必须考虑到的问题。
这里的客户,某种程度是指软件的使用者,也还包括调用的界面、其他程序等。例如,在一个基于Web的ASP.Net或JSP系统中,业务逻辑功能的客户乃是这些ASP.Net页面或JSP页面。
业务逻辑组件应当通过什么方式,必要的,或间接的,向这些客户获取服务,是这一层必须已完成的任务。◆层的部署和层间交互对于一个多层的应用软件系统来说,特别是在是大型的应用软件系统,一般来说必须把有所不同的部分部署在有所不同的逻辑或物理设备上。
尤其是一些基于Web的应用软件系统,其部署工作将牵涉到到Web服务器、组件服务器、数据库服务器等有所不同的服务设备。在展开应用软件架构的设计的时候,必需考虑到各种有所不同的部署方案。10/39综上所述,一个原始的基于Web的应用软件系统,其架构可以用右图来回应(Websharp引荐的应用软件系统架构):对于以上各个方面来说,每个问题都可以有很多种策略和方案,但是,在一个系统中,应当尽量的统一这些策略和方案。
也就是说,在一个系统,或者一个项目中,应当统一每个解决问题每个问题所使用的方法。软件的开发方法是灵活性的,可以用有所不同的方法解决问题完全相同的问题,这不会引诱开发人员使用他们指出需要展现出自己的方法,但是,从整个系统来看,这将不会是灾难性的。
我们应当尽量统一,就是,使用统一的数据表示方式、统一的数据读取方式、统一的业务逻辑处理方式等。下面,将就这些部分的设计策略和能用方案展开一些较为详尽的阐述。11/39数据实体的回应应用软件系统,从本质上来说,是计算机对现实世界的仿真。现实世界中的实体对象,在软件系统中,展现出为必须处置的数据。
在面向对象的系统中,这是通过类和对象来回应的。参照知名的MVC模式,类可以分为实体类(M)、掌控类(C)、和边界类(V),分别代表了实体对象、掌控和界面显示。系统中必须处置的数据,在面向对象的系统中,归属于实体类部分。
12/39在考虑到数据实体层的设计策略的时候,必须做到以下要点:◆完全一致的数据表示方式。在一个系统中,数据的回应方式必需尽量统一,同时,在处置单个数据和多个数据的时候,处理方式尽量完全一致。
◆因为数据一般来说是必须存储到数据库中,因此,较好的同构方法是必须的。◆处置好对象的粒度,即所谓的粗粒度对象、细粒度对象。
13/39一般例子考虑到一个现实的例子,一个仓库中的产品(Product),在系统中可以用于如下定义:publicclassProduct{publicstringName;//名称publicdecimalPrice;//价格publicintCount;//数量}可以按照如下方法用于Product类:Productp=newProduct();//……处置Product14/39这是一个包括了三个属性的Product类的定义。为了便于解释,在这里,我们尽可能将问题修改了。又例如,一张入库单可以用于如下定义:publicclassForm{publicstringID;//入库单编号publicDateTimeAddTime;//入库时间publicFormDetail[]FormDetails;//入库单明细}publicclassFormDetail{publicProductInProduct;//入库产品publicintCount;//入库数量}15/39对于处置单个对象,一般来说使用上述的方法,但是,当我们必须处置完全相同类的一组对象,也就是处置一个对象子集的时候,就不会有一些小小的困难。
如前所述,我们期望在处置单个对象和对象子集的时候,处置的方式尽可能统一,这对于软件开发的意义是相当大的。常用的处置对象子集的方法有:◆数组回应的方法例如,上面的例子中当一张入库单包括多条入库单明细的时候使用的方法。为了灵活性,也可以用于容器来,如Java中的Vector或C#的ArrayList(C#)。
只是,在处置对象的时候,必须一个构造函数的操作者。这个问题,在反对泛型的语言中会不存在,如用于C++的标准库的容器类。
16/39◆ObjectCollection方法。这个方法同上面的方法类似于,不同之处在于,为每个实体类设计一个Collection类。例如,可以为FormDetail设计一个FormDetailsCollection类(C#):publicclassFormDetailsCollection:ArrayList{publicvoidAdd(FormDetaildetail){base.Add(detail);}publicnewFormDetailthis[intnIndex]{get{return(FormDetail)base[nIndex];}}}这么做到的益处在于,在操作者子集中的对象时,不用展开构造函数的操作者。
17/39◆数据集的回应方法。使用这种方法,一般来说是必要把从数据库查找中提供的数据集(Recordset)作为数据处理对象。这种方法在ASP应用程序中是十分少见的作法。这种作法非常简单,初学者很更容易掌控,但是弊病也很多。
EJB的方法在J2EE体系中,对实体对象的处置的典型方法是EntityBean。J2EE中用于EntityBean来回应数据,以及封装数据的长久化储存(同数据库的交互)。由于EntityBean较为消耗资源,而且使用的是远程调用的方式来采访,因此,在必须传送大量数据,或者在有所不同的层次之间传递数据的时候,往往还不会使用一些诸如值对象(ValueObject)的设计模式来提高性能。
关于J2EE中的设计模式的更好内容,读者可以参照《J2EE核心模式》一书。18/39JDO的方法相对于J2EE这个便宜的方法来说,JDO获取了一个比较轻量级的方案。
在JDO中,你可以使用一般的作法,撰写实体类,然后,通过一些增强器对这些类展开增强,以使其合乎JDO的规范,最后,你可以通过PersistenceManager来构建对象的长久化储存。无论是EJB还是JDO,在同数据库展开同构的时候,都搭配了XML配置文件的方式。这是一种灵活性的方式。
由于XML强劲的表达能力,我们可以很好的用它来叙述代码中的实体类和数据库之间的同构关系,并且,不必在代码中展开软编码,这样,在情况发生变化的时候,有可能只必须改动配置文件,而不必去改动程序的源代码。关于EJB和JDO的配置文件的更好的信息,各位可以参照涉及的文档,这里仍然赘述了。然而,用于XML配置文件的方式并不是唯一的方法,在微软公司获取的一些案例中,如Duwamish示例,就没使用这种方式。
至于开发人员在研发过程中明确使用哪种方式,是必须根据具体情况展开权衡和权衡的。19/39Websharp的方法Websharp在数据的展现出上,充分利用了.NetFramework类库中DataSet的功能,设计了一个EntityData类。
这个类承继了DataSet,并减少了一些属性和方法。某种程度的,同数据库的同构关系,也是使用XML配置文件的方式。
在实际的应用于中,要提供一个实体对象,可以通过如下方式获得:EntityDataCustomer=EntityDataManager.GetEmptyEntity(Customer);然后,可以通过如下方式来采访这个对象的属性:stringCustomerID=Customer[CustomerID]20/39可以看见,这种方式同传统的方式有点有所不同。在这种方式下,数据的表现形式只有一个,那就是EntityData。其益处是显著的,不必为每个实体都分开撰写一个类,需要大大减少代码的撰写量。
其缺点也很显著,那就是无法利用编译器类型检测的功能,如果在调用对象的属性的时候,写错了属性的名称,就有可能错误,但是,这个问题可以通过工具来解决问题。关于这个方面更为详尽的信息,可以参看拙文:《利用.Net框架研发应用于系统》《空战揭露:研发.Net平台应用于系统框架》21/39数据的读取方式数据读取的目的,是长久化留存对象,以待后来的用于,如查找、改动、统计分析等。读取的对象,可以是数据库、普通文件、XML甚至其他任何方式,只要保证数据需要持久留存,并且,会不受断电、系统重起等因素的影响。
在这个部分,最理想的状况,大自然是需要反对除了数据库以外的各种类型的读取方式,或者,最少尚存模块,需要较为便利的扩展。因为数据库是最常用,也是最有效地的数据存储方法,因此,反对数据库存储是最首先必需反对的。
在有所不同的平台下,有有所不同的数据库采访的手段。例如,在Java平台下,有JDBC,在Windows平台下,可以用于ADO、ADO.Net等。但是,这些手段还较为相似底层,在实际操控数据库的时候,必须撰写大量的代码,并且,我们还必须通过手工的方式来已完成将程序中的面向对象的数据存储到关系型数据库的工作。
这么做到,大自然编程的效率不低,并且非常容易错误。但是,不可否认,这也是一种可以搭配的方式。
22/39从另外一个方面来看,由于我们前面早已解决问题了数据的同构问题,因此,在数据的读取方面是十分有规律的,我们几乎可以让这个工作通过框架来继续执行。这样,我们一方面可以修改很多同数据库交互方面的代码撰写工作量,需要增加经常出现Bug的几率,另一方面,由于框架PCB了有所不同数据库之间的差异,使得我们在编写程序的时候,不必考虑到有所不同数据库之间的差异,而将这个工作转交框架去做到,构建软件的后台数据库牵涉到性。在这个部分,以下两个部分的类会变得尤其最重要:◆对象--关系同构的分析类,需要通过既定的方案已完成对象--关系的同构,确认数据读取方案◆数据库操控类:根据同构关系,将数据精确的存储到数据库中,并且PCB有所不同数据库之间的差异。
23/39在J2EE中,这个部分较为典型的就是EntityBean中的CMP。由于在BMP中,同数据库的交互部分必须通过手工撰写代码的方式来构建,因此,很难享用到容器带给的便捷,只是由于EJB2.0以前的标准,CMP的功能,还包括同构能力、实体关系模式等方面的功能较为很弱,所以,在很多时候,我们被迫用于BMP。现在,EJB2.0,在这个方面的功能早已十分强劲了,我们几乎可以享用容器带给的便捷,而将大部分精力放到构建更为简单的业务逻辑方面了。
24/39在JDO中,您某种程度可以通过PersistenceManager来构建某种程度的目标,例如,您想要把一个Customer对象留存到数据库中,可以使用类似于下面的代码:Customercustomer=newCustomer(……);PersistenceManagerPM=PMFactory.initialize(……);Pm.persist(customer);代码某种程度十分简要和直观,没一大堆数据库操控的代码,也不更容易再次发生差错。25/39Websharp的方案Webshap为数据读取的类定义了IEntityDAO模块,该模块的定义如下:publicinterfaceIEntityDAO{voidInsertEntity(EntityDataentity);voidUpdateEntity(EntityDataentity);voidDeleteEntity(EntityDataentity);EntityDataFindByPrimaryKey(objectKeyValue);}26/39对于每一个实体类,可以通过拓展这个模块来构建数据采访的类。但是,由于这个模块没获取任何构建方法,因此,到明确每个构建类的时候,如果是必要拓展自这个模块,构建的代码还必需手工填上。为了提升研发效率,增加代码撰写量和经常出现Bug的可能性,框架获取了AbstractSingleTableDAO和AbstractMultiTableDAO.cs类,这两个类拓展自IEntityDAO,分别构建了针对单个数据库表和多个数据库表的数据库采访方法,并且,构建了IDisposable模块。
这样,我们在实际撰写代码的时候,只必须承继自这两个类就可以了。例如,Customer类的数据读取类可以定义如下:publicclassCustomerEntityDAO:AbstractSingleTableDAO27/39然后,就可以在代码中这么用于:Customercustomer=......using(CustomerEntityDAOCDO=newCustomerEntityDAO()){CDO.UpdateEntity(customer);}更为一般的,Wensharp也获取了PersistenceManager类,可以用作将EntityData中的数据现金数据库。这个类包括了两个方法:PersistEntity和DeleteEntity。
如果想为某个实体类撰写专门的DAO类,那么,也可以用于这个类来操控实体对象。不过,目前,只反对同构成单个表的对象的自动存贮。下面是一个例子:28/39PersistenceManagerpm=PersistenceManager.Initial();pm.PersistEntity(entity);为了PCB有所不同数据库的操作者,统一的数据库采访模块是必需的。
关于撰写标准化数据库采访类的内容,可以参看拙作:《用于设计模式建构标准化数据库采访类》。在这个部分,另外必须留意的是,为了保证数据存储的完整性,应该考虑到事务处理的功能。J2EE、JDO和Websharp都反对在数据存储的时候用于事务处理。
29/39业务逻辑的处置有了上面的工作,我们就可以把这些对象人组一起,撰写我们的业务逻辑。在面向对象的系统中,业务逻辑展现出为对象之间的交互。
在一些非常简单的系统中,没简单的业务逻辑,只是一些数据的确保工作,那么,有了上面两个部分的工作,我们实质上有可能早已忘成了大部分的工作。在这个部分,由于有所不同系统之间业务逻辑千差万别,基本上没办法获取统一的模式。但是,应该留意的是,在同一个系统中,使用大致相同的策略是十分适当的,这有助避免项目内部的不一致性,使项目更为高效率。甚至于,这些策略可以拓展成公司部分、甚至所有项目的策略。
有一点认为的是,很多人在这个部分操控数据库,把业务逻辑处置等同于数据库操作者,这是不是非的。在业务逻辑处置中,处置的应当是对象,而不是必要同数据库做事,这样,才能取得更佳的系统结构。30/39在业务逻辑处置部分,由框架获取一些承托的服务是十分适当的。这其中,最重要的一点就是事务的处置。
业务逻辑的处理过程,不会牵涉到到多个对象之间的交互,以及多次同数据库的交互。为了确保处理过程的完整性,必需用于事务处理的方法。框架必需反对事务处理。
事务处理的功能,基本上有两种自由选择:用于基于数据库相连的事务、用于外部事物处置服务。用于基于数据库相连的事务,事务处理的性能比较较为低,但是,当系统牵涉到到多个数据库之间的交互时,基于数据库相连的事务之后无能为力了。而用于专用的事务处理服务,需要适应环境更好的情况,并且,有测试表明,随着数据处理量的下降,两者之间的性能差异不会渐渐增大。在J2EE中,容器获取了事务处理的能力。
在.Net平台上,事务处理是通过WindowsCOM+服务来获取的。在Websharp中,对COM+服务做到了一个非常简单的PCB。同时,也需要用于基于数据库相连的事务。31/39下面是一个非常简单的例子,回应了一张入库单入库的过程,在这个过程中,必须改动入库单上每种产品的现有库存量:publicvoidStoreIntoWarehouse(EntityDatainsertForm){insertForm.SetCurrentTable(FormDetail);TransactionManagertransManager=newTransactionManager();ProductEntityDAOproductDAO=newProductEntityDAO(true);FormEntityDAOformDAO=newFormEntityDAO(true);try{32/39if(insertForm.CurrentTable.Rows.Count0)do{stringproductID=insertForm[ProductID].ToString();decimalinCount=insertForm.GetDecimal(InCount);EntityDataproduct=productDAO.FindByPrimaryKey(productID);product[CurrentCount]=product.GetDecimal(CurrentCount)+inCount;transManager.AddMethod(newTransactionManagedFunction(productDAO.UpdateEntity),product);}while(insertForm.Next());transManager.AddMethod(newTransactionManagedFunction(formDAO.InsertEntity),insertForm);33/39transManager.ExecuteMethods();}catch(Exceptionee){throwee;}finally{productDAO.Dispose();insertForm.Dispose();}}34/39业务服务的获取业务外观层(BusinessFacade)的目的,是隔绝系统功能的提供者和使用者,更加具体地说道,是隔绝业务逻辑的软件的用户界面(可以参看Facade设计模式)。
这一层没任何必须处置的逻辑,只是作为后台逻辑处置和前端用户界面的缓冲区,以超过如下目的◆将用户界面和系统业务逻辑处置分离,这样,当业务逻辑发生变化时,不必改动客户端程序,是一种反对变化的设计方法。◆使同一个业务逻辑需要处置有所不同的客户端催促。
例如,可以将Facade设计成WebService,这样,可以同时为传统的WinForm客户端程序、Web程序以及其他外部系统获取服务,而用于完全相同的应用服务层,同时,也可以构建系统的分布式部署。关于如何做这一点,可以参看本文附有的Demo程序。
35/39◆作为系统有所不同模块之间的调用模块。一个系统一般来说不会包括很多模块,这些模块比较独立国家,又有可能相互调用。
为了增加各个有所不同部分之间的耦合度,必需使用一定的设计方法,Facade设计模式就是十分有效地的一种,也是业务外观层的基础。◆不利于项目团队的分工协作。业务外观层作为一个采访模块,将界面设计人员和逻辑设计人员分离,使得系统的研发可以构建横向的分工,有所不同的开发人员可以注目自己的领域而会受到阻碍。业务外观层的代码框架,在系统分析和设计已完成后就可以已完成,他必须获取的方法,就相等于在界面设计人员和逻辑设计人员之间签定了一个协议,他虽然没构建任何逻辑,但是,他的引进,能使系统的研发更为有条理,更为简要。
套用《设计模式》上的一句话,就是,任何问题,都可以通过引进一个中间层来获得修改。36/39剪裁和权衡以上四个层次,对于大型的应用软件系统来说,是十分适当的。但是,对于一些小型的应用软件系统,如果几乎按照以上的层次来做到,有可能反而不会影响工作效率。
因此,针对有所不同的系统,可以对架构展开一定的剪裁。数据实体层和实体掌控层,是每个应用软件系统所必须的,似乎无法削减。对于业务逻辑层和业务外观层,根据实体情况,可以展开如下削减:◆如果系统没简单的业务逻辑,而只是一些数据的操作者,或者业务逻辑尤其较少,那么,可以省略业务逻辑层,而将涉及的功能移到实体掌控层。
◆如果不考虑到多种客户端的情况,也不考虑到分布式部署的问题,系统的模块又很少,会产生模块间紧耦合的情况,那么,可以不用于业务外观层,而让用户界面程序必要采访业务功能。37/39在上面的阐述中,对于每个层次,都说明了可以自由选择的多种方案,每一种方案都有他的优点和缺点,在明确研发的过程中,必须根据具体情况加以权衡。系统外的话应用软件系统架构,是软件工程的最重要组成部分。
设计一个好的框架,其目的很具体,那就是,在目前还没银弹之前,尽仅次于的有可能,提升软件开发的效率和软件质量,把不必要的工作和更容易错误的工作,转交框架去处置。应用服务层,在软件系统中,是一个非常复杂的部分,乍看之下,没任何规律不切实际,给人无从下手的感觉。我们的目标,就是尽可能化无规律为有规律,把有规律的东西萃取出来,构成规范,从而增加今后的研发工作量。其方法,就是对系统展开合理的分层,这样,系统的层次明晰了,每个层次已完成的功能就较为单一,就意味著每个层次的都比较更加有规律难以确定,这样,我们就可以把这些有规律的东西转交框架去继续执行,或者,研发一个辅助工具,来已完成这部分的代码撰写工作。
Websharp就获取了这样一个代码自动分解的工具。这个工具被设计成VisualStudio.Net构建研发环境的插件,在实际研发过程中,需要获取很多便捷。这是系统层次明晰带给的另外一个益处。
38/39对于一个软件公司来说,统一的系统框架的意义某种程度在于软件开发的本身。一个统一的系统框架,也是公司科学知识管理的最重要组成部分。公司如果有一个或受限个数的具体的软件框架,那么,这些框架就可以沦为凝固公司开发人员经验、智慧的载体,并且可以在大大的实践中加以扩充和完备。
由于公司的软件系统的框架较为统一,那么当某个项目替换或减少开发人员的时候,后来的人也需要较为更容易接掌,这对于公司的研发管理是具备十分最重要的意义的。关于系统框架同科学知识管理的关系的内容,因为不是本文的重点,仅限于篇幅的关系,所以仍然赘述,不会另文加以解释。
39/39结语应用软件系统的应用服务层是非常复杂的,为了使得系统的结构更为明晰,找到其中规律性的东西,就必须我们对系统做到更进一步的层次区分。对于每个层次,都可以有多种设计的策略,每一种策略都不有可能做尽善尽美,这就必须我们在实际中加以权衡。仅限于本人的了解和水平,文章中所说观点和方法或有不当之处,还请求大家需要指教,一起探究。
本文来源:云开·体育全站APPkaiyun-www.0395best.com