访问者模式中核心方法是否必须返回void?能否自定义返回类型?
关于访问者模式修改返回值的疑问解答
1. 为什么不建议把accept/visit改成返回String?
不是完全不能这么做,但这种实现会削弱访问者模式的核心优势,甚至违背它的设计初衷:
- 操作逻辑回渗到元素类:如果
accept要返回String,处理组合元素(比如包含多个子零件的Car)时,你得在Car的accept方法里手动拼接自身和子元素的返回结果——这就把“字符串拼接”的操作逻辑又塞回了元素类里,而访问者模式本来就是要把操作从元素中剥离,让访问者负责具体逻辑。 - 访问者扩展性被锁死:每个
visit返回String的话,这个访问者就只能用来生成字符串了。如果之后需要做其他操作(比如统计零件数量、生成JSON),要么得重新定义一套返回对应类型的接口,要么就得在现有接口里妥协,灵活性极差。 - 结果收集场景受限:用返回值传递结果的方式,无法处理复杂的收集需求(比如多步骤拼接、条件性添加内容)。而让访问者内部维护一个
StringBuilder之类的状态来收集结果,能更灵活地控制输出逻辑,还能支持多次访问、多线程安全(做好同步即可)。
2. 访问者模式的接口方法必须返回void吗?
当然不是。访问者模式的核心是双分派机制和操作与数据结构分离,返回值完全可以根据业务需求定义,甚至可以用泛型实现通用化的返回类型:
比如定义泛型访问者接口:
interface CarElementVisitor<R> { R visit(Wheel wheel); R visit(Engine engine); R visit(Body body); R visit(Car car); } interface CarElement { <R> R accept(CarElementVisitor<R> visitor); }
这样你可以实现不同的访问者:
- 一个返回
String的访问者,负责生成文本内容写入文件 - 一个返回
Integer的访问者,负责统计零件的总数量 - 一个返回
List<Part>的访问者,负责收集所有零件信息
这种方式既保留了访问者模式的优势,又能灵活支持各种返回需求,比直接固定返回String要优雅得多。
内容的提问来源于stack exchange,提问作者nik
相关产品推荐
相关产品推荐

