Comments (5)
One of the main reasons we advice against static methods is that it is hard to test them.
In the following example, it is hard to unit-test the method_under_test
because the static dependency to unmockable_method
cannot be mocked:
METHOD method_under_test.
some_dependency=>unmockable_method( ).
ENDMETHOD.
With objects, this becomes easy, as the dependency can be replaced with a test double:
METHOD method_under_test.
some_dependency->mockable_method( ).
ENDMETHOD.
How would you make this testable without instance methods?
from styleguides.
I think we are talking about different aspects.
Let's consider an example.
class lcl_my_class
data mt_data type table.
methods run.
methods select_data.
methods post_process_data.
endclass.
method select_data.
select * from xxx where yyy into mt_data.
endmethod.
method post_process_data.
loop at mt_data assigning <i>.
<i>-attr = ...
endloop.
endmethod.
method run.
select_data( ).
post_process_data( ).
endmethod.
The code is OK. However it can be improved. The run
method serves kind of controller - the main flow. And although the logic flow is clear, the data flow is obscured by usage of members inside secondary methods. In terms of readability and comprehension I would declare select
and post_process
as static and thus get this.
method run.
mt_data = select_data( ).
post_process_data(
changing
ct_data = mt_data ).
endmethod.
Now the data flow also clearer and post_process_data
becomes less error prone as it does not relay on object state (postprocessing is not the right example for this issue I confess). Object state is a minified global variables
problem to some extent. Pure functions just do now have this problem conceptually. Also post_process
becomes more testable in terms of isolation (if you want to test it at all ... see below).
Now let's focus select
. It is accessing DB so good idea to mock it. In this case you create an interface, a data accessor class implementing this interface, well ... if I understand correctly this is the case you're referring to. And I 100% agree, hands up. The select
should become instance method (of data accessor) in this case.
Note that the above code is very refactoring-friendly for select
, just one clean change to do:
method run( data_accessor ). " PSEUDO CODE
mt_data = data_accessor->select_data( ).
post_process_data(
changing
ct_data = mt_data ).
endmethod.
The above is more about code composition and being more bug prone and readable. In terms of testability:
- I agree that public methods should better be mockable
- static public are probably utilities and should go to a separate class. E.g. let's say we also have some method
convert_account_to_range
which converts single or table of e.g. gl accounts into range table. This really should be in-out pure function - a static method. But if it remains public then it does not belong to the class. - finally the
post_process_data
would probably be private. And then maybe it should not even be tested ("test public interface ..." rule) so it end up with benefits of having it as a pure function I mentioned.
To summarize: it is not about "avoiding static methods" it is about "properly using them". I personally would forumulate the rule as "unless you're planning to mock the object, try to use pure functions as far as you can while it stay convenient and clean (mainly about number of passed parameters and performance)"
from styleguides.
What you are describing is the conflict between stateful and stateless programming. As described in Don't mix stateful and stateless in the same class, both are sound and have their applications.
Also, as described in the examples above, both benefit from instances, objects, and interfaces, and should not be implemented with static
methods alone.
Do we need to reformulate Prefer objects to static methods to make clear that the "object" here really only means "instances of classes", and not "object-oriented stateful design"?
from styleguides.
@sbcgua, I am unclear what to do with this issue. Does it need more clarification? Do we need to make the text clearer, as described in my last post above?
from styleguides.
I guess let's close for now. "Prefer objects to static methods" section does capture my idea about utilities. I think it can and should be used wider but at the end it is a matter of preference. :)
(And sorry for long silence :)
from styleguides.
Related Issues (20)
- Strategy for handling dependencies to system releases HOT 4
- Text on logo not readable in dark mode (Code Review Guide) HOT 3
- [Exploit the test tools] Add CL_AUNIT_AUTHORITY_CHECK to the list? HOT 6
- [Consider decomposing complex conditions] bad use case example HOT 1
- German Translation: Typo HOT 1
- Use assert class instead of ASSERT HOT 12
- Are comments bad or not?
- [Use CHANGING sparingly, where suited] Is it ok to use IMPORTING REF instead of CHANGING? HOT 7
- New rule: prefer inferring types HOT 1
- Abap Exception categories HOT 3
- Use READ-ONLY sparingly - new abap command FINAL HOT 2
- How to add sample code to Clean ABAP? HOT 1
- Unclear explanation of [Use LOCAL FRIENDS to access the dependency-inverting constructor] HOT 5
- Follow rules when abbreviating HOT 1
- "Dead" link at section "split-method-instead-of-boolean-input-parameter" HOT 3
- Chapter "Avoid abbreviations" HOT 7
- [Prefer RAISE EXCEPTION NEW to RAISE EXCEPTION TYPE] In defense of RAISE EXCEPTION TYPE HOT 6
- Prefer ENUM to constants interfaces HOT 1
- [Use | to assemble text] Is a caveat needed in case of translatable texts? HOT 7
- "New rule" Tables > Prefer a Table Expression to READ TABLE
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from styleguides.