适配器模式
在现实生活中,经常存在一些不兼容的事物。如某电器的工作电压与家庭交流电电压不一致,网络速度与计算机处理速度不一致,某硬件设备提供的接口与计算机支持的接口不一致等。在这种情况下,我们可以通过一个新的设备使原本不兼容的事物可以一起工作,这个新的设备称为适配器。在软件开发中,也存在一些不一致的情况,同样,也可以通过一种称为适配器模式的设计模式来解决这类问题。
在适配器模式中可以定义一个包装类,包装不兼容接口的对象,这个包装类指的就是适配器(Adapter),它所包装的对象就是适配者(Adaptee),即被适配的类。适配器提供客户类需要的接口,适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用。也就是说,当客户类调用适配器对方法时,在适配器类对内部将调用适配者类对方法,而这个过程对客户类是透明的,客户类并不直接访问适配者类。因此,适配器可以使用由于接口不兼容而不能交互的类可以一起工作,这就是适配器模式的模式动机。
适配器模式定义(Adapter Pattern)定义:将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构性模式。
案例 - 找工作
/**
* 人类
*/
interface PersonalInterface
{
/**
* 是否合适这个工作
* @return boolean true=>适合这个工作 false=>不适合这个工作
*
public function adaptation(Work $work);
}
/**
* 人类实体
*/
abstract class Personal implements PersonalInterface
{
public function __construct(
public string $name,
public int $age
){}
}
/**
* 男人
*/
class ManPersonal extends Personal
{
public function adaptation(Work $work)
{
if($work instanceof MoveBricks)
return true;
return false;
}
}
/**
* 女人
*/
class WomanPersonal extends Personal
{
public function adaptation(Work $work)
{
if($work instanceof Waiter)
return true;
return false;
}
}
设计一个抽象类:工作。作为所有工作的抽象父类
目前提供有搬砖、服务员两个工作
/**
* 工作
*/
interface Work
{
public function getName();
}
/**
* 搬砖
*/
class MoveBricks implements Work
{
public function getName()
{
return "搬砖工作";
}
}
/**
* 服务员
*/
class Waiter implements Work
{
public function getName()
{
return "服务员工作";
}
}
设计一个招聘中心
/**
* 找工作服务
*/
class JobHunting
{
public array $works = [];
public function __construct(Work ...$args)
{
array_push($this->works,...$args);
}
public function jobMatch(PersonalInterface $personal) : Work
{
if(!empty($this->works))
{
foreach($this->works as $work)
{
if($personal->adaptation($work))
return $work;
}
}
throw new Exception("没有匹配的工作",101);
}
}
开始找工作
//初始化找工作服务,将已有的招聘工作注册进去
$jobService = new JobHunting(new MoveBricks(),new Waiter());
//实例化一个人
$man = new ManPersonal('谭勇',27);
//获得工作
$manWork = $jobService->jobMatch($man);
//输出工作名称
echo $manWork->getName(); //搬砖