八、结构型模式之适配器、桥接、代理-----《大话设计模式》

一、适配器模式

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

    适用:系统的数据和行为都正确,但接口不相符时;目的是使控制范围之外的一个原有对象与某个接口匹配。适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。

    C#中最重要的适配器:DataAdapter,用于DataSet与数据源之间的适配器以便检索和保存数据。DataAdapter通过映射Fill(更改了DataSet中的数据以便与数据源中的数据相匹配)和Update(更改了数据源中的数据以便与DataSet中的数据相匹配)来提供这一适配器。

image

// Target类,客户所期待的接口或者类
class Target
    {
        public virtual void Request()
        {
            Console.WriteLine("普通请求");
        }
    }

//需要适配的类
    class Adaptee
    {
        public void SpecificRequest()
        {
            Console.WriteLine("特殊请求");
        }
    }

//通过在内部包装一个Adaptee对象,把源接口转换成目标接口
    class Adapter : Target
    {
        private Adaptee adaptee = new Adaptee();

        public override void Request()
        {
            adaptee.SpecificRequest();
        }
    }
static void Main(string[] args)
        {

//调用的是Target的方法,实现的是ADaptee的SpecificRequest()
            Target target = new Adapter();
            target.Request();

            Console.Read();

        }

二、桥接模式

    将抽象部分与它的实现部分分离,使它们都可以独立地变化。比如可以让“手机”既可以按照品牌来分类,也可以按照功能来分类。

    实现系统可能有多角度分类,每一种分类都有可能变化,那么就把这种多角度分离出来让它们独立变化,减少它们之间的耦合。

    目的:解耦,解决由于继承导致结构过于复杂的问题。

image

//第一种抽象分类
class Abstraction
    {
        protected Implementor implementor;

        public void SetImplementor(Implementor implementor)
        {
            this.implementor = implementor;
        }

        public virtual void Operation()
        {
            implementor.Operation();
        }

    }
//实现的还是具体实现类的方法
    class RefinedAbstraction : Abstraction
    {
        public override void Operation()
        {
            implementor.Operation();
        }
    }
//第二种分类
abstract class Implementor
    {
        public abstract void Operation();
    }
//具体类并实现方法
class ConcreteImplementorA : Implementor
    {
        public override void Operation()
        {
            Console.WriteLine("具体实现A的方法执行");
        }
    }

    class ConcreteImplementorB : Implementor
    {
        public override void Operation()
        {
            Console.WriteLine("具体实现B的方法执行");
        }
    }
static void Main(string[] args)
        {
            Abstraction ab = new RefinedAbstraction();
            //不管用哪种分类,最后执行的内容是一样的
            ab.SetImplementor(new ConcreteImplementorA());
            ab.Operation();

            ab.SetImplementor(new ConcreteImplementorB());
            ab.Operation();

            Console.Read();
        }

三、代理模式

    为其他对象提供一种代理以控制对这个对象的访问。

    适用:1.远程代理,也就是为一个对象在不同的地址空间提供局部代表,这样可以隐藏一个对象存在于不同地址空间的事实,例如WebService;

             2.虚拟代理,是根据需要创建开销很大的对象,通过它在存放实例化需要很长时间的真实对象,例如浏览器优化下载的原理;

             3.安全代理,用来控制真实对象访问时的权限。

             4.智能指引,是指当调用真实对象时,代理处理另外一些事,通过代理在访问一个对象时附加一些内务处理。

image

//定义了共同接口,这样就在任何使用RealSubject的地方都可以使用Proxy
abstract class Subject
    {
        public abstract void Request();
    }

//代表真实的实体
    class RealSubject : Subject
    {
        public override void Request()
        {
            Console.WriteLine("真实的请求");
        }
    }

//代理,保存一个引用使得代理可以访问实体,并提供一个与Subject的接口相同的接口,这样代理就可以用来替代实体
    class Proxy : Subject
    {
        RealSubject realSubject;
        public override void Request()
        {
            if (realSubject == null)
            {
                realSubject = new RealSubject();
            }

            realSubject.Request();
        }
    }
static void Main(string[] args)
        {
          //使用的时候使用的是代理,返回的结果是真实的值
           Proxy proxy = new Proxy();
          proxy.Request();

          Console.Read();
        }

四、对比

代理模式

适配器模式

一种原来对象的代表,其他需要与这个对象打交道的操作都是和这个代表交涉 不需要虚构出一个代表者,只需要为应付特定使用目的,将原来的类进行一些组合
原文地址:https://www.cnblogs.com/shanymen/p/4827269.html