简体   繁体   English

策略模式和适配器的区别

[英]Difference between Strategy Pattern and Adapter

Why is the strategy design pattern and the adapter related to each other?为什么策略设计模式和适配器是相互关联的? It seams to me that the adapter manipulates the result of some method to fullfill the input needs of anotherone.在我看来,适配器操纵某种方法的结果来满足另一个人的输入需求。 Wheras the strategy precibes behaviour.战略先行于行为。

Adapter patterns basically allows classes to work together that on their could not due to incompatible interfaces. 适配器模式基本上允许类在一起工作,因为不兼容的接口。 Adapter converts the interface of one class into something that may be used by another class. 适配器将一个类的接口转换为另一个类可能使用的接口。

Similar to how if you travel abroad you need to carry a power adapter to be able to use the wall sockets. 与您出国旅行的方式类似,您需要携带电源适配器才能使用墙壁插座。

Strategy pattern, on the other hand takes a group of algorithms, and makes them interchangeable (by extending from a common interface). 另一方面,策略模式采用一组算法,并使它们可互换(通过从公共接口扩展)。 So that whatever class that is going to use the strategy can easily interchange it with another strategy from the group. 因此,无论使用该策略的哪个类都可以轻松地将其与该组中的另一个策略互换。

In other words, Adapter does not add behavior in any way, it just modifies the existing interface to allow some other class to access the existing functionality. 换句话说,Adapter不会以任何方式添加行为,它只是修改现有接口以允许其他类访问现有功能。

Strategy pattern on the other hand encapsulates different behavior, and allows them to be switched at run time. 另一方面,策略模式封装了不同的行为,并允许它们在运行时切换。

An example is always good, lets take a look at a use case for an adapter.一个例子总是好的,让我们看一个适配器的用例。 Imagine you have are using some package you cannot modify, it contains the following files:假设您正在使用一些无法修改的 package,它包含以下文件:

class DatabaseManager
{
   private Connection $connection;

   public function connect(Connection $connection)
   {
      $this->connection = $connection->establish();
   }
}

class MysqlConnection implements Connection
{
    public function establish(){
       // connect to mysql...
    }
}

Inside your repo you have the following code:在您的存储库中,您有以下代码:

class YourService
{
   public function connectDB()
   {
      $db = new DatabaseManager();
      $db->connect(new MysqlConnection());
   }
}

It all works fine, however then you get the requirement to change the connection to SqlLiteConnection and add have to import a different package for using it.一切正常,但是您需要更改与 SqlLiteConnection 的连接并添加必须导入不同的 package 才能使用它。 The imported file looks like this:导入的文件如下所示:

class SqlLiteConnection
{
    public function prepareConnection(){
       // first prepare the connection...
       return $preparedConnection;
    }

    public function executeConnection($preparedConnection){
       // then connect ...
       $preparedConnection->execute();
    }
}

The interface (method names) of SqlLiteConnection is different to MysqlConnection, so you are having trouble using it: SqlLiteConnection 的接口(方法名)与 MysqlConnection 不同,所以你在使用时遇到了问题:

class YourService
{
   public function connectDB()
   {
      $db = new DatabaseManager();
      $db->connect(new SqlLiteConnection()); // error! method `establish` does not exist in SqlLiteConnection.
   }
}

You are not able to modify the SqlLiteConnection package, so to get it to work you create an adapter:您无法修改 SqlLiteConnection package,因此要使其正常工作,您需要创建一个适配器:

class SqlLiteAdapter implements Connection
{
   public function establish($sqlConnection)
   {
      $preparedConnection = $sqlConnection->prepareConnection();
      $sqlConnection->executeConnection(preparedConnection);
   }
}

Now it works!现在它起作用了!

class YourService
{
   public function connectDB()
   {
      $db = new DatabaseManager();
      $db->connect(new SqlLiteAdapter(new SqlLiteConnection())); //works!
   }
}

As you can see the adapter was just used as an alias to map establish to the methods prepareConnection and executeConnection .如您所见,适配器只是用作 map establish别名,用于方法prepareConnectionexecuteConnection This is the purpose of an adapter, it does not add functionality but just adapts the interface to your needs.这是适配器的目的,它不会添加功能,而只是根据您的需要adapts接口。 Similar to a travel adapter that allows you to use a US plug in a EU socket.类似于允许您在欧盟插座中使用美国插头的旅行适配器。

The strategy pattern on the other hand would have a similar implementation as above but you would not simply map some functions in the Adapter but would add your unique logic for each of your Strategies.另一方面,策略模式将具有与上述类似的实现,但您不会只是 map 适配器中的某些功能,而是会为每个策略添加您独特的逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM