C#设计模式之适配器模式

适配器模式

文章目录

  • 适配器模式
    • 模式分类
    • 模式产生原因
    • 模式灵感来源
    • 模式类图
    • 经典代码实现
    • 适配器模式优化
      • 缺省适配器:
      • 双向适配器:
    • 适配器模式总结
      • 适配器模式的优点:
      • 适配器模式的缺点:

本片博客将介绍适配器模式,适配器模式是一种使用频率非常高的结构型设计模式,当我们的系统中存在不兼容的接口时,我们就可以引入一个适配器模式来使原本因为接口不兼容而不能一起工作的两个类可以在一起协同工作了。

模式分类

结构型设计模式。结构型设计模式关注如何将现有的类或者对象组织在一起形成更加强大的结构。

模式产生原因

在实际的软件开发中,系统可能需要使用一些现有的类,而这些类的接口不符合系统需求,甚至没有这些类的源码。当我们遇到这种困难时我们就需要一个在中间可以调解两边的类,让原本因为接口不兼容而不能一起工作的两个类可以在一起协同工作,这就是适配器模式的目的。

模式灵感来源

众所周知,我们国家的生活用电电压为220V,但是我们日常使用的电脑,手机等电子产品其实际工作电压并没有这么高,为了使电脑和手机也可以使用220V的生活用电,我们需要一个电源的适配器,也就是我们平时说的充电器或者变压器,有了电源适配器之后,生活用电的220V就可以与我们的手机和电脑相兼容了,这里的电源适配器就是一个适配器的角色,生活用电和手机用电就是两个不兼容的接口。

模式类图

适配器模式分为类适配器和对象适配器:
类适配器:
C#设计模式之适配器模式_第1张图片

对象适配器:
C#设计模式之适配器模式_第2张图片

适配器模式主要有3个对象组成:

Target(目标抽象类):

目标抽象类定义客户所需要的接口,可以是一个抽象类或接口也可以是一个具体类,在类适配器中由于C#只支持单继承,所以目标抽象类只能是接口。

Adapter(适配器类):

它可以调用另一个接口,作为一个转换器对Adaptee和Target进行适配。适配器Adapter是适配器模式的核心类,在类适配器中,它通过实现Target接口并继承Adaptee来使得二者产生关系,在对象适配器中,它通过继承或实现Target接口并关联Adaptee来使得二者产生关系。

Adaptee(适配者类):

适配者类就是需要被适配的对象,它定义了一个已经存在的接口且需要适配,一般就是一个具体类,其中包含了客户端想要调用的业务方法。

经典代码实现

类适配器实现:

Target:

namespace Adapter.Adapter.Example.ClassAdapter
{
    public interface ITarget
    {
        void Operation();
    }
}

Adapter:

namespace Adapter.Adapter.Example.ClassAdapter
{
    public class ClassAdapter : ClassAdaptee,ITarget
    {
        public void OperationAdapter()
        {
            base.Operation();
        }
    }
}

Adaptee:

namespace Adapter.Adapter.Example.ClassAdapter
{
    public class ClassAdaptee
    {
        public void Operation()
        {
            
        }
    }
}

对象适配器实现:

Target:

namespace Adapter.Adapter.Example.ClassAdapter
{
    public interface ITarget
    {
        void Operation();
    }
}

Adapter:

namespace Adapter.Adapter.Example.ClassAdapter
{
    public class Adapter : ITarget
    {
        private Adaptee _adaptee;

        public void SetAdaptee(Adaptee adaptee)
        {
            _adaptee = adaptee;
        }

        public void Operation()
        {
            _adaptee.Operation();
            
        }
    }
}

Adaptee:

namespace Adapter.Adapter.Example.ClassAdapter
{
    public class Adaptee
    {
        public void Operation()
        {
            
        }
    }
}

适配器模式优化

缺省适配器:

缺省适配器的意思是有些时候我们可能并不需要使用目标接口中的所有方法,这时我们就需要封装一层抽象适配器来实现空方法,之后由抽象适配器的子类决定覆盖那个方法进行使用。

Target:

namespace Adapter.Adapter.Example.DefaultAdapter
{
    public interface ITarget
    {
        void Operation1();
        void Operation2();
        void Operation3();
    }
}

AbstractAdapter:

namespace Adapter.Adapter.Example.DefaultAdapter
{
    public abstract class AbstractAdapter : ITarget
    {
        public void Operation1()
        {
            
        }

        public void Operation2()
        {
            
        }

        public void Operation3()
        {
            
        }
    }
}

ConcreteAdapter:

namespace Adapter.Adapter.Example.DefaultAdapter
{
    public class ConcreteAdapter : AbstractAdapter
    {
        private Adaptee _adaptee;

        public void SetAdaptee(Adaptee adaptee)
        {
            _adaptee = adaptee;
        }
        public new void Operation1()
        {
            _adaptee.Operation1();
        }
    }
}

Adaptee:

namespace Adapter.Adapter.Example.DefaultAdapter
{
    public class Adaptee
    {
        public void Operation1()
        {
            
        }
    }
}

双向适配器:

双向适配器的和核心在于之前的目标抽象类和适配者类,在这里同时是目标抽象类和适配者类。

Target:

namespace Adapter.Adapter.Example.DoubleAdapter
{
    public interface ITarget
    {
        void TargetOperation();
    }
}

ConcreteTarget:

namespace Adapter.Adapter.Example.DoubleAdapter
{
    public class ConcreteTarget : ITarget
    {
        public void TargetOperation()
        {
            
        }
    }
}

Adapter:

namespace Adapter.Adapter.Example.DoubleAdapter
{
    public class Adapter : ITarget, IAdaptee
    {
        private ITarget _target;
        private IAdaptee _adaptee;

        public void SetTarget(ITarget target)
        {
            _target = target;
        }

        public void SetAdaptee(IAdaptee adaptee)
        {
            _adaptee = adaptee;
        }
        public void TargetOperation()
        {
            _target.TargetOperation();
        }

        public void AdapteeOperation()
        {
            _adaptee.AdapteeOperation();
        }
    }
}

Adaptee:

namespace Adapter.Adapter.Example.DoubleAdapter
{
    public interface IAdaptee
    {
        void AdapteeOperation();
    }
}

ConcreteAdaptee:

namespace Adapter.Adapter.Example.DoubleAdapter
{
    public class ConcreteAdaptee : IAdaptee
    {
        public void AdapteeOperation()
        {
            
        }
    }
}

适配器模式总结

适配器模式的优点:

  1. 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无需修改原有结构。
  2. 增加类的透明性和复用性,将具体的业务实现过程封装在适配者类中,对于客户端来说是透明的,一个适配者可以在多个系统中使用,提高了复用性。

适配器模式的缺点:

  1. 对于类适配器来说,像C#,JAVA这种只支持单继承的语言,一次只能有一个适配者类,不可能同时适配多个适配者。
  2. 对于类适配器来说,适配者不可为最终类,C#中不可以为sealed类。
  3. 对于类适配器来说,在C#,JAVA中由于只支持单继承,所以目标抽象类必须为接口。
  4. 对于对象适配器模式,与类适配模式相比,要在适配器中置换适配者类的某些方法比较麻烦。

你可能感兴趣的:(设计模式,设计模式,c#)