策略模式和适配器的区别

问题描述 投票:0回答:3

为什么策略设计模式和适配器相互关联? 在我看来,适配器操纵某种方法的结果来满足另一个方法的输入需求。策略决定行为。

design-patterns adapter strategy-pattern
3个回答
40
投票

适配器模式基本上允许类一起工作,而由于不兼容的接口,它们自己不能一起工作。 Adapter 将一个类的接口转换成另一个类可以使用的东西。

类似于出国旅行需要携带电源适配器才能使用墙上的插座。

另一方面,策略模式采用一组算法,并使它们可以互换(通过从公共接口扩展)。这样,无论哪个班级要使用该策略,都可以轻松地将其与组中的另一个策略互换。

换句话说,Adapter 不会以任何方式添加行为,它只是修改现有接口以允许其他一些类访问现有功能。

另一方面,策略模式封装了不同的行为,并允许它们在运行时切换。


2
投票

一个例子总是好的,让我们看一下适配器的用例。假设您正在使用一些您无法修改的包,它包含以下文件:

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!
   }
}

如您所见,适配器只是用作将

establish
映射到方法
prepareConnection
executeConnection
的别名。这是适配器的目的,它不添加功能,而只是
adapts
您需要的接口。类似于允许您在欧盟插座中使用美国插头的旅行适配器。

另一方面,策略模式将具有与上述类似的实现,但您不会简单地在适配器中映射一些功能,而是会为每个策略添加您独特的逻辑。


0
投票

Adapter 是在不修改行为的情况下使用现有功能。策略根据当时正在使用的具体类修改行为。

© www.soinside.com 2019 - 2024. All rights reserved.