Thursday, 15 January 2015

java - Avoid static binding in operations which use hierarchy arguments -



java - Avoid static binding in operations which use hierarchy arguments -

i have found issue static binding.

my real class extended, utilize several toy class express problem.

we suppose have next hierarchy.

class="lang-java prettyprint-override">public class element{} public class element1 extends element{} public class element2 extends element{}

i have stock class utilize different element specialization defined element hierarchy.

class="lang-java prettyprint-override">public class stock{ public void operation(element1 e1){ system.out.println("operation - " + e1.getclass().getname()); } public void operation(element2 e2){ system.out.println("operation - " + e2.getclass().getname()); } }

finally, have stockmanager allows manage stock.

public stockmanager{ stock stock; public stockmanager(stock stock){ this.stock=stock; } public void manage(list<element> elements){ for(element element: elements){ stock.operation(element); } } }

of course, code not compile, because stock not define method includes element argument. in case prepare code using different approaches.

first, able define method define element input arg, e.g.

public void operation(element e){ system.out.println("operation - " + e.getclass().getname()); }

this method define switch managing different concrete elements (element1, element2). however, imposible me, because switch violate open/close principle, , have lot (a lot) of concrete elements.

another alternative, utilize visitor pattern. send stock object concrete element. , concrete element charge of using stock operations. so, class alter to:

class="lang-java prettyprint-override">public abstract class element{ public abstract void stockoperation(stock stock); } public class element1 extends element{ public abstract void stockoperation(stock stock){ stock.operation(this); } } public class element2 extends element{ public abstract void stockoperation(stock stock){ stock.operation(this); } }

and stockmanager.

public stockmanager{ stock stock; public stockmanager(stock stock){ this.stock=stock; } public void manage(list<element> elements){ for(element element: elements){ element.stockoperation(stock); } } }

it allows determine in compile-time static type of concrete elements. , dynamic binding charge of phone call stockoperation method of right concrete element (element1 or element2). however!!, have duplicate code in concrete elements, , have several concrete elements.

so, know if know pattern design or best practice solve issue. (another alternative, maybe utilize reflection, not utilize it).

the problem place individual stock operations in stock object. no matter if utilize switch or not, have element type, you'll need modify stock adding new overloaded operation it. , said, stock class should closed modifications.

so have relegate whatever stock operation element object itself. sec suggestion, implementation in each different element.

public abstract class element{ public abstract void stockoperation(stock stock); } public class element1 extends element{ @override public void stockoperation(stock stock){ system.out.println("operation - element1"); } } public class element2 extends element{ @override public void stockoperation(stock stock){ system.out.println("operation - element2"); } }

you need communicate stock object real operations. stock passed each stockoperation, making methods available allow elements or set whatever needed within stock object, result of operation.

this way, if have new element type, need write new operation in new element, , can maintain same stock class without changing it. extension rather modification.

java design-patterns dynamic-binding static-binding

No comments:

Post a Comment