0

Should all public methods correspond to business logic?

  • if yes, how to deal with situation in which two objects need to communicate at lower design layer, and thus need some non-business methods to be public? (or is this antipattern?)
  • if no, how to clearly distinguish between public and business public methods?

These are the options I am aware of:

  • create business logic interfaces (as Attila and ArjunShankar suggest)
  • #define BUSINESS (in C++) and then use as BUSINESS void myMethod()- not sure if it is good idea

Any other possibility?

Jan Turoň
  • 26,696
  • 21
  • 102
  • 153
  • 1
    If I *had* to do this: I would expose 'business logic' methods in a separate interface. Then cast the object into it before providing it to a 'business logic' user. – ArjunShankar May 21 '12 at 10:49
  • The preprocessor will expand BUSINESS to nothing. So I'm guessing your intention is to 'document' the 'intended use' of a function in code, and hope that users of the class will follow it? – ArjunShankar May 21 '12 at 11:08
  • I don't think that the premise you have makes sense. From one of the comments you intend to use *business* as should not be changed or refactored because it is *important to other parts of the application*. All code is *business code* in the sense that it is important for other parts of the application to be able to complete the business logic. If they are not, then just remove them from the project. What you probably need is to fully document what the method should do (different to what it actually does) and as long as any refactor maintains those invariants, you'll be fine. – David Rodríguez - dribeas May 21 '12 at 11:55
  • Considering that there are two types of *functions* and that some of it are second class citizens is absurd. What you call *business* will depend on other parts of the code, and changing those dependencies without changing the *business* will lead you to broken code. – David Rodríguez - dribeas May 21 '12 at 11:56
  • @dribeas: business logic depends on analysis, not on implementation. Analyst knows the big picture, coder may not. So it may be useful to give a hints like *do not change this, or else it will require substantial change in the rest of the application you do not see or threaten future development because your colleagues needs this to be untouched for now* I would agree with you if the development was one-man show. – Jan Turoň May 21 '12 at 12:20
  • If you are worried about developers arbitrarily changing the logic (and fixing the failing tests) you have issues that cannot be solved by code. If documentation is not a help, code reviews should at least help detect the issues and educate developers. – Filippo Pensalfini May 21 '12 at 15:31

3 Answers3

2

public just means that code outside the class can access (e.g. call, if method) the member, it has nothing to do with business logic.

If you need to restrict your object's interface to some code that is using it, you can have the class implement an interface that lists only the desired methods, and pass the object via that interface (i.e. the method parameter's type is the interface), so the code that is operating on the object can only access the desired methods

Attila
  • 26,065
  • 3
  • 41
  • 52
1

If your language supports interfaces, you could use that to let it expose different behavior based on context (if your language supports multiple inheritance instead, use that):

Interface Kickable /* For 'business logic'.  */
  method kick (Direction)
  method dribble (Technique)

Interface PhysicsObject /* For collaboration with other objects.  */
  method collide_with (PhysicsObject)
  method fall (gravity)

Class Football Implements <Kickable, PhysicsObject>

This is pretty clean, because nobody gets to see the methods they shouldn't:

Football football = new Football ();
/* Let the physics engine deal with PhysicsObjects.  */
physics_engine.add (PhysicsObject (football));

/* Let players deal with it Kickables.  */
game.set_ball (Kickable (football));
ArjunShankar
  • 21,354
  • 5
  • 57
  • 78
  • Okay, nice example, but how to distinguis between business interface and common interface? I'd like to emphasize in my code: *this is business logic, do not change this!* – Jan Turoň May 21 '12 at 11:09
  • @JanTuroň - I didn't understand what you mean by *common interface*. – ArjunShankar May 21 '12 at 11:10
  • The point of my answer was not to make 'business logic' more important. It was to show that each 'kind' of interaction is special, and to hide from each kind of user, functionality that is not useful to it. i.e. the PhysicsEngine never needs to know that this is a Football being kicked about in a game. And the Players never need to know how the Physics behind the ball works when they kick it. – ArjunShankar May 21 '12 at 11:13
  • common interface = intended for collaboration with other object, not for business logic – Jan Turoň May 21 '12 at 11:13
  • Say my colleague is working with part of my project and he would like to refactor something. I'd like to emphasize directly into the code in some short and standard way: *do not change Kickable, it is business logic important to other parts of the application. Feel free to change PhysicsObject if you really need* – Jan Turoň May 21 '12 at 11:18
  • 1
    @JanTuroň - I guess *that* sort of thing is better done with comments/documentation. e.g. the empty `#define` you quote in your question. The point of this answer was more technical, in the sense, ensuring at compile time that the 'right' people access the 'right' behavior of your object. – ArjunShankar May 21 '12 at 11:21
0

Is it really possible to know what methods are to be used externally and which methods should not? In my experience, the methods used for internal communication between classes often get used in unexpected ways later as the requirements from the user change. So I would first recommend writing good unit tests to verify the behavior of all public methods of your class.

With that said there is an idiom in C++ to accomplish your goal, the pimpl idiom: Why should the "PIMPL" idiom be used?

Community
  • 1
  • 1
Josh Peterson
  • 2,159
  • 15
  • 19