`

企业管理软件开发架构之三 系统分层组织结构

阅读更多
原帖地址:http://www.cnblogs.com/JamesLi2015/archive/2013/06/14/3135033.html

我给MIS类型的软件分四个实现层次,三层架构。

BusinessLogic 业务实体 由LLBL Gen 生成业务实体,代码生成器生成

Interface 数据访问接口 根据实体产生的数据访问接口,由Code Smith生成

Manager 接口实现 根据实体产生的数据访问接口的实现代码,由Code Smith生成

UI 界面层 拖拉控件,绑定数据到界面中

image_thumb2

 

Business Logic 业务实体层

以ORM作为数据访问基础技术,业务实体中包含数据之间的关系逻辑,而不再是用于填充数据的实体。

image

以上结构由LLBL Gen自动生成,它已经为我们生成了实体,实体验证类型,数据访问接口和相关的辅助类型。

公司注册中的公司实体,它的定义如下代码所示

[Serializable]
public partial class CompanyEntity : CommonEntityBase
// __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces
// __LLBLGENPRO_USER_CODE_REGION_END


{
#region Class Member Declarations
private EntityCollection<ModuleEntity> _modules;

// __LLBLGENPRO_USER_CODE_REGION_START PrivateMembers
// __LLBLGENPRO_USER_CODE_REGION_END
#endregion

#region Statics
private static Dictionary<string, string> _customProperties;
private static Dictionary<string, Dictionary<string, string>> _fieldsCustomProperties;

/// <summary>All names of fields mapped onto a relation. Usable for in-memory filtering</summary>
public static partial class MemberNames
{
/// <summary>Member name Modules</summary>
public static readonly string Modules = "Modules";
}
#endregion

/// <summary> Static CTor for setting up custom property hashtables. Is executed before the first instance of this entity class or derived classes is constructed. </summary>
static CompanyEntity()
{
SetupCustomPropertyHashtables();
}

/// <summary> CTor</summary>
public CompanyEntity():base("CompanyEntity")
{
InitClassEmpty(null, null);
}

.....
}

<style type="text/css"><br/>.csharpcode, .csharpcode pre<br/>{<br/>font-size: small;<br/>color: black;<br/>font-family: consolas, "Courier New", courier, monospace;<br/>background-color: #ffffff;<br/>/*white-space: pre;*/<br/>}<br/>.csharpcode pre { margin: 0em; }<br/>.csharpcode .rem { color: #008000; }<br/>.csharpcode .kwrd { color: #0000ff; }<br/>.csharpcode .str { color: #006080; }<br/>.csharpcode .op { color: #0000c0; }<br/>.csharpcode .preproc { color: #cc6633; }<br/>.csharpcode .asp { background-color: #ffff00; }<br/>.csharpcode .html { color: #800000; }<br/>.csharpcode .attr { color: #ff0000; }<br/>.csharpcode .alt <br/>{<br/>background-color: #f4f4f4;<br/>width: 100%;<br/>margin: 0em;<br/>}<br/>.csharpcode .lnum { color: #606060; }</style>

LLBL Gen设计器生成的实体代码有几个特点




  • 生成有多个用途的构造方法(ctor)。我们经常用到的是不带参数的构造方法,和带有主键值参数的方法。



[EditorBrowsable(EditorBrowsableState.Never)]
protected CompanyEntity(SerializationInfo info, StreamingContext context) : base(info, context)
{
if(SerializationHelper.Optimization != SerializationOptimization.Fast)
{
_modules = (EntityCollection<ModuleEntity>)info.GetValue("_modules", typeof(EntityCollection<ModuleEntity>));
this.FixupDeserialization(FieldInfoProviderSingleton.GetInstance());
}
// __LLBLGENPRO_USER_CODE_REGION_START DeserializationConstructor
// __LLBLGENPRO_USER_CODE_REGION_END
}


 



<style type="text/css"><br/>.csharpcode, .csharpcode pre<br/>{<br/>font-size: small;<br/>color: black;<br/>font-family: consolas, "Courier New", courier, monospace;<br/>background-color: #ffffff;<br/>/*white-space: pre;*/<br/>}<br/>.csharpcode pre { margin: 0em; }<br/>.csharpcode .rem { color: #008000; }<br/>.csharpcode .kwrd { color: #0000ff; }<br/>.csharpcode .str { color: #006080; }<br/>.csharpcode .op { color: #0000c0; }<br/>.csharpcode .preproc { color: #cc6633; }<br/>.csharpcode .asp { background-color: #ffff00; }<br/>.csharpcode .html { color: #800000; }<br/>.csharpcode .attr { color: #ff0000; }<br/>.csharpcode .alt <br/>{<br/>background-color: #f4f4f4;<br/>width: 100%;<br/>margin: 0em;<br/>}<br/>.csharpcode .lnum { color: #606060; }</style>

这个构造方法用在序列化对象时发生,比如.net Remoting远程返回对象时。



 




  • 生成包含自定义属性的字段 自定义属性常用用属性的特殊设置。比如CompanyEntity.CompanyCode,实际中为了不区分CompanyCode的大小写,统一要求为大写,我们可以在此添加自定义属性RequiredCap,再到程序运行时读取此属性,并设置控件的字母大小写特性。



private static Dictionary<string, string>    _customProperties;
private static Dictionary<string, Dictionary<string, string>> _fieldsCustomProperties;


private static void SetupCustomPropertyHashtables()
{
_customProperties = new Dictionary<string, string>();
_fieldsCustomProperties = new Dictionary<string, Dictionary<string, string>>();
Dictionary<string, string> fieldHashtable;
fieldHashtable = new Dictionary<string, string>();
_fieldsCustomProperties.Add("CompanyCode", fieldHashtable);
......




Dictionary<string, string> fieldCustomProperties = CompanyEntity.FieldsCustomProperties["CompanyCode"];
string requiredCap = fieldCustomProperties["RequiredCap"];

<style type="text/css"><br/>.csharpcode, .csharpcode pre<br/>{<br/>font-size: small;<br/>color: black;<br/>font-family: consolas, "Courier New", courier, monospace;<br/>background-color: #ffffff;<br/>/*white-space: pre;*/<br/>}<br/>.csharpcode pre { margin: 0em; }<br/>.csharpcode .rem { color: #008000; }<br/>.csharpcode .kwrd { color: #0000ff; }<br/>.csharpcode .str { color: #006080; }<br/>.csharpcode .op { color: #0000c0; }<br/>.csharpcode .preproc { color: #cc6633; }<br/>.csharpcode .asp { background-color: #ffff00; }<br/>.csharpcode .html { color: #800000; }<br/>.csharpcode .attr { color: #ff0000; }<br/>.csharpcode .alt <br/>{<br/>background-color: #f4f4f4;<br/>width: 100%;<br/>margin: 0em;<br/>}<br/>.csharpcode .lnum { color: #606060; }</style>



读取自定义属性RequiredCap的值为true时,设置控件的CharachterCasing属性。



image



 



界面和逻辑分离



再来看业务实体的业务计算如何发生。示例代码如下所示



  protected override void OnFieldValueChanged(object originalValue, IEntityField2 field)
{
base.OnFieldValueChanged(originalValue, field);

switch ((CompanyFieldIndex)field.FieldIndex)
{
case CompanyFieldIndex.DriverAssembly:
OnChangeDriverAssembly((string)originalValue);
break;
}
}

private void OnChangeDriverAssembly(string originalValue)
{
if (this.DriverAssembly == originalValue || String.IsNullOrEmpty(DriverAssembly)) return;

this.DriverType = BaseCommon.GetProjectName(ModuleType.BusinessLogic, DriverAssembly);
}


<style type="text/css"><br/>.csharpcode, .csharpcode pre<br/>{<br/>font-size: small;<br/>color: black;<br/>font-family: consolas, "Courier New", courier, monospace;<br/>background-color: #ffffff;<br/>/*white-space: pre;*/<br/>}<br/>.csharpcode pre { margin: 0em; }<br/>.csharpcode .rem { color: #008000; }<br/>.csharpcode .kwrd { color: #0000ff; }<br/>.csharpcode .str { color: #006080; }<br/>.csharpcode .op { color: #0000c0; }<br/>.csharpcode .preproc { color: #cc6633; }<br/>.csharpcode .asp { background-color: #ffff00; }<br/>.csharpcode .html { color: #800000; }<br/>.csharpcode .attr { color: #ff0000; }<br/>.csharpcode .alt <br/>{<br/>background-color: #f4f4f4;<br/>width: 100%;<br/>margin: 0em;<br/>}<br/>.csharpcode .lnum { color: #606060; }</style>



当我在界面中改变当前界面插件程序集时,它会为我自动读取这个程序集的类型信息,项目命名信息。要理解这种方式,需要先理解.NET开发中的数据绑定技术。数据源控件相当于一个桥梁,连接数据实体和界面控件,当给数据源控件赋值时,控件会读取数据实体的值,当界面中的控件值发生改变时,借助于数据源控件,自动把更改后的数据回写到数据实体中。所以,当数据实体中值发生改变后,我们可以注册相应的改变事件,作出业务逻辑处理,数据源控件会读取改变之后的数据实体值,呈现在界面上。几乎所有的业务逻辑是依照此方式编程,也实现了界面和逻辑分离。



界面和逻辑分离后,界面中的作用就是将控件绑定到数据源控件,再以Code Smith来生成数据读写接口:



 public override EntityBase2 LoadEntity(string refNo)
{
IItemManager manager = ClientProxyFactory.CreateProxyInstance<IItemManager>();
ItemEntity customer = manager.GetItem(refNo);
return customer;
}

public override void DeleteEntity(EntityBase2 entity)
{
ItemEntity user = (ItemEntity)entity;
IItemManager manager = ClientProxyFactory.CreateProxyInstance<IItemManager>();
manager.DeleteItem(user);
}

public override void SaveEntity(EntityBase2 entity)
{
ItemEntity user = (ItemEntity)entity;
IItemManager manager = ClientProxyFactory.CreateProxyInstance<IItemManager>();
manager.SaveItem(user);
}


<style type="text/css"><br/>.csharpcode, .csharpcode pre<br/>{<br/>font-size: small;<br/>color: black;<br/>font-family: consolas, "Courier New", courier, monospace;<br/>background-color: #ffffff;<br/>/*white-space: pre;*/<br/>}<br/>.csharpcode pre { margin: 0em; }<br/>.csharpcode .rem { color: #008000; }<br/>.csharpcode .kwrd { color: #0000ff; }<br/>.csharpcode .str { color: #006080; }<br/>.csharpcode .op { color: #0000c0; }<br/>.csharpcode .preproc { color: #cc6633; }<br/>.csharpcode .asp { background-color: #ffff00; }<br/>.csharpcode .html { color: #800000; }<br/>.csharpcode .attr { color: #ff0000; }<br/>.csharpcode .alt <br/>{<br/>background-color: #f4f4f4;<br/>width: 100%;<br/>margin: 0em;<br/>}<br/>.csharpcode .lnum { color: #606060; }</style>



系统中所有与数据库读写相关的界面代码均是以此方式实现。



 



Interface/Implementation 接口层和接口实现层



接口与它的实体均以Code Smith模板生成,效率高。如下所示的供应商接口



 public interface IVendorManager
{
VendorEntity GetVendor(System.String VendorNo);
VendorEntity GetVendor(System.String VendorNo, IPrefetchPath2 prefetchPath);
VendorEntity GetVendor(System.String VendorNo, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList fieldList);

EntityCollection GetVendorCollection(IRelationPredicateBucket filterBucket);
EntityCollection GetVendorCollection(IRelationPredicateBucket filterBucket, ISortExpression sortExpression);
EntityCollection GetVendorCollection(IRelationPredicateBucket filterBucket, ISortExpression sortExpression, IPrefetchPath2 prefetchPath);
EntityCollection GetVendorCollection(IRelationPredicateBucket filterBucket, ISortExpression sortExpression, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList fieldList);

VendorEntity SaveVendor(VendorEntity vendor);
VendorEntity SaveVendor(VendorEntity vendor, EntityCollection entitiesToDelete);
VendorEntity SaveVendor(VendorEntity vendor, EntityCollection entitiesToDelete, string seriesCode);
void SaveCollection(EntityCollection vendors);

void DeleteVendor(VendorEntity vendor);

bool IsVendorExist(System.String VendorNo);
bool IsVendorExist(IRelationPredicateBucket filterBucket);
int GetVendorCount(IRelationPredicateBucket filterBucket);

VendorEntity CloneVendor(System.String VendorNo);
void PostVendor(System.String VendorNo);
void PostVendor(VendorEntity vendor);
void ApprovalItem(EntityCollection vendors);
}


实现接口的Manager类型代码例子如下



 public class VendorManager : Foundation.Common.ManagerBase, IVendorManager
{
public VendorEntity GetVendor(System.String VendorNo)
{
return GetVendor(VendorNo, null);
}

public VendorEntity GetVendor(System.String VendorNo, IPrefetchPath2 prefetchPath)
{
return GetVendor(VendorNo, prefetchPath, null);
}

public VendorEntity GetVendor(System.String VendorNo, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList fieldList)
{
VendorEntity _Vendor = new VendorEntity(VendorNo);
using (DataAccessAdapterBase adapter = GetCompanyDataAccessAdapter())
{
bool found = adapter.FetchEntity(_Vendor, prefetchPath, null, fieldList);
if (!found) throw new Foundation.Common.RecordNotFoundException("Invalid Vendor");
}
return _Vendor;
}


<style type="text/css"><br/>.csharpcode, .csharpcode pre<br/>{<br/>font-size: small;<br/>color: black;<br/>font-family: consolas, "Courier New", courier, monospace;<br/>background-color: #ffffff;<br/>/*white-space: pre;*/<br/>}<br/>.csharpcode pre { margin: 0em; }<br/>.csharpcode .rem { color: #008000; }<br/>.csharpcode .kwrd { color: #0000ff; }<br/>.csharpcode .str { color: #006080; }<br/>.csharpcode .op { color: #0000c0; }<br/>.csharpcode .preproc { color: #cc6633; }<br/>.csharpcode .asp { background-color: #ffff00; }<br/>.csharpcode .html { color: #800000; }<br/>.csharpcode .attr { color: #ff0000; }<br/>.csharpcode .alt <br/>{<br/>background-color: #f4f4f4;<br/>width: 100%;<br/>margin: 0em;<br/>}<br/>.csharpcode .lnum { color: #606060; }</style>



界面层中或是实体层,使用下面的接口来访问接口:



ICompanyManager  _companyManager = ClientProxyFactory.CreateProxyInstance<ICompanyManager>();
CompanyEntity _company = _companyManager.GetCompany(“Kingston”)


如果没有采用分布式技术(.net Remoting,WCF),CreateProxyInstance方法直接返回ICompanyManager接口的实体类型的实例,供接口调用。如果有应用.net Remoting技术,则先以下面的方法产生服务器对象:客户端产生的实体对象会是一个远程代理,指向远程对象:



RemotingConfiguration.RegisterActivatedServiceType(type);



接口与实现分离的好处在这里体现的很明显,简单的切换部署模式(单机,分布式)不需要改变代码。

本文链接

分享到:
评论

相关推荐

    软件 架构 分层体系 结构

    ### 软件架构分层体系结构 #### 一、传统主机系统 (Traditional Host Systems) 在传统的主机系统中,所有处理工作均由一个中心处理器(通常是大型机)完成。本地终端负责用户输入显示功能,但不具备任何智能处理...

    系统架构与分层

    系统架构与分层设计在软件开发中扮演着至关重要的角色,尤其在Java开发环境中。一个良好的架构设计能够确保系统的稳定性、扩展性、柔韧性和有效性。本文主要探讨了系统架构的基本概念、分层设计以及面向服务的架构...

    软件系统架构的方法论

    开发架构则聚焦于软件的实现层面,包括编程语言的选择、第三方库的使用、开发工具和框架的集成等。在这一阶段,开发人员需要考虑如何利用现有的技术和工具来构建系统,同时保持良好的代码组织和开发流程。 运行架构...

    基于模式的分层分布式系统架构的设计研究.pdf

    架构模式定义了软件系统的基本组织结构和总体纲要,设计模式则关注软件子系统的细化,而代码模式则聚焦于具体的实现细节。 在多层分布式系统架构设计中,层次化架构设计模式是一种常见的方法,其特点是系统各组件...

    软件架构师教程,系统架构师讲义

    软件架构是软件开发过程中的关键环节,它定义了系统的整体结构和组织方式,包括主要组件、组件之间的关系以及交互方式。本教程首先会介绍软件架构的基本概念,如模块化、分层架构、微服务架构等,让读者理解架构设计...

    三层架构之学生管理系统_C#管理系统_wilda9b_学生管理_

    三层架构是一种常见的软件设计模式,尤其在开发企业级应用时被广泛应用。在这个“三层架构之学生管理系统”中,我们可以分析出几个关键的知识点。 首先,三层架构是指将应用程序分为表现层(Presentation Layer)、...

    深入.NET平台的软件系统分层开发6

    学习如何使用版本控制工具管理代码变更,协同开发,也是现代软件开发的重要技能。 在Chapter06的文件中,可能会包含与这些知识点相关的课件、代码示例和练习答案,帮助学习者通过实例加深对分层开发的理解和实践。...

    软件架构实践(第三版)林巴斯

    1. **软件架构的重要性**:介绍软件架构在现代软件开发中的地位和作用,强调其对于构建高质量软件系统的必要性。 2. **架构模式与原则**:讨论常见的软件架构模式及其应用,比如分层架构、微服务架构等,并介绍设计...

    软件体系架构中的三层结构

    在软件开发的浩瀚世界里,体系架构设计是决定软件质量和效率的关键因素之一。其中,分层式结构以其清晰的职责划分和易于维护的特点,成为了软件体系架构设计中最常见且重要的结构模式。本文将深入探讨软件体系架构中...

    基于分层结构的智能车系统架构.pdf

    【标题】:基于分层结构的智能...总的来说,基于分层结构的智能车系统架构是当前智能车研究的重要方向,它通过合理地组织硬件和软件资源,增强了系统的灵活性和适应性,为未来智能交通系统的实现提供了有力的技术支持。

    层架构项目学生信息管理系统源代码

    本文将深入探讨.NET三层架构在学生信息管理系统中的具体实现和应用,帮助开发者理解并掌握这种架构的优势与实践。 .NET三层架构是一种常见的软件开发模式,它将应用程序逻辑分为三个独立的层次:表现层...

    autosar架构软件分层架构

    AUTOSAR(汽车开放系统架构)是一个全球性的开发伙伴关系,旨在通过标准化软件架构的设计、开发和集成来降低汽车电子软件系统的复杂性。本文将详细介绍AUTOSAR的分层架构模式、软件功能模块划分、模块介绍以及模块...

    Qt实现组织结构图

    在IT领域,组织结构图是一种常见且重要的可视化工具,它用于表示公司、团队或项目中的层次关系。在本教程中,我们将深入探讨如何使用Qt框架来实现这样的功能。Qt是一个跨平台的应用程序开发框架,广泛应用于桌面、...

    企业级开发与架构

    【企业级开发与架构】是IT领域中一个重要的主题,主要关注如何在大型组织或企业环境中构建、设计和管理复杂的软件系统。企业级开发不仅涉及技术技能,还涉及到软件工程的多个方面,如团队协作、项目管理、系统集成、...

    asp.net 三层架构公共资源管理系统

    总的来说,"asp.net 三层架构公共资源管理系统"是一个综合运用了多种技术的复杂项目,旨在通过规范化的软件设计和强大的技术支撑,为组织提供高效、安全的公共资源管理解决方案。开发者需要对asp.net、C#、三层架构...

    企业级应用软件架构开发过程与实践

    在这一章节,我们首先了解软件架构的概念,它是软件开发的核心,定义了系统的总体结构和组件。讨论了不同的架构风格,如分层架构、微服务架构、事件驱动架构等,以及它们各自的优势和适用场景。此外,还强调了架构...

    visio信息化设计实例软件开发-软件平台物理逻辑分层图.zip

    Visio是一款强大的图表制作工具,常用于绘制各种流程图、网络拓扑图和组织结构图等,对于信息化设计和系统架构的可视化表达非常有用。 首先,让我们深入理解一下"软件平台物理逻辑分层图"。在软件开发中,物理分层...

    C# winfrom 医院管理信息系统+三层架构+注释详细。。。

    医院管理信息系统通常包括患者管理、医生管理、药品管理、预约挂号、收费管理等多个模块,而三层架构则为这些模块提供了良好的组织结构。三层架构主要包括表现层(Presentation Layer)、业务逻辑层(Business Logic...

    三层架构典范项目-图书管理系统(winform应用程序)

    【三层架构典范项目-图书管理系统】是一个基于Winform应用程序的示例,展示了如何在IT行业中构建高效、可维护且分层的软件系统。这个系统利用了三层架构的设计原则,将业务逻辑、数据访问以及用户界面这三个核心部分...

    系统架构师教程.pdf

    系统架构师应精通软件开发生命周期,包括瀑布模型、迭代模型、敏捷开发等不同的开发方法。了解常用的软件工程原则和实践,如模块化、分层架构、面向对象设计、设计模式等,对于制定高质量的系统架构至关重要。此外,...

Global site tag (gtag.js) - Google Analytics