简体   繁体   English

策略模式和命令模式的区别

[英]Difference between Strategy pattern and Command pattern

What is the difference between the Strategy pattern and the Command pattern ?策略模式命令模式有什么区别? I am also looking for some examples in Java.我也在寻找一些 Java 示例。

Typically the Command pattern is used to make an object out of what needs to be done -- to take an operation and its arguments and wrap them up in an object to be logged, held for undo, sent to a remote site, etc. There will tend to be a large number of distinct Command objects that pass through a given point in a system over time, and the Command objects will hold varying parameters describing the operation requested.通常,命令模式用于从需要做的事情中创建一个对象——获取操作及其参数并将它们包装在一个对象中以进行记录、保留用于撤消、发送到远程站点等。将往往是大量不同的 Command 对象,它们随着时间的推移通过系统中的给定点,并且 Command 对象将保存描述所请求操作的不同参数。

The Strategy pattern, on the other hand, is used to specify how something should be done, and plugs into a larger object or method to provide a specific algorithm.另一方面,策略模式用于指定应该如何做某事,并插入更大的对象或方法以提供特定算法。 A Strategy for sorting might be a merge sort, might be an insertion sort, or perhaps something more complex like only using merge sort if the list is larger than some minimum size.排序策略可能是合并排序,可能是插入排序,或者可能是更复杂的东西,例如如果列表大于某个最小大小,则仅使用合并排序。 Strategy objects are rarely subjected to the sort of mass shuffling about that Command objects are, instead often being used for configuration or tuning purposes.策略对象很少受到像 Command 对象那样的大规模改组,而是经常用于配置或调整目的。

Both patterns involve factoring the code and possibly parameters for individual operations out of the original class that contained them into another object to provide for independent variability.这两种模式都涉及将单个操作的代码和可能的参数从包含它们的原始类中分解到另一个对象中,以提供独立的可变性。 The differences are in the use cases encountered in practice and the intent behind each pattern.区别在于实践中遇到的用例和每个模式背后的意图。

Words are already given.话已经给了。 Here is the difference in concrete code.这是具体代码的区别。

public class ConcreteStrategy implements BaseStrategy {

    @Override
    public void execute(Object argument) {
        // Work with passed-in argument.
    }

}

public class ConcreteCommand implements BaseCommand {

    private Object argument;

    public ConcreteCommand(Object argument) {
        this.argument = argument;
    }

    @Override
    public void execute() {
        // Work with own state.
    }

}

Strategy - Quicksort or Mergesort [algo change]策略 - Quicksort 或 Mergesort [algo change]

Command - Open or Close [action change]命令 - 打开或关闭 [动作更改]

The main difference is , the command does some action over the object.主要区别在于,该命令对对象执行一些操作。 It may change the state of an object.它可能会改变对象的状态。

While Strategy decides how to process the object.而策略决定如何处理对象。 It encapsulates some business logic.它封装了一些业务逻辑。

Strategy pattern is useful when you have multiple implementations (algorithms) for a given feature and you want to change the algorithm at runtime depending on parameter type.当您对给定功能有多个实现(算法)并且希望在运行时根据参数类型更改算法时,策略模式非常有用。

One good example from HttpServlet code:来自HttpServlet代码的一个很好的例子:

service() method will direct user's request to doGet() or doPost() or some other method depending on method type. service()方法将根据方法类型将用户的请求定向到 doGet() 或 doPost() 或其他一些方法。

protected void service(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException
    {
    String method = req.getMethod();

    if (method.equals(METHOD_GET)) {
        long lastModified = getLastModified(req);
        if (lastModified == -1) {
        // servlet doesn't support if-modified-since, no reason
        // to go through further expensive logic
        doGet(req, resp);
        } else {
        long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
        if (ifModifiedSince < (lastModified / 1000 * 1000)) {
            // If the servlet mod time is later, call doGet()
                    // Round down to the nearest second for a proper compare
                    // A ifModifiedSince of -1 will always be less
            maybeSetLastModified(resp, lastModified);
            doGet(req, resp);
        } else {
            resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        }
        }

    } else if (method.equals(METHOD_HEAD)) {
        long lastModified = getLastModified(req);
        maybeSetLastModified(resp, lastModified);
        doHead(req, resp);

    } else if (method.equals(METHOD_POST)) {
        doPost(req, resp);

    } else if (method.equals(METHOD_PUT)) {
        doPut(req, resp);   

    } else if (method.equals(METHOD_DELETE)) {
        doDelete(req, resp);

    } else if (method.equals(METHOD_OPTIONS)) {
        doOptions(req,resp);

    } else if (method.equals(METHOD_TRACE)) {
        doTrace(req,resp);

    } else {
        //
        // Note that this means NO servlet supports whatever
        // method was requested, anywhere on this server.
        //

        String errMsg = lStrings.getString("http.method_not_implemented");
        Object[] errArgs = new Object[1];
        errArgs[0] = method;
        errMsg = MessageFormat.format(errMsg, errArgs);

        resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
    }
    }

Salient features of Strategy pattern策略模式的显着特征

  1. It's a behavioural pattern这是一种行为模式
  2. It's based on delegation它基于委托
  3. It changes guts of the object by modifying method behaviour它通过修改方法行为来改变对象的内脏
  4. It's used to switch between family of algorithms它用于在算法族之间切换
  5. It changes the behaviour of the object at run time它在运行时改变对象的行为

Command pattern is used to enable loose coupling between Invoker and Receiver.命令模式用于启用 Invoker 和 Receiver 之间的松散耦合。 Command, ConcreteCommand, Receiver, Invoker and Client are major components of this pattern. Command、ConcreteCommand、Receiver、Invoker 和 Client 是此模式的主要组件。

Different Receivers will execute same Command through Invoker & Concrete Command but the implementation of Command will vary in each Receiver.不同的 Receiver 会通过 Invoker 和 Concrete Command 执行相同的 Command,但是每个 Receiver 中 Command 的实现会有所不同。

eg You have to implement "On" and "Off" functionality for TV & DVDPlayer .例如,您必须为TV & DVDPlayer实现“开”和“关”功能。 But TV and DVDPlayer will have different implementation for these commands.但是 TV 和 DVDPlayer 对这些命令会有不同的实现。

Have a look at below posts with code examples :查看以下带有代码示例的帖子:

Real World Example of the Strategy Pattern 策略模式的真实世界示例

Using Command Design pattern 使用命令设计模式

我认为这里的一个很大区别是当您需要在实现相同接口的不同对象之间进行混洗时使用策略模式,而命令模式用于在实现不同接口的某些对象之间进行混洗(因为它将它们封装到称为“命令对象”)并像策略模式一样传递这些命令对象。

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

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