Adapter mode coding

现在我们来学习适配器模式,现在我们建一个包,在结构型这个包下,建一个adapter,我们适配器模式呢,

主要是分为,类适配器模式,还有对象适配器模式,那这两个适配器模式,最重要的区别,就是一个通过组合,一个通过继承,

那我们都来演示一下,首先创建一个包,classadapter,类适配器模式,那这里说一下这个角色,第一个是被适配者

这个类图还是很清晰的,首先Adapter它继承了Adaptee被适配者,同时实现了目标接口,那这样其实Target其实是两种实现的,

一种是具体的Target实现类,另外一种通过Adapter,他的实现类就变成了Adaptee的adapteeRequest

package com.learn.design.pattern.structural.adapter.classadapter;

/**
 * 
 * @author Leon.Sun
 *
 */
public class Adaptee {
	/**
	 * 这里面有一个方法
	 * 这个方法是被适配者独有的
	 * 我们起名就叫adapteeRequest
	 * 被适配者的方法
	 * 那下面第二个角色登场
	 * 我们目标要实现成什么样的呢
	 * 
	 * 
	 */
    public void adapteeRequest(){
        System.out.println("被适配者的方法");
    }

}
package com.learn.design.pattern.structural.adapter.classadapter;

/**
 * 对于Target它是一个接口
 * 他可以有很多实现类
 * 现在写一个Target的实现类
 * 具体的Target
 * 
 * 
 * @author Leon.Sun
 *
 */
public interface Target {
	/**
	 * 定义成接口
	 * 看到这两个方法是不一样的
	 * Target里面是request
	 * Adaptee里面是adapteeRequest
	 * 
	 */
    void request();
}
package com.learn.design.pattern.structural.adapter.classadapter;

/**
 * 他实现Target
 * 
 * 
 * @author Leon.Sun
 *
 */
public class ConcreteTarget implements Target {
	/**
	 * concreteTarget目标方法
	 * 那具体的Target也有了
	 * 现在我们就要通过Adaptee适配者适配这个被适配者
	 * 来达到Target这个目标
	 * 我们创建Adapter
	 * 
	 * 
	 */
    @Override
    public void request() {
        System.out.println("concreteTarget目标方法");
    }

}
package com.learn.design.pattern.structural.adapter.classadapter;

/**
 * 由他继承被适配者Adaptee
 * 然后实现Target接口
 * 那我们看一下
 * Adaptee他来实现Target他的接口
 * 并且它是Adaptee的子类
 * 那很简单
 * 我们这里只需要调用父类的adapteeRequest即可
 * 这样我们就通过Adapter把适配者adapteeRequest这个方法呢适配给了Target
 * 因为Adapter是Adaptee的子类
 * 通过调用父类的adapteeRequest方法
 * 来实现了Target
 * 那我们看一下
 * 类图
 * 
 * 这里面强调的是继承
 * 通过继承来获取被适配者的一些方法
 * 我们在实现Target的request方法中
 * 我们可以增加各种逻辑代码
 * 这个还是比较好理解的
 * 那我们现在就换一种模式
 * 使用对象适配器模式
 * 
 * 
 * @author Leon.Sun
 *
 */
public class Adapter extends Adaptee implements Target{
    @Override
    public void request() {
        //...
        super.adapteeRequest();
        //...
    }
}
package com.learn.design.pattern.structural.adapter.classadapter;

/**
 * 
 * @author Leon.Sun
 *
 */
public class Test {
    public static void main(String[] args) {
    	/**
    	 * 我们先写一个具体的Target实现类
    	 * new一个ConcreteTarget这个类
    	 * 这个类在这里就是为了衬托Adapter
    	 * 没有他也是OK的
    	 * 但是ConcreteTarget它是Target的直接实现者
    	 * 现在我们就通过Adapter就把这个实现交给Adaptee
    	 * 
    	 * 
    	 */
        Target target = new ConcreteTarget();
        /**
         * 然后调用target的request方法
         * 这就是一个Target的实现
         * 
         * 上面是具体的目标的方法
         * 也就是Target的具体实现
         * 
         * 
         */
        target.request();

        /**
         * 命名一个adapterTarget
         * 实现就通过Adapter来实现了
         * 因为Adapter实现了Adaptee接口
         * 这个时候调用它的request方法
         * 通过Adapter已经提交给了Adaptee
         * 那这个是类适配器模式
         * 
         * 
         * 
         * 
         */
        Target adapterTarget = new Adapter();
        adapterTarget.request();



    }
}

client的Test就不看了,主要是看这四个类,注意这里是一个组合,第一个Adapter里面有一个Adaptee,他们两都作为

Target的实现类,那在对比一下刚刚的UML,Target还是有两个实现类,只不过Adapter和Adaptee之间,并不是通过组合关系,

而是通过继承关系,那这个就是类适配器模式,和对象适配器模式最终要的区别,那这两个例子讲完了,现在我们再引入一个

生活场景,那我们现在引入一个生活场景,例如我们手机充电,那在中国民用电都是220V的交流电,那我们手机基本上都是

锂电池,然后需要5V的直流电,那我们买手机的时候呢,会带电源适配器,他的作用是把220V的交流电呢转化成5V的直流电,

那如果不转换呢,手机也就坏了,那那我们现在就使用对象适配器模式,来解决这一个生活场景,那为什么使用对象适配器模式呢,

那在继承和组合的时候呢,我们优先选择组合,这个是前面讲原则的时候有讲过的一个原则,当然呢如果没得选,只能通过继承,

那也没有办法,那我们被适配者肯定是220V,AC代表交流电
package com.learn.design.pattern.structural.adapter.objectadapter;

