Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I've done this in similar situations.</p> <p>Option A) </p> <p>If the specialized operations are part of the same sequence as a base operation ( e.g. ConvertibleVehicle needs to be foldRoof before it can drive ) then just put the specialized operation inside the base operation.</p> <pre><code>class Vehicle { public abstract void drive(); } class ConvertibleVehicle { public void drive() { this.foldRoof(); .... // drive } private void foldRoof() { .... } } </code></pre> <p>So the effect of driving a fleet will be some of them will fold their roof before being driven. </p> <pre><code> for( Vehicle v : vehicleFleet ) { v.drive(); } </code></pre> <p>The specialized method is not exposed in the object public interface but is called when needed.</p> <p>Option B)</p> <p>If the specialized operation are not part of the same sequence and must be called under certain "special" circumstances then let a specialized version of a client call those specialized operations. Warning, this is not so pure nor low coupling but when both objects ( the client and the service ) are created by the same "condition" or builder then most of the times is ok. </p> <pre><code>class Vehicle { public void drive() { .... } } class ConvertibleVehicle extends Vehicle { // specialized version may override base operation or may not. public void drive() { ... } public void foldRoof() { // specialized operation ... } } </code></pre> <p>Almost the same as the previous example, only in this case <strong>foldRoof</strong> is public also.</p> <p>The difference is that I need an specialized client:</p> <pre><code>// Client ( base handler ) public class FleetHandler { public void handle( Vehicle [] fleet ) { for( Vehicle v : fleet ) { v.drive(); } } } // Specialized client ( sophisticate handler that is ) public class RoofAwareFleetHandler extends FleetHandler { public void handle( Vehicle [] fleet ) { for( Vehicle v : fleet ) { // there are two options. // either all vehicles are ConvertibleVehicles (risky) then ((ConvertibleVehicles)v).foldRoof(); v.drive(); // Or.. only some of them are ( safer ) . if( v instenceOf ConvertibleVehicle ) { ((ConvertibleVehicles)v).foldRoof(); } v.drive(); } } } </code></pre> <p>That <strong>instaceof</strong> look kind of ugly there, but it may be inlined by modern vm.</p> <p>The point here is that only the specialized client knows and can invoke the specialized methods. That is, only <strong>RoofAwareFleetHandler</strong> can invoke <strong>foldRoof()</strong> on ** ConvertibleVehicle**</p> <p>The final code doesn't change ...</p> <pre><code> public class Main { public static void main( String [] args ) { FleetHandler fleetHandler = ..... Vehicles [] fleet = .... fleetHandler.handle( fleet ); } } </code></pre> <p>Of course, I always make sure the fleethandler and the array of Vehicles are compatible ( probably using abstrac factory or builder ) </p> <p>I hope this helps.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload