接着上一篇关于分层架构的讨论,
一个分层架构设计的例子(1)

上篇介绍了实体类(Entity)、数据库访问类(DAL)、数据访问接口(IDAL)的相关设计,本篇主要讨论下面几个部分内容:业务逻辑层、缓存机制、界面层等方面。
业务逻辑层,主要是业务逻辑基类的设计,由于数据库访问类(DAL)的基类封装了大量的操作实现,因此,业务逻辑层的主要工作是进一步封装对底层访问接口的实现,如下所示。



public

class
BaseBLL
<
T
>

where
T : BaseEntity,
new
()



{


构造函数





对象添加、修改、删除等接口





返回集合的接口



}


业务层基类封装了大量的调用,那么对于业务层的具体操作类,它的工作就很简单了,基本上只需要继承一下基类就可以了,这就是有一个优秀父亲的好处,呵呵



public

class
Equipment : BaseBLL
<
EquipmentInfo
>




{

public
Equipment() :
base
()



{

}



}


基本上,业务层的设计到此应该收尾了,可是我们注意到,很多开发都使用了缓存的机制来进一步提高程序的性能,下面对这方面进行讨论。缓存的机制,一般是把创建过的对象资源放到一个集合中,需要的时候,调出来,如下业务层的工厂类所示。



public

class
BLLFactory
<
T
>

where
T :
class




{

private

static
Hashtable objCache
=

new
Hashtable();

public

static
T Instance



{

get




{

string
CacheKey
=

typeof
(T).FullName;

T bll

=
(T)objCache[CacheKey];
//
从缓存读取



if
(bll
==

null
)



{

bll

=
Reflect
<
T
>
.Create(
typeof
(T).Name,
"
HuaweiSoftware.IPSPBD.BLL
"
);
//
反射创建,并缓存


}



return
bll;

}



}



}


这是一个业务逻辑类工厂创建类,我们在界面层只需要如下调用即可构造一个(利用了缓存)具体的业务类出来


CustomerInfo info
=
BLLFactory
<
Customer
>
.Instance.FindByID(ID);


在上面的BaseBLL和BLLFactory类中,有一个Reflect的操作类,这是反射缓存的具体实现所在,我们探讨一下它的实现。



public

class
Reflect
<
T
>

where
T :
class




{

private

static
Hashtable m_objCache
=

null
;

public

static
Hashtable ObjCache



{

get




{

if
(m_objCache
==

null
)



{

m_objCache

=

new
Hashtable();

}



return
m_objCache;

}



}




public

static
T Create(
string
sName,
string
sFilePath)



{

return
Create(sName, sFilePath,
true
);

}



public

static
T Create(
string
sName,
string
sFilePath,
bool
bCache)



{

string
CacheKey
=
sFilePath
+

"
.
"

+
sName;

T objType

=

null
;

if
(bCache)



{

objType

=
(T)ObjCache[CacheKey];
//
从缓存读取



if
(
!
ObjCache.ContainsKey(CacheKey))



{

Assembly assObj

=
CreateAssembly(sFilePath);

object
obj
=
assObj.CreateInstance(CacheKey);

objType

=
(T)obj;


ObjCache.Add(CacheKey, objType);

//
写入缓存 将DAL内某个对象装入缓存


}



}



else




{

objType

=
(T)CreateAssembly(sFilePath).CreateInstance(CacheKey);
//
反射创建


}




return
objType;

}




public

static
Assembly CreateAssembly(
string
sFilePath)



{

Assembly assObj

=
(Assembly)ObjCache[sFilePath];

if
(assObj
==

null
)



{

assObj

=
Assembly.Load(sFilePath);

ObjCache.Add(sFilePath, assObj);

//
将整个DLL装入缓存


}



return
assObj;

}



}



另外,如果你在业务层需要实现更加复杂的功能,而数据库访问基类BaseDAL提供的函数不能满足你的需要,可以扩展数据访问层的接口和实现,如下所示。



public

interface
ICustomer : IBaseDAL
<
CustomerInfo
>




{

List

<
string
>
GetAllCustomerNumber();


CustomerInfo GetByCustomerNumber(

string
number);

}





public

class
Customer : BaseDAL
<
CustomerInfo
>
, ICustomer



{


对象实例及构造函数













ICustomer 成员



}



那么在业务层的类修改如下



public

class
Customer : BaseBLL
<
CustomerInfo
>




{

public
Customer() :
base
()



{

}




public
List
<
string
>
GetAllCustomerNumber()



{

ICustomer customerDAL

=
baseDal
as
ICustomer;

return
customerDAL.GetAllCustomerNumber();

}




public
CustomerInfo GetByCustomerNumber(
string
number)



{

ICustomer customerDAL

=
baseDal
as
ICustomer;

return
customerDAL.GetByCustomerNumber(number);

}



}


最后,界面方面的设计是见仁见智,但根本一条是利用一些控件,可以统一风格,减少劳动,给出几个界面的设计截图供大家参考
WinForm方面的(颜色标明的是使用了特定的界面控件,其中红色部分为和整个架构整合起来的分页控件,集成了一些基本的右键菜单操作,包括打印功能、数据导出功能等):
WinForm_UI1.jpg

Winform分页控件设计视图
GridViewPager.jpg

可以选择列进行打印
GridViewPager_PrintOption.jpg

在实际运用过程中的界面效果
GridViewPager_Product.jpg


WebForm方面的(可以使用之前文章介绍的查询控件、分页控件、内容编辑控件):

下图是查询控件和分页控件的一起运用:

WebForm_UI1.jpg

修改内容时候的编辑控件
WebForm_UI2.jpg


查看内容时候的编辑控件
WebForm_UI3.jpg


以上所引用的代码是通过代码生成工具Database2Sharp自动生成(
http://www.iqidi.com/Database2Sharp.htm
),选择EnterpriseLibrary架构即可。
Database2Sharp_Enterprise.jpg

标签: none

添加新评论