适配器模式

阅读更多

本文参考:《修炼Java开发技术:在架构中体验设计模式和算法之美   于广编著》。

 

适配器模式是指将一个接口转换成客户希望的另一个接口,该模式使得原本不兼容的类可以一起工作。

 适配器模式分为如下两类:

1、类的适配器模式。

2、对象的适配器,采用对象组合方式实现。

下面使用例子说明两类:

例如:现在在工作中有一个能说汉语和英语的岗位,而一个面试者只会说汉语,我们的任务就是将这个人适配到这个岗位中。

1、类的适配器模式:

package org.dyb.design.adapter;

public interface Job {
	public void speakChinese();
	public void speakEnglish();
}

 

package org.dyb.design.adapter;

public class Person {

	public void speakChinese(){
		System.out.println("speak chinese");
	}
}

 

package org.dyb.design.adapter;

public class Adapter extends Person implements Job {

	@Override
	public void speakEnglish() {
		System.out.println("speak English");
	}
}

 测试:

package org.dyb.design.adapter;

import org.junit.Test;

public class TestAdapter {
	@Test
	public void test(){
		Job j = new Adapter();
		j.speakChinese();
		j.speakEnglish();
	}
}

结果:

speak chinese
speak English
2、对象的适配器模式

只需要修改adapter适配器实现方法。

package org.dyb.design.adapter;

public class Adapter implements Job {
	private Person person = null;
	public Adapter(Person person){
		this.person = person;
	}
	@Override
	public void speakEnglish() {
		System.out.println("speak English");
	}

	@Override
	public void speakChinese() {
		person.speakChinese();
	}
}

 测试:

package org.dyb.design.adapter;

import org.junit.Test;

public class TestAdapter {
	@Test
	public void test(){
		Person p = new Person();
		Job j = new Adapter(p);
		j.speakChinese();
		j.speakEnglish();
	}
}

 结果:

speak chinese
speak English

 

Java流接口和装饰模式的关系

    Java程序中,inputstream抽象类中有很多子类,FileInputStream、ObjectInputStream、StringBufferInputStream、ByteArrayInputStream、PipedInputStream等是可以被装饰器装饰的对象。

   FilterInputStream相当于装饰模式中的Decorator,而它的子类DataInputStream、BufferedInputStream、LineNumberInputStream、PushbackInputStream就相当于装饰模式中的ConcreteDecorator。

  举例:

对英文进行加密,a->c    y->a     z->b

package decorator.demo;

import java.io.IOException;
import java.io.OutputStream;

public class EncryptOutputStream extends OutputStream {

    private OutputStream os = null;

    public EncryptOutputStream(OutputStream os) {
        this.os = os;
    }

    @Override
    public void write(int a) throws IOException {
        a += 2;
        if (a >= (97 + 26)) {
            a -= 26;
        }
        this.os.write(a);
    }

}

 

package decorator.demo;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import org.junit.Test;

public class TestDecorator {

    @Test
    public void test() throws IOException {
        DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(new EncryptOutputStream(
                new FileOutputStream("mytest.txt"))));
        dout.write("abcdxyz".getBytes());
        dout.close();
    }
}

 打开mytest.txt

cdefzab

 

如果把EncryptOutputStream和bufferedOutputStream位置调换,这样就不行。因为EncryptOutputStream继承的不是装饰类

下面是最合理的解决方案:

让我们的装饰器集成装饰器的父类,就是FilterOutputStream类,然后使用父类提供的功能来协助完成想要装饰的功能。

package decorator.demo;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class EncryptOutputStream2 extends FilterOutputStream {

    public EncryptOutputStream2(OutputStream os) {
        super(os);
    }

    @Override
    public void write(int a) throws IOException {
        a += 2;
        if (a >= (97 + 26)) {
            a -= 26;
        }
        super.write(a);
    }

}

 运行test2

package decorator.demo;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import org.junit.Test;

public class TestDecorator {

    @Test
    public void test() throws IOException {
        DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(new EncryptOutputStream(
                new FileOutputStream("mytest.txt"))));
        dout.write("abcdxyz".getBytes());
        dout.close();
    }
    
    @Test
    public void test2() throws IOException{
        DataOutputStream dout = new DataOutputStream(new EncryptOutputStream2 (new BufferedOutputStream(
                new FileOutputStream("mytest.txt"))));
        dout.write("abcdxyz".getBytes());
        dout.close();
    }
    
}

 结果:cdefzab

你可能感兴趣的:(适配器模式,Java设计模式,设计模式,适配器)