HeadFrist设计模式学习之适配器模式
2016-05-30 17:36
417 查看
适配器模式定义:
将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。
需求描述:
JVM的公园里有很多动物,在必要时会将动物们放置在BOX里面,所以有很多Box和动物。
现有的是一个可以放置十个鸭子的DuckBox类,其showMsg()方法可以打印每个位置的信息,具体如下:
DuckBox类:
class DuckBox {
private ArrayList<Duck> duck;
private int count;
public DuckBox() {
duck=new ArrayList<Duck>();
count=0;
}
public boolean add(Duck duck)
{
if(!isFull()){
this.duck.add(duck);
count++;
return true;
}
else
return false;
}
public boolean isFull()
{
if(count==10)
return true;
else
return false;
}
public void showMsg()
{
for(Duck d:this.duck)
{
System.out.print("position:"+duck.indexOf(d)+"------MSG:"+ d.getDescription()+"\n");
}
}
}
Duck类:
class Duck {
private String description="this is a duck";
public String getDescription()
{
return description;
}
}
测试代码:
class Run {
public static void main(String[] args) {
// TODO Auto-generated method stub
DuckBox db=new DuckBox();
while(db.add(new Duck()));
db.showMsg();
}
}
结果————————————
position:0------MSG:this is a duck
position:1------MSG:this is a duck
position:2------MSG:this is a duck
position:3------MSG:this is a duck
position:4------MSG:this is a duck
position:5------MSG:this is a duck
position:6------MSG:this is a duck
position:7------MSG:this is a duck
position:8------MSG:this is a duck
position:9------MSG:this is a duck
-----------------------------------
问题:放鸡的Box不够用了,但是放鸭子的Box有剩余,如何做才能使DuckBox类能够同时放置Chicken和Duck呢?
解决方法:
创建一个基类:animal,让Duck和Chicken同时继承animal,将DuckBox中ArrayList<Duck>改为ArrayList<animal>.
这的确是可行的,但是其中存在的问题有两点:
①:DuckBox 可以放置的动物类型好像不止两种,任何实现了animal的类都可以放进来,这样还不如叫Box(失去了设计类本身的意义)。
②:当这种需求变得普遍时(即很多种动物都需要借居在其他相近的动物箱里),整个程序结构变得相当混淆。
这种错误使用多态的方式 使程序变得难以理解(既然名为DuckBox,为什么声明为animal?),我们应该换种思路,使用组合(适配器模式上场了! )。
将一个chicken类与继承Duck类的“包装”,组合起来,这样在DuckBox看起来是个Duck,但是在方法内部调用的都是Chicken的,就像下面这样:
class DuckAdapter extends Duck {
Chicken c;
public DuckAdapter(Chicken c) {
// TODO Auto-generated constructor stub
this.c=c;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return c.getDescription(); //这里调用的是chicken的方法
}
}
测试代码:
class Run {
public static void main(String[] args) {
// TODO Auto-generated method stub
DuckBox db=new DuckBox();
while(db.add(new Duck()))
{
db.add(new DuckAdapter(new Chicken()));
};
db.showMsg();
}
}
结果--------------------------------
position:0------MSG:this is a duck
position:1------MSG:this is a chicken
position:2------MSG:this is a duck
position:3------MSG:this is a chicken
position:4------MSG:this is a duck
position:5------MSG:this is a chicken
position:6------MSG:this is a duck
position:7------MSG:this is a chicken
position:8------MSG:this is a duck
position:9------MSG:this is a chicken
----------------------------------------
好了,这样就得到了比上面更好的解决方案,这种方案的缺点是你几乎要重写所有的方法来达到适配的目的,但是相比程序混淆和难以理解,这是值得的。
将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。
需求描述:
JVM的公园里有很多动物,在必要时会将动物们放置在BOX里面,所以有很多Box和动物。
现有的是一个可以放置十个鸭子的DuckBox类,其showMsg()方法可以打印每个位置的信息,具体如下:
DuckBox类:
class DuckBox {
private ArrayList<Duck> duck;
private int count;
public DuckBox() {
duck=new ArrayList<Duck>();
count=0;
}
public boolean add(Duck duck)
{
if(!isFull()){
this.duck.add(duck);
count++;
return true;
}
else
return false;
}
public boolean isFull()
{
if(count==10)
return true;
else
return false;
}
public void showMsg()
{
for(Duck d:this.duck)
{
System.out.print("position:"+duck.indexOf(d)+"------MSG:"+ d.getDescription()+"\n");
}
}
}
Duck类:
class Duck {
private String description="this is a duck";
public String getDescription()
{
return description;
}
}
测试代码:
class Run {
public static void main(String[] args) {
// TODO Auto-generated method stub
DuckBox db=new DuckBox();
while(db.add(new Duck()));
db.showMsg();
}
}
结果————————————
position:0------MSG:this is a duck
position:1------MSG:this is a duck
position:2------MSG:this is a duck
position:3------MSG:this is a duck
position:4------MSG:this is a duck
position:5------MSG:this is a duck
position:6------MSG:this is a duck
position:7------MSG:this is a duck
position:8------MSG:this is a duck
position:9------MSG:this is a duck
-----------------------------------
问题:放鸡的Box不够用了,但是放鸭子的Box有剩余,如何做才能使DuckBox类能够同时放置Chicken和Duck呢?
解决方法:
创建一个基类:animal,让Duck和Chicken同时继承animal,将DuckBox中ArrayList<Duck>改为ArrayList<animal>.
这的确是可行的,但是其中存在的问题有两点:
①:DuckBox 可以放置的动物类型好像不止两种,任何实现了animal的类都可以放进来,这样还不如叫Box(失去了设计类本身的意义)。
②:当这种需求变得普遍时(即很多种动物都需要借居在其他相近的动物箱里),整个程序结构变得相当混淆。
这种错误使用多态的方式 使程序变得难以理解(既然名为DuckBox,为什么声明为animal?),我们应该换种思路,使用组合(适配器模式上场了! )。
将一个chicken类与继承Duck类的“包装”,组合起来,这样在DuckBox看起来是个Duck,但是在方法内部调用的都是Chicken的,就像下面这样:
class DuckAdapter extends Duck {
Chicken c;
public DuckAdapter(Chicken c) {
// TODO Auto-generated constructor stub
this.c=c;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return c.getDescription(); //这里调用的是chicken的方法
}
}
测试代码:
class Run {
public static void main(String[] args) {
// TODO Auto-generated method stub
DuckBox db=new DuckBox();
while(db.add(new Duck()))
{
db.add(new DuckAdapter(new Chicken()));
};
db.showMsg();
}
}
结果--------------------------------
position:0------MSG:this is a duck
position:1------MSG:this is a chicken
position:2------MSG:this is a duck
position:3------MSG:this is a chicken
position:4------MSG:this is a duck
position:5------MSG:this is a chicken
position:6------MSG:this is a duck
position:7------MSG:this is a chicken
position:8------MSG:this is a duck
position:9------MSG:this is a chicken
----------------------------------------
好了,这样就得到了比上面更好的解决方案,这种方案的缺点是你几乎要重写所有的方法来达到适配的目的,但是相比程序混淆和难以理解,这是值得的。
相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- Ruby设计模式编程之适配器模式实战攻略
- 实例讲解Ruby使用设计模式中的装饰器模式的方法
- 设计模式中的模板方法模式在Ruby中的应用实例两则
- Ruby设计模式编程中对外观模式的应用实例分析
- 实例解析Ruby设计模式编程中Strategy策略模式的使用
- Ruby中使用设计模式中的简单工厂模式和工厂方法模式
- Ruby使用设计模式中的代理模式与装饰模式的代码实例
- 详解组合模式的结构及其在Ruby设计模式编程中的运用
- C#编程中使用设计模式中的原型模式的实例讲解
- 使用设计模式中的工厂方法模式进行C#编程的示例讲解
- 实例解析C#设计模式编程中简单工厂模式的使用
- 详解C#设计模式编程中生成器模式的使用
- 深入解析C#设计模式编程中对建造者模式的运用