适配器模式——结构型模式

≯℡__Kan透↙ 提交于 2020-04-06 21:30:45

思路:

一个软件团队开发绘图系统,设计了圆对象(Circle)、矩形对象(Rectangle),线对象(Line)。都支持Draw()函数,即可以通过Draw()函数绘制图形。我们应该如何做呢?

namespace Adapter
{
    class Program
    {
        static void Main(string[] args)
        {
            Circle circle = new Circle();
            Rectangle rect = new Rectangle();
            Line line = new Line();

            test(circle);
            test(rect);
            test(line);

            Console.ReadKey();
        }
        static void test(IDrawPic drawpic)
        {
            drawpic.draw();
        }
    }

    interface IDrawPic
    {
        void draw();
    }

    class Circle : IDrawPic
    {
        public void draw()
        {
            Console.WriteLine("我画了一个圆");
        }
    }

    class Rectangle : IDrawPic
    {
        public void draw()
        {
            Console.WriteLine("我画了一个矩形");
        }
    }

    class Line : IDrawPic
    {
        public void draw()
        {
            Console.WriteLine("我画了一条线");
        }
    }
}

那么现在,为了加快项目进度,将角度对象(Angle)绘制功能交给了合作团队实现。我们又该怎么做呢?重新定义一个Angle类,然后将角度对象绘制函数定为DrawAngle()?这样合理吗?

容易想到的是,绘图系统提供给用户后,用户不满意,希望能统一的调用,不用记太多命令。这里就要用到我们今天要说的适配器模式了。

namespace Adapter
{
    class Program
    {
        static void Main(string[] args)
        {
            Circle circle = new Circle();
            Rectangle rect = new Rectangle();
            Line line = new Line();

            Angle ang = new Angle();
            IDrawPic drawpic = new AdapterAngle(ang);

            test(circle);
            test(rect);
            test(line);

            test(drawpic);

            Console.ReadKey();
        }
        static void test(IDrawPic drawpic)
        {
            drawpic.draw();
        }
    }

    interface IDrawPic
    {
        void draw();
    }

    class AdapterAngle : IDrawPic
    {
        Angle angle;

        public AdapterAngle(Angle angle)
        {
            this.angle =angle;
        }

        public void draw()
        {
            angle.DrawAn();
        }
    }

    class Angle
    {
        public void DrawAn()
        {
            Console.WriteLine("我画了一个角");
        }
    }

    class Circle : IDrawPic
    {
        public void draw()
        {
            Console.WriteLine("我画了一个圆");
        }
    }

    class Rectangle : IDrawPic
    {
        public void draw()
        {
            Console.WriteLine("我画了一个矩形");
        }
    }

    class Line : IDrawPic
    {
        public void draw()
        {
            Console.WriteLine("我画了一条线");
        }
    }
}

适配器模式的优点是,通常来说,客户端通过类的接口访问它提供的服务。有时候现有的类可以提供客户端的功能需要,但是它所提供的接口不一定是客户端所希望的。这就需要一个适配器,将类提供的接口转换成客户端需要的接口。这样保证了对现有类的重用。这就是适配器类。

UML图:

吐槽:

1、适配器模式(Adapter Pattern): 将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。

2、该模式的优点:

    §将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,而无须修改原有代码。

    §增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性。

    §灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。

2、模式使用情景:

    §系统需要使用的类的接口不符合系统的要求。

    §想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。这些源类不一定有很复杂的接口。

    §(对象适配器而言)在设计里,需要改变多个已有子类的接口,如果使用类的适配器模式,就要针对每一个子类做一个适配器,而这不太实际。

本菜鸟的疑难杂症:

1、结构型模式:描述如何将类或者对象结合在一起形成更大的结构。结构模式描述两种不同的东西:类与类的实例(即对象)。 根据这一点,结构模式可以分为类的结构模式和对象的结构模式。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!