为什么策略设计模式和适配器模式相关?在我看来,适配器模式修改了某个方法的结果以满足另一个方法的输入需求。而策略模式则规定了行为方式。
适配器模式基本上允许那些本身由于接口不兼容而无法工作在一起的类协同工作。适配器将一个类的接口转换为另一个类可使用的接口。
就像当你出国旅行时需要携带电源适配器才能使用墙上的插座。
另一方面,策略模式采用一组算法,并使它们可互换(通过扩展公共接口)。因此,无论要使用策略的类是什么,都可以轻松地与该组中的另一个策略交换。
换句话说,适配器不以任何方式添加行为,只是修改现有接口以使其他某个类可以访问现有功能。
另一方面,策略模式封装了不同的行为,并允许在运行时切换它们。
class DatabaseManager
{
private Connection $connection;
public function connect(Connection $connection)
{
$this->connection = $connection->establish();
}
}
class MysqlConnection implements Connection
{
public function establish(){
// connect to mysql...
}
}
在您的代码库中,您有以下代码:
class YourService
{
public function connectDB()
{
$db = new DatabaseManager();
$db->connect(new MysqlConnection());
}
}
一切都运行良好,但是当你需要将连接更改为SqlLiteConnection并添加导入不同包以使用它时,就会出现问题。导入的文件如下:
class SqlLiteConnection
{
public function prepareConnection(){
// first prepare the connection...
return $preparedConnection;
}
public function executeConnection($preparedConnection){
// then connect ...
$preparedConnection->execute();
}
}
SqlLiteConnection的接口(方法名称)与MysqlConnection不同,因此您在使用它时遇到了麻烦:
class YourService
{
public function connectDB()
{
$db = new DatabaseManager();
$db->connect(new SqlLiteConnection()); // error! method `establish` does not exist in SqlLiteConnection.
}
}
你无法修改SqlLiteConnection包,因此为了让它正常工作,你需要创建一个适配器:
class SqlLiteAdapter implements Connection
{
public function establish($sqlConnection)
{
$preparedConnection = $sqlConnection->prepareConnection();
$sqlConnection->executeConnection(preparedConnection);
}
}
class YourService
{
public function connectDB()
{
$db = new DatabaseManager();
$db->connect(new SqlLiteAdapter(new SqlLiteConnection())); //works!
}
}
适配器(Adapter)是指在不修改行为的情况下使用现有函数。策略(Strategy)则根据当前使用的具体类来修改其行为。