Skip to Content
Author's profile photo Marcin Pciak

OO geek journal – hiding method invocation

Few days ago I was facing a problem, where I needed to use some common algorithm which differs only in some small aspect, that is delegating some task to different methods. Please consider below academic version of a case.

Quick jump in

Model class

/wp-content/uploads/2013/04/model_206829.png


This simple class has merely three methods, get_all, get_active, get_inactive. All they do is to return some set of components. Now, let’s create simple Controller class which utilizes model methods to show the results.

Controller class

/wp-content/uploads/2013/04/controller_def_206830.jpg

/wp-content/uploads/2013/04/controller1_impl_206900.jpg

The important part is that for some reason in each method we need to repeat model creation. Let’s assume this is very complex process which relies on different factors, which we should not bother here. Each method however does the same thing, but it only differantiates model’s method invocation. One time it calls get_all, another time get_active or get_inactive. This is the only part which differs all three controller methods, but for some reason must are tied to the code embracing it.

Test program

/wp-content/uploads/2013/04/run_206901.jpg

Result

All:

01 COMP1

02 COMP2

03 COMP3

Active:

01 COMP1

Inactive

02 COMP2

03 COMP3

Redundancy


As we noticed above we have redundant code which does exactly the same with small difference of model methods’ call. What we wish to have instead is one common method which only differs method call based on some parameter. Using IFs or CASE is ugly practice. We will therefore utilize Object Orientation.

wish to have

/wp-content/uploads/2013/04/controller_wish_to_have_206902.jpg

Hiding method invocation

First we need to introduce new class, whose subclasses represent different component’s sets. It has only one method get_comp which returns different sets of components in different subclasses.

Abstract class

/wp-content/uploads/2013/04/model_comp_abs_206909.jpg

Subclasses

/wp-content/uploads/2013/04/model_comp_impl_206910.jpg
All three classes simply receive model instance and use them appropriately to their meaning.

As simple as that


Now all we need is our common method in the controller which hides model methods invocation by utilizing interface (abstract class).

new Controller definition

/wp-content/uploads/2013/04/controller_2_def_206911.jpg

uniform get_comp method

/wp-content/uploads/2013/04/controller_2_get_comp_206912.jpg

Notice that get_comp represent redundant code and is no longer aware of which method we want to call. It even doesn’t know which object is it working with. The only information it posses is that this object is of type lcl_model_comp (abstract type). So in fact we are programming to an interface as at the time of program creation we don’t know which class we are working with.

We leave the decision of method selection to the specific instance of lcl_model_comp, be it either lcl_model_comp_all, lcl_model_comp_active or lcl_model_comp_inactive. The last thing to do in order get_comp works correctly is to call it with different lcl_model_comp instances in the appropriate methods.

/wp-content/uploads/2013/04/controller_2_impl_206913.jpg

Please don’t bother the fact that showing the result is implemented in all the methods. We could of coruse move that to other method which only shows what was returned. What I wanted to show here is that the result lt_comp originates from get_comp depending on model_comp object we choose.

Conclusion


Sometimes it may be required to invoke different methods of same object inside some complex algorithm. By utilizing simple characteristic of Object Orientation – that is object diversity, we are able to create more uniform code which eliminates redundancy. By introducing another level of abstraction (lcl_model_comp) we don’t need to worry anymore of the method selection at its invocation place. Instead we move that responsibility to that new class instance.





Assigned Tags

      8 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Thomas Thullen
      Thomas Thullen

      Hello Marcin,

      wouldn't it be easier to use a static factory method in lcl_controller instead? Therein create the instance for lcl_controller and lcl_model and you'll have the same effect, only one place to create a lcl_model instance.

      I don't see the need of using abstract class, inheritance and polymorphism in this special case, anyhow they might be great tools in other cases.

      best regards

      Thomas

      Author's profile photo Marcin Pciak
      Marcin Pciak
      Blog Post Author

      Hello Thomas,

      I must disagree here. Using factory method we would only hide model object creation, which of course was part of the problem. But we still leave w/ an issue of different methods call.

      In my blog I wanted point on how we can encapsulate different methods call, where we leave the decision their selection indirectly to the callers (show_.. methods). In fact these callers could be represented by the Client, so we would end up with only one method (get_comp) and the Client would make the choice of model_comp selection, hence calling different methods (either get_active, get_inactive or get_all). Such technique is know as double dispatch.

      Regards

      Marcin

      Author's profile photo Thomas Thullen
      Thomas Thullen

      Hello Marcin,

      yes you're right. My answer was to quick. Didn't see the whole picture of what you was figuring out. Sorry 🙂

      regards

      Thomas

      Author's profile photo Marcin Pciak
      Marcin Pciak
      Blog Post Author

      Hello Thomas,

      No problem. This only made me thinking if I did proper design steps 🙂

      Regards

      Marcin

      Author's profile photo Jacques Nomssi Nzali
      Jacques Nomssi Nzali

      Hello Marcin,

      thanks for taking the time.

      Real life problems usually take a lot of time to analyze. Your academic version is well presented and I had fun following it. I found myself drawing the class diagram a checking which refactoring you applied.

      Now time to nit-pick, my comments:

      it seems to me the uniform get_comp( ) method should depend on lcl_model_comp abstract class and not on the concrete lcl_model class. The code should not be able to just create the object if the parameter model is not bound. So basically you should remove lcl_model from your code.

      I would propose the following refactoring to merge the 3 show_...( ) method into one that would be called 3 time with a parameter

      1. 1. a factory in the lcl_model_comp abstract class,
      2. 2. something like a get_text( ) Method in the lcl_model_comp that would be implemented by the subclasses and return the state as text (active, inactive, all)

      with this, the show method would look like

      lo_model = factory( c_all ). " or c_active or c_inactive

      display( lo_model ).

      the single display( ) method would do

      lt_comp = lo_model->get_comp( ).

      WRITE lo_model->get_text( ).

      LOOP AT lt_comp..

        WRITE ..

      ENDLOOP.

      My understanding is that you are applying the state/strategy pattern with a single dispatch, no double dispatch.

      thanks again for taking the time,

      regards,

      JNN

      Author's profile photo Marcin Pciak
      Marcin Pciak
      Blog Post Author

      Hello Jacques,

      Thank you for nice words and sharing your thoughts, here are mine 🙂 :

      1. actually get_comp is using abstract lcl_model_comp, not concrete class, so not sure what you mean here.

      2. your factory method would rely on parameter (contant which indicates which lcl_model_comp object we want to create). I see it like:

      case ip_param.

         when c_all.

           create object rr_model_comp type lcl_model_comp_all.

        when c_active.

           create object rr_model_comp type lcl_model_comp_active.

          when c_inactive.

            create object rr_model_comp type lcl_model_comp_inactive.

      endcase.

      In such case when new "state" arrive, you would need to change factory method implementation, that is you violate "open-closed" principle. In my example when you need to add new "state" you:

      a) implement new class which subclasses lcl_model_comp and call this new state method in get_comp

      b) add new show method (or add new client call) which simply utilizes this new class object

      With these all you do is "add something" to the implementation, not "change something".

      3. I agree to introduce additional method get_text which will represent lcl_model_comp subclass "state" in words

      4. Actually it's close to state pattern, but I can't agree on single dispatch. Normally, as seen in initial example, we had single dispatch

      method show_active.

          lo_model->get_active( ).   "here dispatch happens

      endmethod.

      Now, we have double dispatch:

      method get_comp.  "in lcl_controller

          lo_model_comp->get_comp( ).  "first dispatch

      endmethod.

      method get_comp. "i.e. in lcl_model_comp_active

           lo_model->get_active( ).     "second dispatch

      endmethod.

      Any commets welcome, maybe I missed something too 🙂

      Regards

      Marcin

      Author's profile photo Jacques Nomssi Nzali
      Jacques Nomssi Nzali

      Hello Marcin,

      oops I got it all wrong 😕 . You are actually implementing a visitor ?

      I will go back to code and return only after more study.

      Anyway it is still fun, thanks.

      Author's profile photo Marcin Pciak
      Marcin Pciak
      Blog Post Author

      Hello Jacques,

      I did not face visitor pattern yet, so I need to study it first to claim whether I am using it or not 🙂 For me it was just intention of sharing idea of how to get over some basic issue. Did not focus on design pattern even I accidentaly had used one.

      BTW: oops for me only means "Object Oriented Programming Sanity" not your mistake 🙂

      Cheers

      Marcin