上一篇地址:整理好了!2024年最常见 20 道设计模式面试题(四)-CSDN博客
九、什么是命令模式?它如何帮助实现解耦?
命令模式(Command Pattern)是一种行为设计模式,它将一个请求或操作封装为一个对象。这种模式的主要目的是将发起请求的对象与执行请求的对象解耦,从而让不同的请求、队列或者日志请求以及操作的撤销等操作能够统一处理。
命令模式的组成部分:
- 命令接口(Command Interface):定义了执行命令的方法,所有命令类都必须实现这个接口。
- 具体命令(Concrete Command):实现命令接口,对应具体的操作。
- 调用者(Invoker):要求命令对象执行请求。
- 接收者(Receiver):知道如何实施与执行一个请求相关的操作。
- 客户端(Client):创建具体命令对象,并且设置它的接收者。
命令模式如何帮助实现解耦:
-
请求者与执行者的解耦:命令模式通过将请求封装为对象,使得请求者和执行者之间没有直接的联系。请求者只需要知道命令接口,而不需要了解具体的命令实现。
-
扩展性:当需要添加新的命令时,只需增加一个新的具体命令类,而不需要修改现有的代码。这符合开闭原则(对扩展开放,对修改封闭)。
-
参数化方法调用:命令模式允许将方法调用的参数进行参数化,这使得可以在不同的时间、不同的环境中执行相同的请求。
-
支持撤销操作:通过维护命令的历史记录,可以实现撤销功能。每个命令对象都可以存储足够的状态信息,以便可以恢复到之前的状态。
-
支持日志记录:命令对象可以很容易地被记录到日志中,因为它们是对象,可以被序列化和存储。
-
支持事务:如果需要,可以设计命令对象来支持事务性操作,确保操作的原子性。
应用场景:
- 需要对操作进行排队、记录、撤销或重做的场景,如文本编辑器。
- 需要支持事务性操作的场景。
- 需要将操作和调用操作的对象解耦的场景。
示例:
假设有一个简单的文本编辑器,它支持撤销和重做操作。使用命令模式,我们可以定义一个命令接口,比如 EditCommand
,然后为每个编辑操作(如插入文本、删除文本)创建具体命令类,如 InsertCommand
和 DeleteCommand
。编辑器作为调用者,根据用户的操作来创建相应的命令对象,并执行它们。同时,编辑器可以维护一个命令历史记录,以便实现撤销和重做功能。
通过这种方式,命令模式提供了一种灵活、可扩展的方式来处理请求和操作,同时保持了系统的解耦和模块化。
十、迭代器模式是如何遍历一个集合的元素的?
迭代器模式(Iterator Pattern)是一种行为设计模式,它允许在不暴露其底层表示的情况下,顺序访问一个聚合对象中的各个元素。迭代器模式定义了一种方法来顺序访问一个聚合对象中的所有元素,而不依赖于聚合对象的特定类。
迭代器模式的组成部分:
- 迭代器接口(Iterator Interface):定义了迭代器的基本操作,如
hasNext()
(检查是否有下一个元素)和next()
(返回下一个元素)。 - 具体迭代器(Concrete Iterator):实现迭代器接口,维护遍历过程中的当前位置。
- 聚合接口(Aggregate Interface):定义了创建迭代器的方法,通常是一个
createIterator()
方法。 - 具体聚合(Concrete Aggregate):实现聚合接口,返回一个与该具体聚合相关的迭代器实例。
迭代器模式如何遍历集合元素:
-
创建聚合对象:首先,你需要有一个聚合对象,它包含了需要遍历的元素集合。
-
创建迭代器对象:通过聚合对象的
createIterator()
方法,创建一个迭代器对象。 -
使用迭代器遍历:使用迭代器对象的
hasNext()
方法检查是否还有元素可以遍历,如果返回true
,则使用next()
方法获取下一个元素。 -
循环遍历:重复步骤3,直到
hasNext()
返回false
,表示所有元素已经被遍历完毕。
迭代器模式的优点:
- 抽象性:迭代器模式将集合对象的遍历过程抽象化,使得遍历过程与具体的集合类解耦。
- 灵活性:可以为不同的集合对象定义不同的迭代器,实现不同的遍历策略。
- 扩展性:在不修改现有代码的情况下,可以很容易地添加新的迭代器类。
- 安全:迭代器模式可以保护集合的内部结构,防止外部代码直接访问和修改集合的内部状态。
应用场景:
- 当需要为一个聚合对象提供多种遍历方式时。
- 当需要在遍历过程中访问聚合对象的内部状态时。
- 当需要在遍历过程中修改聚合对象时。
示例:
假设有一个书籍集合,我们想要遍历这个集合,打印每本书的标题。使用迭代器模式,我们可以这样实现:
// 聚合接口
interface BookAggregate {Iterator createIterator();
}// 具体聚合
class BookCollection implements BookAggregate {private List<Book> books;// 创建迭代器public Iterator createIterator() {return new BookIterator(this);}
}// 迭代器接口
interface Iterator {boolean hasNext();Book next();
}// 具体迭代器
class BookIterator implements Iterator {private BookCollection collection;private int currentIndex = 0;public BookIterator(BookCollection collection) {this.collection = collection;}public boolean hasNext() {return currentIndex < collection.books.size();}public Book next() {return collection.books.get(currentIndex++);}
}// 客户端代码
BookCollection collection = new BookCollection();
// 填充集合
Iterator iterator = collection.createIterator();
while (iterator.hasNext()) {Book book = iterator.next();System.out.println(book.getTitle());
}
通过这种方式,迭代器模式提供了一种统一的方法来遍历不同类型的集合,同时保持了代码的灵活性和扩展性。