最近,我已经熟悉了命令模式的实现。我遇到了一个问题,我需要为用户选择执行哪种方法来执行输入方法名称或编号,这与这个具体的方法执行有关。如果我不需要为每个方法创建单独的类,一切都会好的,如下所述:
public interface Order {
void execute ();
}
// Receiver class.
class StockTrade {
public void buy() {
System.out.println("You want to buy stocks");
}
public void sell() {
System.out.println("You want to sell stocks ");
}
}
// Invoker.
class Agent {
void placeOrder(Order 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 Order {
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 buyStockOrder = new BuyStockOrder(stock);
SellStockOrder sellStockOrder = new SellStockOrder(stock);
Agent agent = new Agent();
agent.placeOrder(buyStockOrder ); // Buy Shares
agent.placeOrder(sellStockOrder ); // Sell Shares
}
}如何避免为每个方法创建过多的类,这些方法也将是正确和灵活的?
发布于 2014-05-30 18:51:47
我可能无法回顾您具体要求的要点,但我将进行一般性回顾:
public和abstract关键字,它是隐式的。public abstract void execute ( );,而应该是void execute();,程序中的某些字符串也可能有固定的间距。m_启动实例变量,也许这是另一种背景下的常见实践,但在Java中并非如此。不过,您似乎在其他地方坚持使用camelCasing。final。如果不小心更改原语或对对象的引用,则会产生编译器错误。Agent中您将m_ordersQueue指定为new ArrayList(),您希望使用泛型。如果可以存储所有类型的对象,则使用new ArrayList<Object>()。我看到您忘记声明变量的类型,使用Java7‘S钻石操作符,它将是private final List<Object> ordersQueue = new ArrayList<>();,还注意到我只将List<Object>定义为类型,因为如果可能的话,您总是希望使用接口来声明类型。bsc和ssc不是描述性的。Queue<Object>中的ordersQueue使用Agent,这个名称意味着您想要一个队列实现,但是您使用的是list实现。好消息是,您似乎正确地遵循了一些范例,并且相当合理地理解了OOP,但是您确实需要在某些方面进行改进。
发布于 2014-05-30 19:01:20
我会继续到@skiwi停下来的地方。关于你的具体问题,有几种选择。
但是@skiwi没有提到的一点是,您应该用@Override标记所有可能的方法
一种方法是使用布尔值,但由于很容易混淆真假,所以我认为枚举更好:
public enum BuyOrSell { BUY, SELL; }
class BuyOrSellStockOrder implements Order {
private final StockTrade stock;
public BuyOrSellStockOrder(StockTrade st, BuyOrSell action) {
this.stock = st;
this.action = action;
}
@Override
public void execute() {
if (action == BUY)
stock.buy();
if (action == SELL)
stock.sell();
}
}但是,考虑到买卖之间的巨大差异,我认为您应该考虑为此设置两个不同的命令类。而且,如果您开始将不同的命令组合到同一个类中,它将变得非常混乱。
如果您使用的是Java 8,您可以使用如下命令:
class MyCommand implements Order {
private final Runnable action;
public MyCommand(Runnable action) {
this.action = action;
}
@Override
public void execute() {
action.run();
}
}然后您可以创建这样的命令:
MyCommand bsc = new MyCommand(stock::buy);
MyCommand ssc = new MyCommand(stock::sell);但是,虽然Java 8很漂亮,很不错,但我不确定是否推荐使用这样的命令模式。我认为通过使用方法引用,命令模式失去了一点意义。
https://codereview.stackexchange.com/questions/52110
复制相似问题