设计模式是面向对象编程中经过验证的最佳实践,用来解决常见的设计问题和重用设计方案。下面是迭代器、命令和外观模式的简要介绍:
1.迭代器模式(Iterator Pattern)
意图: 提供一种统一的方式来顺序访问聚合对象中的元素,而又不需要暴露其底层表示。
应用场景: 当你需要遍历不同的集合结构(比如列表、集合、树等),但又不想暴露它们的具体实现时,就可以使用迭代器模式。这样客户端代码可以通过一致的方式遍历各种类型的集合,而不必了解集合内部的复杂性。
角色:
- Iterator(迭代器):定义访问和遍历元素的接口。
- ConcreteIterator(具体迭代器):实现了Iterator接口,跟踪遍历中的当前位置,知道如何遍历集合并获取下一个元素。
- Aggregate(聚合):定义创建迭代器对象的接口。
- ConcreteAggregate(具体聚合):实现了创建迭代器的行为,提供迭代器所需的内部结构。
示例: 在Java中,java.util.Iterator
接口就是一个典型的迭代器模式实现,我们可以使用iterator()
方法遍历集合类(如ArrayList
、HashSet
等)。
// 接口:迭代器
interface Iterator<T> {
boolean hasNext();
T next();
}
// 具体迭代器:数组迭代器
class ArrayIterator<T> implements Iterator<T> {
private Object[] items;
private int position = 0;
public ArrayIterator(Object[] items) {
this.items = items;
}
@Override
public boolean hasNext() {
return position < items.length && items[position] != null;
}
@Override
@SuppressWarnings("unchecked")
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return (T) items[position++];
}
}
// 聚合接口:集合
interface Collection<T> {
Iterator<T> iterator();
}
// 具体聚合:数组集合
class ArrayList<T> implements Collection<T> {
private Object[] elements;
// ...省略构造方法和其他方法...
@Override
public Iterator<T> iterator() {
return new ArrayIterator<>(elements);
}
}
// 使用示例
ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");
for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
String fruit = it.next();
System.out.println(fruit);
}
2.命令模式(Command Pattern)
意图: 将请求封装为一个对象,从而使用户能够参数化其它对象,同时支持可撤销的操作请求。
应用场景: 当需要将一系列操作请求排队、记录日志、支持取消操作、或者多个请求之间互不影响时,适合使用命令模式。例如GUI应用程序中的菜单操作、历史记录回滚、交易系统等。
角色:
- Command(命令):定义一个执行操作的接口。
- ConcreteCommand(具体命令):实现了Command接口,是“命令”的具体实现,持有接收者并知道如何调用它的方法。
- Invoker(调用者):持有命令对象并对命令对象发出请求执行命令。
- Receiver(接收者):真正执行命令的对象,实现了具体的业务逻辑。
示例: 在Java Swing库中,ActionListener
接口可以看作是一个简化版的命令模式,按钮点击事件可以视为命令,按钮是调用者,而处理事件的方法则是接收者的业务逻辑。
// 抽象命令接口
interface Command {
void execute();
}
// 具体命令:打开灯命令
class TurnOnLightCommand implements Command {
private Light light;
public TurnOnLightCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
}
// 接收者:电灯
class Light {
public void turnOn() {
System.out.println("The light is turned on.");
}
// ...其他方法...
}
// 调用者:遥控器
class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
// 使用示例
Light livingRoomLight = new Light();
Command openLightCmd = new TurnOnLightCommand(livingRoomLight);
RemoteControl remote = new RemoteControl();
remote.setCommand(openLightCmd);
remote.pressButton(); // 输出 "The light is turned on."
3.外观模式(Facade Pattern)
意图: 为子系统中的一组接口提供一个统一的高层接口,从而简化了对该子系统的使用。
应用场景: 当系统过于复杂,子系统之间的依赖关系紧密,或者客户只想使用简单的接口去操作整个系统,而不想深入了解内部复杂的子系统时,可以使用外观模式。
角色:
- Facade(外观):提供一个高层次的接口,对子系统进行组合调用,简化外部调用的复杂性。
- Subsystem Classes(子系统类):内部的复杂子系统,拥有各自的接口和实现。
示例: 假设有一个复杂的音频播放系统,包含音轨加载、混音、音效处理等多个子系统。我们可以创建一个AudioPlayerFacade类,提供一个简单的接口,如playSong(),而在内部这个方法会调用各个子系统的具体方法来完成整个播放流程,无需用户直接操作子系统。
// 子系统类:音响系统中的不同组件
class Amplifier {
public void on() {
System.out.println("Amplifier is on");
}
public void off() {
System.out.println("Amplifier is off");
}
public void setStereoSound() {
System.out.println("Setting stereo sound mode");
}
// ...还有其他方法...
}
class CDPlayer {
public void play() {
System.out.println("CD Player playing...");
}
public void stop() {
System.out.println("CD Player stopped");
}
// ...还有其他方法...
}
// 外观类:简化对外部的接口
class StereoSystemFacade {
private Amplifier amplifier;
private CDPlayer cdPlayer;
public StereoSystemFacade(Amplifier amp, CDPlayer cdPlayer) {
this.amplifier = amp;
this.cdPlayer = cdPlayer;
}
public void turnOn() {
amplifier.on();
cdPlayer.play();
}
public void turnOff() {
amplifier.off();
cdPlayer.stop();
}
// ...还有其他简化的方法...
}
// 使用示例
Amplifier amp = new Amplifier();
CDPlayer player = new CDPlayer();
StereoSystemFacade stereo = new StereoSystemFacade(amp, player);
stereo.turnOn(); // 输出 "Amplifier is on" 和 "CD Player playing..."