概述
模式动机
在软件开发中采用类似于电源适配器的设计和编码技巧被称为适配器模式。
通常情况下,客户端可以通过目标类的接口访问它所提供的服务。有时,现有的类可以满足客户类的功能需要,但是它所提供的接口不一定是客户类所期望的,这可能是因为现有类中方法名与目标类中定义的方法名不一致等原因所导致的。
在这种情况下,现有的接口需要转化为客户类期望的接口,这样保证了对现有类的重用。如果不进行这样的转化,客户类就不能利用现有类所提供的功能,适配器模式可以完成这样的转化。
在适配器模式中可以定义一个包装类,包装不兼容接口的对象,这个包装类指的就是适配器(Adapter),它所包装的对象就是适配者(Adaptee),即被适配的类。
适配器提供客户类需要的接口,适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用。也就是说:当客户类调用适配器的方法时,在适配器类的内部将调用适配者类的方法,而这个过程对客户类是透明的,客户类并不直接访问适配者类。因此,适配器可以使由于接口不兼容而不能交互的类可以一起工作。这就是适配器模式的模式动机。
模式定义
适配器模式(Adapter Pattern) :将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
模式结构
这里我们依据下面这个例子实现一个仿生机器人:
•现需要设计一个可以模拟各种动物行为的机器人,在机器人中定义了一系列方法,如机器人叫喊方法cry()、机器人移动方法move()等。如果希望在不修改已有代码的基础上使得机器人能够像狗一样叫,像狗一样跑,使用适配器模式进行系统设计。
仿生机器人uml图:
实现代码:
1、首先我们已有Robot.java接口和他的一个实现类BioRobot.java
package cn.yqh.adapter;
/**
* 机器人接口:Robot.java提供cry()和move()方法。
* @author 袁
*
*/
public interface Robot {
void cry();
void move();
}
package cn.yqh.adapter;
/**
* 仿生机器人:BioRobot.java。它可以叫和慢慢跑
* 这是原有的代码,我们现在不满于仿生机器人,想结合狗实现类狗机器人
* @author 袁
*
*/
public class BioRobot implements Robot{
public void cry() {
System.out.println("仿生机器人在叫喊......!");
}
public void move() {
System.out.println("仿生机器人在移动......!");
}
}
2、我们现在不满足于上面那个机器人的功能,所以我们想通过下面的狗和机器人结合实现类狗机器人
Dog.java:
package cn.yqh.adapter;
/**
* Dog.java。可以旺旺叫和快快跑。
* @author 袁
*
*/
public class Dog {
public void dogCry(){
System.out.println("狗在汪汪叫......");
}
public void dogMove(){
System.out.println("狗在快快跑......");
}
}
3、故,增加适配器,使实现类狗机器人:
adapter.java:
package cn.yqh.adapter;
/**
* 适配器,这个适配器能够使仿生机器人像狗一样叫,一样跑。
* @author 袁
*
*/
public class Adapter implements Robot{
private Dog dog;
//通过构造方法注入狗
public Adapter(Dog dog) {
super();
this.dog = dog;
}
public void cry() {
System.out.print("机器人模拟狗叫......");
dog.dogCry();
}
public void move() {
System.out.print("机器人模拟狗跑......");
dog.dogMove();
}
}
最后来一个client.java进行一下测试:
package cn.yqh.adapter;
/**
* 客户端运行
* @author 袁
*
*/
public class Client {
public static void main(String[] args) {
//首先我们需要一只狗
Dog dog = new Dog();
//把狗进行包装,以生产类狗机器人
Robot dogRobot = new Adapter(dog);
dogRobot.cry();
dogRobot.move();
}
}
运行结果:
至此,仿生机器人的实现全部完成。
----------------------------------------------------------------------------------------------------------------------------------------------------------------
现在我将Dog.java,进行改进,上面我们用的只是一个具体的Gog类,那现在我们如果想机器人模拟cat或者bird呢?是不是又得新增一个cat.java或者bird.java呢?
这么做当然可以,但是我这里给出另一个设计思路,也就是使用工厂模式来创建一个animal生产工厂,我们直接通过工厂来生产出各种各样的动物,然后通过适配器来进行各种仿生。
改进代码如下:
前面的Robot.java,biorobot.java都不变,下面是新增或者改变的代码:
1、首先,来一个animal.java的接口:
package cn.yqh.factory;
public interface Animal {
void animalCry();
void animalMove();
}
2、接口下面实现各种各样的动物具体类:
package cn.yqh.factory;
public class Bird implements Animal{
public void animalCry() {
System.out.println("鸟在唧唧叫......");
}
public void animalMove() {
System.out.println("鸟在天上飞......");
}
}
package cn.yqh.factory;
public class Cat implements Animal{
public void animalCry() {
System.out.println("猫在喵喵叫......");
}
public void animalMove() {
System.out.println("猫在轻轻跑......");
}
}
package cn.yqh.factory;
/**
* Dog.java。可以旺旺叫和快快跑。
* @author 袁
*
*/
public class Dog implements Animal{
public void animalCry() {
System.out.println("狗在汪汪叫......");
}
public void animalMove() {
System.out.println("狗在快快跑......");
}
}
3、其次我们写一个animalFactory.java的工厂类来生产animal
package cn.yqh.factory;
public class AnimalFactory {
public static Animal getAnimal(String animalName) {
if (animalName.equals("dog")) {
return new Dog();
} else if (animalName.equals("cat")) {
return new Cat();
} else if (animalName.equals("bird")) {
return new Bird();
} else {
return null;
}
}
}
4、最后改进当初的adapter.java代码:
package cn.yqh.adapter;
import cn.yqh.factory.Animal;
/**
* 适配器,这个适配器能够使仿生机器人像狗一样叫,一样跑。
* @author 袁
*
*/
public class Adapter implements Robot{
private Animal animal;
//通过构造方法注入狗
public Adapter(Animal animal) {
super();
this.animal = animal;
}
public void cry() {
System.out.print("机器人模拟叫......");
animal.animalCry();
}
public void move() {
System.out.print("机器人模拟跑......");
animal.animalMove();
}
}
5、写一个client.java来测试我们的适配器和工厂模式是否正常:
package cn.yqh.adapter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import cn.yqh.factory.Animal;
import cn.yqh.factory.AnimalFactory;
/**
* 客户端运行
* @author 袁
*
*/
public class Client {
public static void main(String[] args) throws IOException {
//先根据properties文件获得要模拟的动物
Properties properties = new Properties();
InputStream is = Client.class.getClassLoader().getResourceAsStream("animal.properties");
properties.load(is);
String animalName = properties.getProperty("animalName");
//这里我们从工厂中获得动物
Animal animal = AnimalFactory.getAnimal(animalName);
//把狗进行包装,以生产类狗机器人
Robot dogRobot = new Adapter(animal);
dogRobot.cry();
dogRobot.move();
}
}
animal.properties:增加properties文件已增强代码的 实用性。
#这里放置机器人需要模拟的动物的名字
#猫:cat
#狗:dog
#鸟:bird
animalName=cat
运行结果:
over!!!
完整代码见我的github地址戳这里!
最后
以上就是仁爱诺言为你收集整理的适配器模式的实现模式动机模式定义模式结构这里我们依据下面这个例子实现一个仿生机器人:现在我将Dog.java,进行改进,上面我们用的只是一个具体的Gog类,那现在我们如果想机器人模拟cat或者bird呢?是不是又得新增一个cat.java或者bird.java呢? over!!!的全部内容,希望文章能够帮你解决适配器模式的实现模式动机模式定义模式结构这里我们依据下面这个例子实现一个仿生机器人:现在我将Dog.java,进行改进,上面我们用的只是一个具体的Gog类,那现在我们如果想机器人模拟cat或者bird呢?是不是又得新增一个cat.java或者bird.java呢? over!!!所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复