接上文,来看抽象工厂模式下的三层架构的代码实现,这里还是以用户模块为例。
//数据访问层接口
public interface IUser<T>
{
//根据参数获取用户列表
IList<T> GetEntitys(T entity);
//登录判断
bool Login(string username,string password);
}
是的,抽象工厂中的每个产品族对应一个产品接口。详见跟着项目学设计模式(四):抽象工厂模式。
类UserDAL和类UserBLL需要实现同一个接口,其中类UserDAL并不需要实现Login方法,但因为接口必须全部实现,因此会保留一个Login空方法,代码如下:
//数据访问层
public UserDAL:IUser<User>
{
public IList<User> GetEntitys(User entity)
{
......
//从数据库返回数据
......
return enititys;
}
public bool Login(string username,string password)
{
throw new NotImplementedException();
}
}
//业务逻辑层
public UserBLL:IUser<User>
{
public IList<User> GetEntitys(User entity)
{
......
调用DAL层的GetEntitys并返回
......
}
//登录判断
public bool Login(string username,string password)
{
var entity=new User{UserName=username,Password=password};
......
调用DAL层的GetEntitys
......
判断是否登录成功,并返回
}
}
现在,我们的需求是类UserDAL和类UserBLL实现同一个接口,其中类UserDAL中是部分实现,而UserBLL中是全部实现,我们的类UserBLL已经全权代理类UserDAL,并可以附加业务逻辑判断。结构型设计模式中的代理模式就是专门用来解决这种问题的。
代理模式
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
组成:
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
同适配器模式,代理模式同样分为类代理和对象代理。
分层的思想否定了层与层之间继承关系,因为当类UserBLL成为类UserDAL的子类时,因为父类的内部细节对子类完全可见,UserBLL中其实就是耦合了DAL层的职责,降低了这个类的内聚性,也失去了分层的意义。
继承被否定了,那只剩下对象组合了。最后的代码如下:
//数据访问层
public UserDAL:IUser
{
public IList<User> GetEntitys(User entity)
{
......
//从数据库返回数据
......
return enititys;
}
public bool Login(string username,string password)
{
throw new NotImplementedException();
}
}
//业务逻辑层
public UserBLL:IUser
{
private IUser dal;
public UserBLL(UserDal _dal)
{
dal = _dal;
}
public IList<User> GetEntitys(User entity)
{
return dal.GetEntitys(entity);
}
//登录判断
public bool Login(string username,string password)
{
var entity=new User{UserName=username,Password=password};
if(dal.GetEntitys(entity).Count == 0)
{
return false;
}
return true;
}
}
这里,我们严格的按照代理模式的定义来做,虽然UserBLL并没有对GetEntitys的业务逻辑,也会代理该方法,而没有选择留空!(假定UI中并不需要GetEntitys这个服务)