We all debate over when to use Static methods or Instance methods. Most of the times we go for simplest approach, but that may not be the correct one. Lets try to explore and see what should be possibly the best approach when deciding Static or Instance.
Basics
Before jumping into the difference and which should be used, check out the basics of both – Static method and Instance method.
Static Methods
Static methods are methods which can be called irrespective to the class instance. You can access only static attributes and static events within the Static method.
This is how you declare and call static method:
* static method declaration CLASS lcl_data DEFINITION. PUBLIC SECTION. CLASS-METHODS: get_data IMPORTING iv_date TYPE d. ENDCLASS. "lcl_data DEFINITION * * static method call - calling using class name lcl_data=>get_data( '20130313' ). * CLASS lcl_data IMPLEMENTATION. METHOD get_data. * do something ENDMETHOD. "get_Data ENDCLASS. "lcl_data IMPLEMENTATION
Instance Methods
Instance methods are methods which can be ONLY called using the object reference. Instance methods can access instance attributes and instance events.
This is how you declared and call instance method:
*Instance method declaration CLASS lcl_data DEFINITION. PUBLIC SECTION. METHODS: get_data IMPORTING iv_date TYPE d. ENDCLASS. "lcl_data DEFINITION * * Instance method call - calling using the object reference DATA: lo_data TYPE REF TO lcl_data. CREATE OBJECT lo_data. lo_data->get_data( '20130313' ). * CLASS lcl_data IMPLEMENTATION. METHOD get_data. " get data ENDMETHOD. "get_data ENDCLASS. "lcl_data IMPLEMENTATION
Why not to use Static methods
As you can see from the sample code, It may sound good and lucrative to create a static method as it does not involve long steps when calling the methods – declaring reference variable, instantiating the object and calling method. Static method can be directly called without doing these steps. But the design using static will not be as good as it sounds. Let me show you why:
Static methods cannot be Redefined
One of the most important aspect of the Object Oriented programming is the Polymorphism – replacing the default implementation with the more specific implementation whenever its required. In OO ABAP the polymorphism would be achieved using Method Redefinition. As we have discussed in earlier article Override Static method, we can’t redefine Static methods. The primary reason behind this is static methods are operable on their own. With static methods, you call them by explicitly specifying the type on which they are defined. Which means, you directly call the implementation, which is not bound to any specific implementation of the instance object.
Lets see this by the a simple scenario – If you have static method which does the Sales Order Creation using the BAPI. When you designed, this method was only used for one business scenario. Now, you want to use this for different business scenario. In this new scenario, you need to set some additional fields on item, like Higher Level item, determine a new item category etc. What you would think as a simple solution would be to add a code block in the method to do this logic for XYZ Sales Area, ZABC order type. What you have done here is opened a box where you would keep on adding more and more conditions. Thus violating the Single Responsibility Principle.
If you had an Instance method, you could have easily inherited another class, redefined the method and replaced the existing implementation. In this new implementation, you set the additional fields and call Super Method to do the rest.
Problem in ABAP unit testing
I haven’t covered ABAP Unit yet. They are coming soon…
Test Fixture
In ABAP unit, you can set the test data in special methods called test fixtures. After this method, your test method would be called where you have access to test data. Since each ABAP Unit test should be operable and testable on its own, Static methods makes it very difficult to test with. Static methods would use static attributes and since they are using that, you have to have additional logic to get rid of them all the time in your test fixture methods.
If you are working with the instance if the object, it can be easily cleared. When you instantiate a new object, the old object would be de-referenced without any additional logic
Constructor
Design using the static methods would end up using the CLASS_CONSTRUCTOR, as opposed to the method CONSTRUCTOR for Instance methods. As I noted earlier, CLASS_CONSTRUCTOR and CONSTRUCTOR: Who comes before whom?, it would be difficult to predict when CLASS_CONSTRUCTOR would be called. CLASS_CONSTRUCTOR can be called when the class is first accessed even though it was accessed to get Constant value. This makes it inoperable and un-testable on its own.
Reuse the Utility in same Session
Static attributes would be bound to memory till the session is over. This means that if the values are set once, they wont be cleared until the session is finished. If static attributes it won’t be possible to leverage the same logic in the same session. E.g. A simple utility class to generating Application Log.
The design is like:
- Collect log in an attribute of the static class
- Call static method to generate Application log after the collect.
The design seems fully appropriate for the utility class which should be static. But the problem with this is, it restrict you from using the same logic again in the same session without losing the existing information. Lets say, you are collecting a errors using this application log. Now, in the same program, you wont to generate another application log to track the activities performed. Since you have collecting all the errors in the static attributes, unless you copy it into another placeholder and call the Utility class for generating the tracking log, you would lose the error log data when you try to use the same Utility class.
On the other hand, you had a design using instance method and attributes, you would be able to simply create another instance and start using it for tracking log.
Thumb Rules
So based on all these facts, we can conclude to these thumb rules:
- If you are planning to create any static attribute which would be used by static method, Consider creating instance methods. It would allow you to work with multiple instances. It also allows you to control on when you can free up the bound memory.
- If you think that there would be a chance to add a conditional logic in future, Go for instance. This makes design more flexible by allowing you to leverage polymorphism by Redefinition
- Static should only used for object creation design patterns like Singleton, Factory Method, Abstract Factory, Singleton Factory to facilitate the object creation.
- Static should be for pure utility classes not for helper classes. The best examples would be methods within the class CL_GUI_FRONTEND_SERVICES.
Let me know if you want to add any other perspective of using vs not using the Static method.
On a side note
Implemented quite a few changes on site Homepage and other pages including Navigation, Menu, Related Post etc. The site is also now mobile (iPhone, Android, Nokia, and others) as well as tablet (iPad, Galaxy and others) friendly. Check it out and let us know your feedback.
Ok, lets think of the following scenario: custom development, custom table, create methods and some other methods where the possibility is that according to a specific condition, they would need to be different ( redefinition in subclass )
My current idea to ‘best practice’ this (after the discussions in the previous articles ):
Objects needed:
– Static class, singleton factory which returns an instance object
– Instance superclass for the main flow
– Instance subclasses for the condition based flows
In our application, let’s say a Webdynpro ABAP application, we would call the static class factory method in the COMPONENTCONTROLLER, WDDOINIT method and we pass along the condition based parameter.
This factory method would return an instance of the correct class (ZCL_SUPER or ZCL_SUB_COUNTRY_A).
This would give us the flexibility, that for Country A the create would be that way, and for country B the retrieval of a description would be another way.
We could also use the static class to initiate a BAL Log in the static constructor and add messages to it along the way.
What do you guys think?
@Wouter that is a bit more advanced that what I’m doing.
My take, static method = function-module. Instance method like a locally used and changeable function-module.
The coolest for me is using as a functional method calls and using them instead of variables.
Hello Wouter,
Yes, I overall agree with your design. Definitely looks like a easily extendable design. A new condition for COUNTRY_B, Inherit the super class, extend the factory/singleton method for object creation, easy! After all OO is for easy maintenance.
For object creation, I guess what you are looking for is the Singleton, as your application would only executed for a single condition at a time. Compare to Factory method which gives NEW object all the time, Singleton provides the same object again and again.
Regards,
Naimesh Patel
Please keep posted such articles…thanks a lot
Hi Naimesh,
I’m with you on not using static methods too much, but for me, it’s not (only) about methods, it’s about objects. Objects encapsulate data/state with methods to do something intelligent with the data. So for any class (= responsibility), if there is common data shared by its methods (= how to implement the responsibility), that data should be in the attributes, and the methods should be instance methods.
Static methods/attributes should thus be the exception, and the question which one to use should not even be raised in general.
Just my 2 cents of course 😉
Cheers, Fred
Hello Fred,
I completely agree with you on the overall design perspective. We definitely need to think about the responsibility and state of the objects. But as soon as you say objects, you are going to use Instance methods. This basic guidelines would help to decide to use Objects or not. As soon as you go for objects, there will be second stage of refactoring to achieve polymorphism, responsibility and setting proper state 🙂
Thanks Much for your comment.
Regards,
Naimesh Patel
Hey Fred,
Agreed, but I don’t emediately dare to use it on customer systems to be honest. Just because that approach is too OO. I’ve heard procedural ABAPpers already complain about simple classes and such, also they don’t like it because then Functional people or even internal IT people cannot debug anymore ( or not as easily ) to locate issues.
If I would look at my example, a static class with create methods and methods to change the status, and convert this to your approach, fully OO that would mean:
Instantiate an object with the key, call the create methods which prepares the records to save to the table later on. Some update methods to set different statusses and on and everything would be done in the attributes.
i would have to retrieve the values with getters and setters and commit to the db with a method.
But if I would do this in mass, it would be less readable and I would always get everything out of objects, while otherwise I can call my static create methods and append this to a large internal table.
Any thoughts? Do you also have experiences anti-oo or better said, people not willing to learn oo or postpone learning oo as long as possible.
Greets,
Wouter
As a customer developer, we have very little outside development. And when we do, they must code within our standards, However, we do change and update our standards every few years (well I instigate most of the changes usually by introducing new functionality)
The biggest complaint I have about SAP’s OO code is knowing what exactly it does and is suppose to do. Too much abstraction and little documentation (not availible in your language!?!) make it like a nesting/nested doll, that when you get to the last one, it’s just simple ABAP that would have been better in the first doll. You get the feeling they are re-coding just to make it shiny and charge more money for the same thing, in a “new and improved” package.
If you want to sell to a customer, make it easy for them to understand. Make it simple for them to use. Make it easy to maintain. Show them K.I.S.S.
Flexibility – We are a US state government. I don’t use ‘flexibility’. Anything that is not straightforward, or easy to understand or simple is really wasted and takes up space. When production problems occur, I really don’t need to spend my time analyzing nested code to find out what it is suppose to do. I want to know what the data is, where it came from, and how the result occurred.
So, when I use the OO approachs I have learned here, I run it by the most junior ABAPPERs to see if they understand, because they will be the ones most likely to change and maintain this code. And I take the time to review it with my QA reviewer so they understand by using this particular OO code, I have made an improvement. Then, they do suggest using this in other programs, and it becomes a de facto standard.
To all posters, thank you very much for posting. I learn from reading your comments.
Thanks!!
Hello Wouter,
Thanks you very much for your valuable inputs.
The design you are thinking for each database record is Kind of Persistent Objects. When using the Persistent objects, you create setters and getter methods. Each field in your table which you want to update would become and instance attribute of your Persistent Object. You keep on collecting the persistent object for each row in the context. At COMMIT WORK, system would take all the active changes and update them in the DB table.
Persistent Objects are not getting much of the popularity in ABAP. Mainly the lack of Object services to access the tables and retrieve the information from DB tables. As you have noted, they would be performance intensive as well.
The state based design would be ideal solution for the User Entry screens like, ME21N Purchase Order entry. That is using kind of State mechanism to handle each record. It would generate objects for Header, for each item, for each schedule line item, etc. At save, it would check the state of each object to decide on update.
Agree that it would be difficult for procedural IT people to understand. For developers, we should keep our Technical Design document up-to-date with the current design. Including UMLs would be a great idea. As long as the developers can read UML, they would be able to understand it easily. For functional teams, they would need to keep up their skill to get used to it.
I too get this push back from my other team members, but I would still pursue using OO ABAP.
Regards,
Naimesh Patel
Hello Steve,
I agree that when you are using OO ABAP, the newbie would have difficult time to understand especially if they have already tasted the Procedural ABAP. But, as I mentioned in my reply to Wouter, they should be able to understand the design if the TD is well up-to-date.
Obviously, OO ABAP needs more time from beginning of development to testing for the initial development. But as that software evolves, we would start reaping the benefits of that.
Thanks much for making this discussion so unique.
Regards,
Naimesh Patel
One last thought: when we talk about instance methods, we are actually always talking about ‘ persistance objects’ ( using class attributes) ? The only other instance scrnario i can think of right now is an instance class that is the application model, which does some main things such as logging, and all other methods would act as static methods ( as in methods who don’t use class attributes – you could set these as instance too to enable redefinition ).
Hello Wouter,
You can use your instance methods & attributes in any context. It doesn’t need to be persistent only. For example, If you are using to update a standard document say Sales Order using BAPI, than your class design is not Persistent. You only care about setting the BAPI parameters from your class properly. Another example could be a report – two options – Summary and Details. Summary can be inherited from Details as summary would be ideally total of all the amount/qty fields.
Thanks,
Naimesh Patel
Hey Naimesh,
I’m a regular follower of your blogs on ABAP. We, as an audience, get to learn a lot by reading your articles. You’ve, kind of, anagrammatized ABAP in a beautiful way.
I was, however, thinking that wouldn’t it be great if you could write something on new dimension topics like CRM WebUI, Webdynpro or even ALE/Idocs for that matter?
Cheerz!
Aasim
Hello Aasim,
I’m glad that you like the what you read on zevolving.
Regarding new dimension topics – I have them lined up and they would be coming up soon. BTW, design patterns, and all OO Stuff you find here, is a new dimension already 🙂
Regards,
Naimesh Patel