命令设计模式

发布于 2024-10-09 18:14:45 字数 3063 浏览 5 评论 0原文

阅读命令设计模式后,我有一个问题 -

为什么我们要在客户端创建具体的命令和接收者对象。这不能在调用者类上初始化吗?

我认为客户端应该创建调用者并将其请求传递给调用者。调用者应该处理所有的事情。

通过这样做,

  1. 我们对客户的依赖减少了。
  2. 类图的设计与实际设计完全不同。

示例 - 客户创建一些买卖股票的订单。然后订单被发送给代理。代理接收订单并将其放入 StockTrade 系统。

这里代理是调用者,股票交易系统是接收者。

根据命令设计模式:

public interface IOrder 
{
public abstract void execute ( );
}

class StockTrade {
    public void buy() {
        System.out.println("You want to buy stocks");
    }
    public void sell() {
        System.out.println("You want to sell stocks ");
    }
}

class Agent {
    public Agent() 
    {
    }

    void placeOrder(IOrder order) {
        order.execute();
    }    
}

//ConcreteCommand Class.
class BuyStockOrder implements Order {
    private StockTrade stock;
    public BuyStockOrder ( StockTrade st) {
        stock = st;
    }
    public void execute( ) {
        stock . buy( );
    }
}

//ConcreteCommand Class.
class SellStockOrder implements IOrder { 
    private StockTrade stock;
    public SellStockOrder ( StockTrade st) {
        stock = st;
    }
    public void execute( ) {
        stock . sell( );
    }
}

// Client
public class Client {
    public static void main(String[] args) {
        StockTrade stock = new StockTrade();
        BuyStockOrder bsc = new BuyStockOrder (stock);
        SellStockOrder ssc = new SellStockOrder (stock);
        Agent agent = new Agent();

        agent.placeOrder(bsc); // Buy Shares
        agent.placeOrder(ssc); // Sell Shares
    }
}

现在该类依赖于接收者、具体命令和代理。

我们不能从客户端移走接收器和具体命令的依赖关系吗?

Agent Class
class Agent {
    public Agent() 
    {
    }

    void BuyStock(BuyStockRequest request) 
    {
        IOrder order = new BuyStockOrder();
    order.execute(request);
    } 

    void SellStock(SellStockRequest request) 
    {
        IOrder order = new SellStockOrder();
    order.execute(request);
    }   
}

//ConcreteCommand Class.
class BuyStockOrder implements IOrder {
    private StockTrade stock;
    public BuyStockOrder () {
        stock = new StockTrade;
    }
    public void execute(BuyStockRequest request) {
        stock.Name = request.Name;
    stock.Price = request.Price;
        stock.buy( );
    }
}

//ConcreteCommand Class.
class SellStockOrder implements IOrder {
    private StockTrade stock;
    public SellStockOrder () {
        stock = new StockTrade;
    }
    public void execute(SellStockRequest request) {
        stock.Name = request.Name;
    stock.Price = request.Price;
        stock.sell( );
    }
}


//Request Class
class BuyStockRequest
{
  public string Name {get; set;}
  public decimal price {get; set;}
}

class SellStockRequest
{
  public string Name {get; set;}
  public decimal price {get; set;}
}

Client
public class Client {
    public static void main(String[] args) {
        BuyStockRequest request = new BuyStockRequest();
        request.Name = "XYZ";
    request.Price = 100;
        Agent agent = new Agent();
        agent.BuyStock(request); // Buy Shares
    }
}

After reading command design pattern, I have a question -

Why we are creating concrete command and receiver object on client. Can't this initializatied on invoker class?

I think client should create invoker and pass it's request to invoker. Invoker should take care of all the stuff.

By doing this,

  1. We have less dependency on client.
  2. The design of class diagram is totally different from actual design.

example - The client creates some orders for buying and selling stocks. Then the orders are sent to the agent.The agent takes the orders and place them to the StockTrade system.

Here agent is invoker and stock trade system is receiver.

as per command design pattern:

public interface IOrder 
{
public abstract void execute ( );
}

class StockTrade {
    public void buy() {
        System.out.println("You want to buy stocks");
    }
    public void sell() {
        System.out.println("You want to sell stocks ");
    }
}

class Agent {
    public Agent() 
    {
    }

    void placeOrder(IOrder order) {
        order.execute();
    }    
}

//ConcreteCommand Class.
class BuyStockOrder implements Order {
    private StockTrade stock;
    public BuyStockOrder ( StockTrade st) {
        stock = st;
    }
    public void execute( ) {
        stock . buy( );
    }
}

//ConcreteCommand Class.
class SellStockOrder implements IOrder { 
    private StockTrade stock;
    public SellStockOrder ( StockTrade st) {
        stock = st;
    }
    public void execute( ) {
        stock . sell( );
    }
}

// Client
public class Client {
    public static void main(String[] args) {
        StockTrade stock = new StockTrade();
        BuyStockOrder bsc = new BuyStockOrder (stock);
        SellStockOrder ssc = new SellStockOrder (stock);
        Agent agent = new Agent();

        agent.placeOrder(bsc); // Buy Shares
        agent.placeOrder(ssc); // Sell Shares
    }
}

Now the class has dependency on receiver, concrete command and agent.

Can't we move the receiver and concrete command dependency from client?

Agent Class
class Agent {
    public Agent() 
    {
    }

    void BuyStock(BuyStockRequest request) 
    {
        IOrder order = new BuyStockOrder();
    order.execute(request);
    } 

    void SellStock(SellStockRequest request) 
    {
        IOrder order = new SellStockOrder();
    order.execute(request);
    }   
}

//ConcreteCommand Class.
class BuyStockOrder implements IOrder {
    private StockTrade stock;
    public BuyStockOrder () {
        stock = new StockTrade;
    }
    public void execute(BuyStockRequest request) {
        stock.Name = request.Name;
    stock.Price = request.Price;
        stock.buy( );
    }
}

//ConcreteCommand Class.
class SellStockOrder implements IOrder {
    private StockTrade stock;
    public SellStockOrder () {
        stock = new StockTrade;
    }
    public void execute(SellStockRequest request) {
        stock.Name = request.Name;
    stock.Price = request.Price;
        stock.sell( );
    }
}


//Request Class
class BuyStockRequest
{
  public string Name {get; set;}
  public decimal price {get; set;}
}

class SellStockRequest
{
  public string Name {get; set;}
  public decimal price {get; set;}
}

Client
public class Client {
    public static void main(String[] args) {
        BuyStockRequest request = new BuyStockRequest();
        request.Name = "XYZ";
    request.Price = 100;
        Agent agent = new Agent();
        agent.BuyStock(request); // Buy Shares
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尬尬 2024-10-16 18:14:45

它实际上归结为您有多少命令以及您想要从调用者公开多少接口。如果您最终为每个命令公开一个接口,那么为什么要首先创建命令对象呢?命令模式的整个思想是将调用者逻辑与命令数量解耦,当您增加命令数量时,代理类不应进行任何更改。

It actually boils down to how many commands you have and how many interface you want to expose from invoker. If you end up exposing one interface for each command then why bother creating command objects in first place. The whole Idea of command pattern is to decouple invoker logic from number of commands as you increase number of commands your Agent class should not under go any change.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文