欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

跟着项目学设计模式(七) 适配器模式

程序员文章站 2024-01-21 17:26:52
...

接上文,来看工厂模式下的三层架构的代码实现,这里以用户模块为例。

 //数据访问层接口
    public interface IUserDAL<T>
    {
        //根据参数获取用户列表
        IList<T> GetEntitys(T entity);
    }

    //业务逻辑层接口
    public interface IUserBll<T>
    {

        //登录判断
        bool Login(string username,string password);
    }
 

思路:

数据访问层声明了GetEntitys通用方法,通过传入的实体,检索数据。

业务逻辑层声明了Login方法,传入参数username和password,并调用数据访问层的GetEntitys方法,并通过该方法的返回值判断登录是否成功。

现在,我们的需求是将UserDAL和UserBLL这两个原本由于接口不兼容而不能一起工作的类可以一起工作。结构型设计模式中的适配器模式就是专门用来解决这个问题的。

 

适配器模式

定义:将一个类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

角色:

1)Target(目标抽象类):目标抽象类定义客户所需的接口,可以是一个抽象类或接口。

2)Adapter(适配器类):它可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配。它是适配器模式的核心。

3)Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类包好了客户希望的业务方法。

理解:客户需要Target,现实只有Adaptee,可以用一个实现Target协议的适配器通过类继承或者对象组合类获得被Adaptee。

//类继承实现适配器
class Adapter : Adaptee, Target
{
    public void Request()
    {
        base.SpecificRequest();
    }
}

//对象组合实现适配器
class Adapter : Target
{
    private Adaptee adaptee; //维持一个对适配者对象的引用
    
    public Adapter(Adaptee adaptee)
    {
        this.adaptee = adaptee;
    }
    
    public void Request()
    {
        adaptee.SpecificRequest();//转发调用
    }
}

分层的思想否定了层与层之间继承关系,因为当类UserBLL成为类UserDAL的子类时,因为父类的内部细节对子类完全可见,UserBLL中其实就是耦合了DAL层的职责,降低了这个类的内聚性,也失去了分层的意义。

          继承被否定了,那只剩下对象组合了。最后的代码如下:


    //数据访问层
    public UserDAL:IUserDAL<User>
    {
        public IList<User> GetEntitys(User entity)
        {
            ......
            //从数据库返回数据
            ......
            return enititys;
        }
    }

    //业务逻辑层
    public UserBLL:IUserBll<User>
    {
        private IUserDal dal; 
    
        public UserBLL()
        {
            dal = new UserDAL();
        }

        //登录判断
        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;
        }
    }