Command Design Pattern
After reading command design pattern, I have a question -
Why we are creat开发者_开发技巧ing 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,
- We have less dependency on client.
- 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
}
}
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.
精彩评论