/**
 * 首先还是Target这个接口
 * 这个接口不变
 * 
 * 
 * @author Leon.Sun
 *
 */
public interface Target {
    void request();
}
package com.learn.design.pattern.structural.adapter.objectadapter;

/**
 * 也就是说换模式的时候
 * 从类适配器模式
 * 到对象适配器模式
 * 被适配者和Target
 * 是没有变化的
 * 那具体的原有的Target
 * 实现类也没有变
 * 
 * 
 * @author Leon.Sun
 *
 */
public class Adaptee {
    public void adapteeRequest(){
        System.out.println("被适配者的方法");
    }

}
package com.learn.design.pattern.structural.adapter.objectadapter;


/**
 * 
 * @author Leon.Sun
 *
 */
public class ConcreteTarget implements Target {
    @Override
    public void request() {
        System.out.println("concreteTarget目标方法");
    }

}
package com.learn.design.pattern.structural.adapter.objectadapter;

/**
 * 变化的出现在Adapter上
 * 我们创建一个Adapter
 * 这里让他直接来实现Target
 * 然后实现这个方法
 * 因为没有继承
 * 所以不能调用父类的方法
 * 所以我把Adaptee组合到Adapter这个类里面
 * 然后调用它的adapteeRequest
 * 
 * 通过组合的方式
 * 把具体实现Target的方法
 * 委托给adaptee来实现
 * 同样的我们这里可以加代码
 * 我们在看一下这个类图
 * 
 * 
 * @author Leon.Sun
 *
 */
public class Adapter implements Target{
    private Adaptee adaptee = new Adaptee();

    @Override
    public void request() {
        //...
        adaptee.adapteeRequest();
        //...
    }
}
package com.learn.design.pattern.structural.adapter.objectadapter;

/**
 * 我们在copy代码做版本演进的时候
 * 一定要注意import里面的包名
 * 你们可以直接在源代码上改
 * 我这里是为了演示演进的过程
 * 以及给适配器模式这两种方式
 * 方便你们学习
 * Test的代码是没有任何变化的
 * 变化的只有一个Adapter
 * 
 * 
 * @author Leon.Sun
 *
 */
public class Test {
    public static void main(String[] args) {
        Target target = new ConcreteTarget();
        target.request();

        Target adapterTarget = new Adapter();
        adapterTarget.request();



    }
}
package com.learn.design.pattern.structural.adapter;

/**
 * 
 * @author Leon.Sun
 *
 */
public class AC220 {
	/**
	 * 返回值是int
	 * 输出220V的交流电
	 * 
	 * 
	 * @return
	 */
    public int outputAC220V(){
        int output = 220;
        System.out.println("输出交流电"+output+"V");
        return output;
    }
}
package com.learn.design.pattern.structural.adapter;

/**
 * 他的方法就是输出5V的直流电
 * 那这个就是Target
 * 那现在我们写一个适配者
 * PowerAdapter
 * 电源适配器
 * 
 * 
 * @author Leon.Sun
 *
 */
public interface DC5 {
    int outputDC5V();
}
package com.learn.design.pattern.structural.adapter;

/**
 * 由他来实现5V的直流电
 * 首先在这个适配器的输入呢
 * 现在就通过电源适配器里面还有一个变压器
 * 实现了220V的交流电转化成5V的直流电
 * 那我们测试一下
 * 
 * 
 * @author Leon.Sun
 *
 */
public class PowerAdapter implements DC5{
	/**
	 * 把220V的交流电组合进来
	 * 
	 * 
	 */
    private AC220 ac220 = new AC220();

    /**
     * 实现这个方法
     * 
     * 
     */
    @Override
    public int outputDC5V() {
    	/**
    	 * 赋值220V的交流电
    	 * 输出200V交流电赋值给adapterInput
    	 * 
    	 * 
    	 */
        int adapterInput = ac220.outputAC220V();
        //变压器...
        /**
         * 输出等于什么呢
         * 等于输入进来的220V的交流电除以44
         * 具体交流电和直流电怎么变化的呢
         * 我们就认为这里是一个变压器
         * 也就是说我们适配层的逻辑可以写在这里了
         * 这里就比较简单的
         * 只把数字除以44
         * 变成5
         * 
         * 
         */
        int adapterOutput = adapterInput/44;

        /**
         * 然后输出
         * 使用电源适配器输入AC
         * AC多少呢
         * adapterOutput
         * 单位
         * 加上输出
         * 输出直流电DC
         * adapterOutput
         * 然后加上符号
         * 
         * 
         */
        System.out.println("使用PowerAdapter输入AC:"+adapterInput+"V"+"输出DC:"+adapterOutput+"V");
        /**
         * 这个时候把adapterOutput返回回去
         * 
         * 
         */
        return adapterOutput;
    }
    
}
package com.learn.design.pattern.structural.adapter;

/**
 * 
 * @author Leon.Sun
 *
 */
public class Test {
    public static void main(String[] args) {
    	/**
    	 * 首先目标new一个PowerAdapter
    	 * 
    	 * 
    	 */
        DC5 dc5 = new PowerAdapter();
        /**
         * 然后直接调用电源适配器的outputDC5V
         * 非常简单
         * 通过适配器就是这样简单
         * 结果已经输出了
         * 首先在AC220这个类里面
         * 输出了交流电220V
         * 然后通过PowerAdapter输出
         * 输入是220V的交流电
         * 输出是5V的直流电
         * 和我们预期是一致的
         * 
         * 
         */
        dc5.outputDC5V();

    }
}

 

Guess you like

Origin blog.csdn.net/Leon_Jinhai_Sun/article/details/90789200