A partial answer to the partial question (with no partiality to C#, Java, or quantum mechanics):
Some unnamed caller needs to effectively call:
where calculateAllocation is private (so, presumably invisible to the caller).
[So, let's imagine the int getQuantity() method in the Order interface.]
The Warehouse implementation depends on AllocationResponse.
The unnamed caller must minimally depend on the existence of Order and Warehouse and needs some way to call calculateAllocation "for an order".
Comparison of the variants:
Option 1 pros:
- The unnamed caller has no further dependencies beyond the above minimum.
Option 1 cons:
- Warehouse now depends on Order, Order.getQuantity and Order.processed.
Option 2 pros:
- Warehouse has no further dependencies.
Option 2 cons:
calculateAllocation is now completely exposed to abusive calling (via allocate) with not so much as an Order in sight. They might as well be one public function. Yet calculateAllocation was likely defined private for good reason -- otherwise:
would have been Option 0.
The unnamed caller now depends on Order.getQuantity, Order.processed, and AllocationResponse.
Note: The dependency on AllocationResponse could be reduced (at least in one sense) at some cost of readability (you judge?) and unique line numbers for breakpoints (typically just where and when you need one) with:
Now, those are just the apparent trade-offs, but they may well be outweighed by how these design options fit in with other present and foreseeable code.
Option 1 would be more favorable in a wider system that might:
define Warehouse-based classes that specifically refine the behavior of allocate(order),
possibly with no change or a different change to calculateAllocation(int). That is, refining allocate(order) SOLELY indirectly by refining calculateAllocation(int) would be the same deal between Options 1 and 2.
have many different callers of the exact same idiom:
require other exposure to Order, Order.getQuantity and Order.processed in the Warehouse module (helping to justify/amortize the dependency cost).
Option 2 would be more favorable in a wider system that might:
require or desire other exposure to Order.getQuantity and Order.processed, and possibly AllocationResponse in the unnamed caller (to justify/amortize the dependency cost) other than just using the idiom:
Repeated use of this idiom would argue for giving it its own method -- under Option 2, a local method of the unnamed caller, so that would be pretty much the same deal between Options 1 and 2.
In some "binary" sense, the Order interface is already imported by the unnamed caller, so the exposure to the methods is implicitly already there "for free" or more like "for better or worse". Here "binary" has BOTH its meanings of "either on or off" and "down to the compiled bits". This "binary" distinction is important when designing interfaces for libraries intended for public consumption "to be supported forever". But in a subtler practical sense, for an interface that's only used experimentally or in a small "in house" code base, isolating function calls to a small fraction of even the modules that import the interface can make it considerably less painful to "break the contract" later by evolving those functions. In this sense, calls to each distinct Order method from the unnamed caller is a "deeper" dependency than merely importing the Order interface.
- require or desire other exposure to calculateAllocation/allocate(int) outside Warehouse. That seems unlikely. Otherwise, calculateAllocation would not have been declared private, or it would have been changed to public as a knee-jerk Option 0 solution as soon as this design problem arose, with none the wiser -- now THAT's what I'd call "doing it all wrong".