After our discussion in comments, reading your comment to Peter's answer and inspecting your lately added sample code, I actually understand your question but fail to understand why you see a problem there.
Your method fireAndWait()
is actually a Template Method, which is a well-proven OOP design pattern. I think it is totally fine to implement doWork(List<T>)
as part of the algorithm, but instruct the user (via JavaDoc) not to call it himself but rely on its being called indirectly. For instance, you often implement Runnable.run()
(even in your sample code!), but do not complain that it is not being called by yourself but indirectly via Thread.start()
or ExecutorService.execute()
. Isn't that the same pattern? Why should one "God method" do everything?
If you do not like your own pattern method approach, feel free to write a PartitionedParallelExecutorStatisticsAspect
(sorry for the long name) taking care of this aspect (because that's what it is). Put it into the same package if you like, so it is near the abstract class, and let it do its job. God classes are equally bad as God methods, so arguably using AOP is also a viable alternative. Doing the (parallel partitioned) job is the core concern here, keeping stats is a secondary one. I would be fine with both approaches if implemented cleanly.
Although this topic is partly kinda philosophical and I have seen several close votes here, which is understandable, I am still hoping my comments are helpful. If so, feel free to accept the answer and close the topic so as not to make it an endless discussion thread.