在计算机编程中,适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适
配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。
基本信息:
共有两类适配器模式:
(1)对象适配器模式
在这种适配器模式中,适配器容纳一个它包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体。当客户在接口中定义了他期望的行为时,我们就可以应用适配器模式,提供一个实现该接口的类,并且扩展已有的类,通过创建子类来实现适配。
(2)类适配器模式
这种适配器模式下,适配器继承自已实现的类(一般多重继承)。对象适配器”通过组合除了满足“用户期待接口”还降低了代码间的不良耦合。在工作中推荐使用“对象适配”。
使用的前提:
1.接口中规定了所有要实现的方法
2.但一个要实现此接口的具体类,只用到了其中的几个方法,而其它的方法都是没有用的。
下面是适配器模式的结构图:
实现方法:
1.用一个抽象类实现已有的接口,并实现接口中所规定的所有方法,这些方法的实现可以都是“平庸”实现---
-空方法;但此类中的方法是具体的方法,而不是抽象方法,否则的话,在具体的子类中仍要实现所有的方法,
这就失去了适配器本来的作用。
2.原本要实现接口的子类,只实现1中的抽象类即可,并在其内部实现时,只对其感兴趣的方法进行实现。
具体编程代码(下面是两类适配器模式写的代码,更容易领悟):
(1)类适配器:
#include <iostream>
#include <string>
using namespace std ;
//类适配器
class Player //运动员抽象类
{
string strname ;
public:
Player(string name):strname(name){} ; //名字赋值
string Getname(){return strname ;} //获取姓名
virtual void Attack() = 0 ; //进攻纯虚函数
virtual void Defense() = 0 ; //防守传虚函数
};
class Forward_palyer : public Player //前锋类
{
public:
Forward_palyer(string name):Player(name){} ; //名字赋值
void Attack()
{
cout<<"前锋:"<<this->Getname() <<" 开始进攻"<<endl ;
}
void Defense()
{
cout<<"前锋:"<<this->Getname() <<" 开始防守"<<endl ;
}
};
class Guard_palyer : public Player //后卫类
{
public:
Guard_palyer(string name):Player(name){}; //名字赋值
void Attack()
{
cout<<"后卫:"<<this->Getname()<<" 开始进攻"<<endl ;
}
void Defense()
{
cout<<"后卫:"<<this->Getname() <<" 开始防守"<<endl ;
}
};
class ForeignCenter //外籍中锋类
{
string strname ;
public:
void Setname(string name){strname = name ;} //名字赋值
void JingGong()
{
cout<<"外籍中锋: "<<strname<<" 开始进攻"<<endl ;
}
void FangShou()
{
cout<<"外籍中锋:"<<strname<<" 开始防守"<<endl ;
}
};
class Translator : public Player,public ForeignCenter //外籍运动员的翻译类(适配器)
{
public:
Translator(string name):Player(name)
{
this->Setname(name) ;
}
void Attack() //进攻
{
this->JingGong() ;
}
void Defense() //防守
{
this->FangShou() ;
}
};
int main()
{
Player * pForward = new Forward_palyer("麦迪") ;
pForward->Attack() ;
Player * pGuard = new Guard_palyer("巴蒂尔") ;
pGuard->Defense() ;
Player * pTranslator = new Translator("姚明") ;
pTranslator->Attack() ;
pTranslator->Defense() ;
return 0 ;
}
(2)对象适配器:
#include <iostream>
#include <string>
using namespace std ;
class Player //运动员抽象类
{
string strname ;
public:
Player(string name):strname(name){} ; //名字赋值
string Getname(){return strname ;} //获取姓名
virtual void Attack() = 0 ; //进攻纯虚函数
virtual void Defense() = 0 ; //防守传虚函数
};
class Forward_palyer : public Player //前锋类
{
public:
Forward_palyer(string name):Player(name){} ; //名字赋值
void Attack()
{
cout<<"前锋:"<<this->Getname() <<" 开始进攻"<<endl ;
}
void Defense()
{
cout<<"前锋:"<<this->Getname() <<" 开始防守"<<endl ;
}
};
class Guard_palyer : public Player //后卫类
{
public:
Guard_palyer(string name):Player(name){}; //名字赋值
void Attack()
{
cout<<"后卫:"<<this->Getname()<<" 开始进攻"<<endl ;
}
void Defense()
{
cout<<"后卫:"<<this->Getname() <<" 开始防守"<<endl ;
}
};
class ForeignCenter //外籍中锋类
{
string strname ;
public:
void Setname(string name){strname = name ;} //名字赋值
void JingGong()
{
cout<<"外籍中锋: "<<strname<<" 开始进攻"<<endl ;
}
void FangShou()
{
cout<<"外籍中锋:"<<strname<<" 开始防守"<<endl ;
}
};
//对象适配器
class Translator : public Player //外籍运动员的翻译类(适配器)
{
ForeignCenter * pMycenter ;
public:
Translator(string name):Player(name)
{
pMycenter = new ForeignCenter() ;
pMycenter->Setname(name) ;
}
void Attack() //进攻
{
pMycenter->JingGong() ;
}
void Defense() //防守
{
pMycenter->FangShou() ;
}
};
int main()
{
Player * pForward = new Forward_palyer("麦迪") ;
pForward->Attack() ;
Player * pGuard = new Guard_palyer("巴蒂尔") ;
pGuard->Defense() ;
Player * pTranslator = new Translator("姚明") ;
pTranslator->Attack() ;
pTranslator->Defense() ;
return 0 ;
}
两种方法运行后的结果是一致的,如下图: