Command Pattern与Simple Factory的核心差异及相关疑问解答
Great question—this is such a common sticking point when you’re learning design patterns, especially since both involve wrapping logic in abstractions that can look similar at first glance. Let’s break this down clearly, starting with their core purposes, then address your specific questions.
First: What Each Pattern Actually Does
Simple Factory: It’s All About Object Creation
The Simple Factory pattern is a creational pattern—its entire job is to handle the messy details of creating objects, so your client code doesn’t have to. Think of it as a specialized "object builder" that hides new calls and conditional logic for creating different concrete classes.
For example, if you have a bunch of Pizza subclasses (CheesePizza, PepperoniPizza), the factory takes care of deciding which one to instantiate based on input. Once it hands you the object, the factory steps back—you, the client, directly use the object’s methods.
// Simple Factory example class PizzaFactory { public Pizza createPizza(String type) { return switch(type) { case "cheese" -> new CheesePizza(); case "pepperoni" -> new PepperoniPizza(); default -> throw new IllegalArgumentException("Unknown pizza type"); }; } } // Client code var factory = new PizzaFactory(); var pizza = factory.createPizza("cheese"); pizza.bake(); // Client interacts directly with the pizza
Command Pattern: It’s All About Encapsulating Behavior
The Command pattern is a behavioral pattern—its goal is to wrap an entire request or action into an object. This lets you treat actions like data: you can pass them around, queue them up, undo them, log them, or parameterize different actions without changing the code that triggers them.
A Command object doesn’t just create something—it defines a complete unit of work. For example, a MakeCheesePizzaCommand might create a pizza and bake it and box it all in its execute() method. And crucially, you can store these commands, reuse them, or even reverse them (if you add an undo() method).
// Command Pattern example (even with object creation) interface Command { void execute(); } class MakeCheesePizzaCommand implements Command { @Override public void execute() { var pizza = new CheesePizza(); // Creation is part of the command pizza.bake(); pizza.box(); System.out.println("Cheese pizza ready!"); } } // Client code (e.g., a pizza order queue) class PizzaOrderQueue { private final Queue<Command> orders = new LinkedList<>(); public void addOrder(Command order) { orders.add(order); } public void processOrders() { while (!orders.isEmpty()) { orders.poll().execute(); // Execute the entire action } } }
Answering Your Specific Questions
1. Is the only difference that Factory handles creation, Command handles behavior?
Not exactly—though that’s a good starting point. The bigger distinction is their intent:
- Simple Factory exists to decouple object creation from object usage. It eliminates
newcalls and conditional logic from client code, making it easier to add new types later. - Command Pattern exists to turn actions into objects, enabling flexible behavior management. Creation might be part of that action, but it’s never the end goal.
2. If a Command involves object creation, are they equivalent?
Absolutely not. Let’s use the examples above:
- The
PizzaFactoryonly gives you aPizza—you have to handle baking, boxing, etc., yourself. It can’t be stored or queued as an action. - The
MakeCheesePizzaCommandencapsulates the entire workflow of making a pizza. You can add it to a queue, process it later, or even undo it (if you added anundo()method that throws away the unbaked pizza). The creation is just one step in a larger, manageable action.
Another way to think about it: If you only need to create objects, use a Factory. If you need to treat actions as reusable, manipulable entities, use Command.
内容的提问来源于stack exchange,提问作者the_only_sa

