C#设计模式06——适配器的写法

什么是适配器模式?

适配器模式是一种结构型设计模式,用于将现有接口转换为符合客户端期望的接口。适配器模式允许不兼容的类可以相互协作。

为什么需要适配器模式?

在实际开发中,经常会遇到需要复用一些已有的类,但是这些类的接口和我们当前需要的接口不匹配的情况。而适配器模式就可以让这些不兼容的类之间可以协作,方便地进行复用。

适配器模式有哪些角色?

1. 目标接口(Target):期望得到的接口,客户端调用的接口。
2. 原始类(Adaptee):现有的需要进行适配的接口。
3. 适配器(Adapter):将原始类的接口转换成了目标接口的类。

适配器模式的基本流程是什么?

1. 客户端通过调用 Target 接口中的方法,请求完成某个功能。
2. 适配器内部包装了一个 Adaptee 实例,并实现了 Target 接口。
3. 客户端调用适配器的方法,适配器实际上会调用 Adaptee 实例的方法。
4. 适配器将结果转换为目标接口对应的格式,返回给客户端。

适配器模式的优点是什么?

1. 提高代码的复用性,将原有的类适配到新的接口上之后可以在新的系统中重复使用。
2. 降低了类之间的耦合度,使用适配器模式可以让原有的类和新的系统之间解耦。
3. 提高了系统的灵活性和可扩展性,将来如果需要增加其他的接口类型,只需要增加相应的适配器即可。

适配器模式的缺点是什么?

1. 适配器模式增加了系统的复杂性,需要增加额外的适配器类来完成接口转换工作。
2. 适配器模式可能会造成一定的性能损失,因为需要增加额外的适配器层来完成数据转换。

适配器模式有哪些应用场景?

1. 系统需要使用现有的类,而这些类的接口不符合系统的需要。
2. 统一输入/输出接口,如日志记录、数据统计等。
3. 兼容性问题,如不同操作系统、不同数据库之间的数据交换。

总结一下适配器模式五个W和一个H:

- What:适配器模式,一种结构型设计模式,将不兼容的接口转换为符合客户端期望的接口。
- Why:用于复用现有的类,并让不兼容的接口之间可以进行协作。
- Who:目标接口、原始类、适配器。
- When:需要将一些不兼容的类适配到新的接口上,从而让它们可以在新系统中被重复使用。
- Where:适配器模式常用于统一输入/输出接口、解决兼容性问题等场景。
- How:客户端通过调用适配器的方法,适配器实际上会调用原始类的方法,并将结果转换为目标接口对应的格式后返回给客户端。

目标角色

    public interface IHelper
    {
        void Add<T>();
        void Delete<T>();
        void Update<T>();
        void Query<T>();
    }

被适配器角色

sqlserver、mysql、redis

 

 适配器角色

SqlServerHelper
    public class SqlServerHelper : IHelper
    {
        public void Add<T>()
        {
            Console.WriteLine("This is {0} Add", this.GetType().Name);
        }
        public void Delete<T>()
        {
            Console.WriteLine("This is {0} Delete", this.GetType().Name);
        }
        public void Update<T>()
        {
            Console.WriteLine("This is {0} Update", this.GetType().Name);
        }
        public void Query<T>()
        {
            Console.WriteLine("This is {0} Query", this.GetType().Name);
        }
    }
MysqlHelper
    public class MysqlHelper : IHelper
    {
        public void Add<T>()
        {
            Console.WriteLine("This is {0} Add", this.GetType().Name);
        }
        public void Delete<T>()
        {
            Console.WriteLine("This is {0} Delete", this.GetType().Name);
        }
        public void Update<T>()
        {
            Console.WriteLine("This is {0} Update", this.GetType().Name);
        }
        public void Query<T>()
        {
            Console.WriteLine("This is {0} Query", this.GetType().Name);
        }
    }

对于一些第三方的组件方法,它里面已有类似的方法,这个时候我们可以采取 继承或 组合的方式,来做适配

    /// <summary>
    /// 第三方提供的  openstack  servicestack
    /// 不能修改
    /// </summary>
    public class RedisHelper
    {
        public RedisHelper()
        {
            Console.WriteLine($"构造RedisHelper");
        }
        public void AddRedis<T>()
        {
            Console.WriteLine("This is {0} Add", this.GetType().Name);
        }
        public void DeleteRedis<T>()
        {
            Console.WriteLine("This is {0} Delete", this.GetType().Name);
        }
        public void UpdateRedis<T>()
        {
            Console.WriteLine("This is {0} Update", this.GetType().Name);
        }
        public void QueryRedis<T>()
        {
            Console.WriteLine("This is {0} Query", this.GetType().Name);
        }
    }

类适配器,通过继承的方式,在它上面实现目标IHelper

    /// <summary>
    /// 类适配器
    /// </summary>
    public class RedisHelperInherit : RedisHelper, IHelper
    {
        public RedisHelperInherit()
        {
            Console.WriteLine($"构造{this.GetType().Name}");
        }

        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

    public class RedisHelperObject : IHelper
    {
        public RedisHelperObject()
        {
            Console.WriteLine($"构造{this.GetType().Name}");
        }
        //属性注入 声明写死
        private RedisHelper _RedisHelper = new RedisHelper();

        ////构造函数 可以替换(需要抽象) 
        public RedisHelperObject(RedisHelper redisHelper)
        {
            this._RedisHelper = redisHelper;
        }

        ////方法注入 可以替换(需要抽象)
        public void SetObject(RedisHelper redisHelper)
        {
            this._RedisHelper = redisHelper;
        }

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

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

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

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

运行测试

            {
                //继承 既满足现有的规范调用,又没有修改RedisHelper  
                //类适配器模式
                IHelper helper = new RedisHelperInherit();
                helper.Add<Program>();
                helper.Delete<Program>();
                helper.Update<Program>();
                helper.Query<Program>();
            }
            {
                //组合 既满足现有的规范调用,又没有修改RedisHelper 
                //对象适配器
                IHelper helper = new RedisHelperObject();
                helper.Add<Program>();
                helper.Delete<Program>();
                helper.Update<Program>();
                helper.Query<Program>();
            }

 源码下载:https://gitee.com/weilong2020/csharp_23_-design-patterns.git 

posted @ 2021-02-08 20:18  明志德道  阅读(204)  评论(0编辑  收藏  举报