求教《Object Thinking》中协作定义的符合要求的实际代码示例
理解《Object Thinking》中的“隐秘助手”协作模式
你提的这个问题戳中了David West定义里最反直觉的部分——一开始确实很难想象这种“既不是实例变量、也不是临时变量、也不是参数”的协作对象到底是什么样的。咱们先再明确一下原文的定义:
对象A收到其已声明服务的请求,在处理该请求的过程中,需要向对象B请求服务。对象B并非对象A的实例变量、不是A为处理原请求而执行的方法中声明的临时变量,也不是作为服务请求消息的参数提供给A的对象,B是A的协作方,即隐秘助手。
你说的没错,你代码里的helper1(实例变量)、helper2(方法内临时创建)、helper3(方法参数)确实都不符合这个定义,而且静态方法调用也不算——因为静态方法属于类,不是对象之间的协作。
实际代码示例:服务定位器模式下的隐秘助手
最典型的场景是通过服务定位器或全局上下文获取的对象,这类对象既不属于A的内部状态,也不是A自己创建或接收的参数,而是A在处理请求时从外部环境中获取的协作方。
先写一个极简的服务定位器:
// 简单的服务注册与获取工具 class ServiceLocator { private static final Map<Class<?>, Object> registeredServices = new HashMap<>(); // 提前注册服务实例 public static void registerService(Class<?> serviceType, Object instance) { registeredServices.put(serviceType, instance); } // 根据类型获取服务实例 @SuppressWarnings("unchecked") public static <T> T getService(Class<T> serviceType) { return (T) registeredServices.get(serviceType); } }
然后定义协作方B和需要它的A:
class B { public void assistWithProcessing() { System.out.println("B正在作为隐秘助手协助A处理请求"); } } class A { public void handleRequest() { // 这里的B既不是A的实例变量,也不是方法内new的,更不是参数传入 // 而是从服务定位器中获取的外部协作对象 B secretHelper = ServiceLocator.getService(B.class); secretHelper.assistWithProcessing(); } }
另一个例子:线程上下文对象
还有一种常见场景是**线程局部存储(ThreadLocal)**中的对象——A在处理请求时,从当前线程的上下文里获取B,同样符合定义:
// 线程局部上下文,存储每个线程专属的B实例 class ThreadContext { private static final ThreadLocal<B> threadLocalB = ThreadLocal.withInitial(B::new); public static B getCurrentB() { return threadLocalB.get(); } } class A { public void handleRequest() { B secretHelper = ThreadContext.getCurrentB(); secretHelper.assistWithProcessing(); } }
为什么这符合定义?
- 对于A来说,B既不是它的实例变量(A没有持有B的引用作为成员),也不是方法内临时创建的(不是
new B()出来的),更不是通过handleRequest的参数传入的。 - A只知道“我可以获取到一个B来帮我处理请求”,但完全不关心B的创建、存储或管理逻辑——这就是West所说的“隐秘助手”:它是A的协作方,但A对它的来源一无所知。
内容的提问来源于stack exchange,提问作者Ward
相关产品推荐
相关产品推荐

