适配器模式

108 阅读2分钟

将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作。别名为包装器(Wrapper)

适配器模式主要有四种用法,分别为类适配器模式,对象适配器模式,缺省适配器模式,双向适配器模式。

**adapter/**wrapper的都是适配器

适配器属于补救模式,不要在项目的一开始就用 适配器模式是为了解决接口与用户需要的对象类型不一致的问题。这时我们就可以创建一个Adaper的类,用来做桥接。比如有一个ISqlHelper的接口,和几个实现类MySqlHelper、SqlServerHelper等,现在我们项目中要用到Redis,有一个现成的第三方的RedisHelper,但是它和ISqlHelper的接口有些区别,但是我们又不能改这个第三方的RedisHelper,就可以创建一个适配器类来完成适配。一般使用类适配器、对象适配器。类适配器是通过继承的方式实现的,父类有的子类也有,不够灵活。对象适配器只实现接口,不继承类,在适配器类内部创建RedisHelper的对象,调用它的方法。

示例

抽象

public interface IHelper    //访问数据库的接口
{
    void Add<T>();

    void Delete<T>();

    void Update<T>();

    void Query<T>();
}

关系型数据库实现

MySqlHelper

public class MySqlHelper : IHelper
    {
        public MySqlHelper()
        {
            Console.WriteLine($"{GetType().Name} 被构造! ");
        }

        public void Add<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Add ");
        }

        public void Delete<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Delete ");
        }

        public void Query<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Query ");
        }

        public void Update<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Update ");
        }
    }

OracleHelper

public class OracleHelper : IHelper
    {
        public OracleHelper()
        {
            Console.WriteLine($"{GetType().Name} 被构造! ");
        }

        public void Add<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Add ");
        }

        public void Delete<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Delete ");
        }

        public void Query<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Query ");
        }

        public void Update<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Update ");
        }
    }

SqlServerHelper

public class SqlServerHelper : IHelper
    {
        public SqlServerHelper()
        {
            Console.WriteLine($"{GetType().Name} 被构造! ");
        }

        public void Add<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Add ");
        }

        public void Delete<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Delete ");
        }

        public void Query<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Query ");
        }

        public void Update<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Update ");
        }
    }

假设要引入Nosql型数据库redis,通过SDK方法ServiceStack调用,第三方的东西不能改

//这个第三方的,不能改,需要一波转换
public class RedisHelper
    {
        public RedisHelper()
        {
            Console.WriteLine($"{GetType().Name}被构造!");
        }

        public void AddRedis<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Add ");
        }

        public void DeleteRedis<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Delete ");
        }

        public void QueryRedis<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Query ");
        }

        public void UpdateRedis<T>()
        {
            Console.WriteLine($"this is {GetType().Name} Update ");
        }
    }

上端直接调用会报错

IHelper helper = new RedisHelper();

方案一:继承(类适配器)

public class RedisHelperInHreat : RedisHelper,IHelper
    {
        public void Add<T>()
        {
            base.AddRedis<T>();
        }

        public void Delete<T>()
        {
            base.DeleteRedis<T>();
        }

        public void Query<T>()
        {
            base.QueryRedis<T>();
        }

        public void Update<T>()
        {
            base.UpdateRedis<T>();
        }
    }

上端调用

IHelper helper = new RedisHelperInHreat();

方案二:组合(对象适配器)

组合要灵活一点,但是组合的代码要相对复杂一点

1、继承属于强依赖,任何父类的东西,子类必须有,无法抛弃父类的缺陷。继承相当于写死了

public class RedisHelperObject : IHelper
    {
    	//可以是个抽象,通过构造函数传入,为多种类型服务
        public RedisHelper _RedisHelper = new RedisHelper();

        // public RedisHelperObject(RedisHelper _RedisHelper)
        // {
        //     this._RedisHelper = _RedisHelper;
        // }

        public void Add<T>()
        {
            _RedisHelper.AddRedis<T>();
        }

        public void Delete<T>()
        {
            _RedisHelper.DeleteRedis<T>();
        }

        public void Query<T>()
        {
            _RedisHelper.QueryRedis<T>();
        }

        public void Update<T>()
        {
            _RedisHelper.UpdateRedis<T>();
        }
    }

上端调用

IHelper helper = new RedisHelperObject();

核心套路

包一层