-1

There exists different composition arts/techniques, i will present in the following some of them.

The question then is do you know more techniques additional to my presented ones?

And then the important question is, what kind of different makes it from the client perspective, how should i access from a client a compositionend objectgraph or in an other way asked, which composition-technique is client-friendly in the context of a good object orientented design, which depends on the Law of Demeter?

Which other dependencies could be out there, let me go more into that direction (using the compostion A) and what to go into an other direction (using composition B)

i have choosen my examples with the approach extending a root object, which is initially used by the client in its behaviour:

This question is related to that one: No trivial god-class refactoring

i have an object and a few methods in it

//also called MyObject1
class MyObject{
  
  ...

  doSomething1(){}
  doSomething2(){}

}

and now i want to extend this object with more methods, for example a doSomething3 which acts on the state of that object and maybe on some kind of "own" state.

so there are now different ideas how i can achieve this:

  • add this method + its more membervariables, which are needed, to the existing class
  • create a new class MyObject2 and write it down into this class

if i decide for the secound solution, then the question is how to combine MyObject and MyObject2

  • I can integrate MyObject2 into MyObject

    class MyObject {
    
      MyObject2 myObject2 = new MyObject2(this)
      ...
    
      doSomething1(){}
      doSomething2(){}
    
    }
    
  • i can let MyObject2 standalone, but when is the question, how the client get access to MyObject2, if he has access to MyObject

  • Third class, that combine the other two

     class ThirdClass {
    
       MyObject myObject = new MyObject()
       MyObject2 myObject2 = new MyObject2(myObject)
    
     }
    

The client have then in option 1) and option 3) the following possibilities:

....myObject.getMyObject2().doSomething3();
....thirdClass.getMyObject2().doSomething3();

Edit (because the solution from Greg Burghardt is a trivial solution, but correct, to my simple examples, but covers not the main-problem):

So let us say we have a MyObject3 built up the same way as MyObject2, depends only on MyObject1 (it's a synonym for MyObject without the 1, to make clear that i dont have type-mistake here), and a MyObject4.... MyObject2-4 don't need to know each other because they extend only the behaviour of MyObject1.

And then i have a MyObject5, which depends directly on MyObject1 and MyObject3

The question is the same, how should i compose that objects, to get access to all functionality of all of these objects from client-side? Which of these objects is the root-object, do i have a "third" object which acts as root-object?

  • I was about to start writing an answer until I went to the "No trivial god-class refactoring" question, and saw @Kain0_0's answer. Their answer was literally the exact answer I was about to write on this question. What about that answer doesn't address your question? – Greg Burghardt Apr 05 '21 at 13:17
  • @GregBurghardt his answer is more about a general god-class refactoring having a not deleted facade at the end. At this point his answer stops. The question here focus more on that, how a client can use a collaborating object-graph reaching all its functionality (with(if you want) and without a facade and other possibilities), lets say i have a class and i want to add functionality to it (not in that class itself but in a new class), and i want as client get access to that functionality, what kind of compostion i have to choose to achieve that; or what you mean from Kains answer adress my que? – Robin Kreuzer Apr 05 '21 at 13:38
  • Kains0_0's answer does answer your question. – Greg Burghardt Apr 05 '21 at 13:47
  • what kind of his his answer answer my question? – Robin Kreuzer Apr 05 '21 at 13:51
  • I *think* I might know the angle your question is coming from... – Greg Burghardt Apr 05 '21 at 14:15

1 Answers1

1

Since refactoring MyObject to use composition, the downstream impact on clients of MyObject is twofold:

  1. There is no impact. The refactoring was doing internal to MyObject. Clients of MyObject can and should continue calling the methods they used to call. This is the important first step, because this reduces how many files need to be changed.

    At this point you would view MyObject as the beginnings of an anti corruption layer.

  2. Begin refactoring clients of MyObject to use MyObject2. This should not be one giant refactoring job. Instead, split it into distinct tasks focused on refactoring one class, or even just refactoring one method in one class.

Doing this two-step refactoring job for clients of MyObject may allow you to eliminate MyObject as a dependency for other classes. Eventually you will have refactored enough of the application that nobody is calling members of MyObject that just pass through to MyObject2. At that point, you can remove those pass-through methods from MyObject. Once MyObject2 is no longer being used from inside MyObject, you can eliminate MyObject2 from inside MyObject.

When you are done with this two-step refactoring process, clients will be using MyObject2 directly instead of the MyObject methods that pass through to MyObject2.

Greg Burghardt
  • 34,276
  • 8
  • 63
  • 114
  • how to get the functioniality from the origin `MyObject` if the clients at the points only on `MyObject2`, is there then a getterMethod?, if i dont want to make `MyObject` to a facade? What if i want to add more functionality on more classes, Let's say we have a `MyObject3` that needs only functionality of `MyObject` and not `MyObject2`, then i have a problem if the clients points only on a `MyObject2` or on a `MyObject3`, because bothdont know from each other but only from `MyObject` – Robin Kreuzer Apr 05 '21 at 14:47
  • @RobinKreuzer: The last sentence in my answer addressed your question. I rewrote that last sentence to clarify it. – Greg Burghardt Apr 05 '21 at 15:02
  • so you recommend using MyObject2 as a facade for the methods which only MyObject2 have access to from the MyObject1........ yeah this carify your last sentence, thumps up^^ (but still the question, what do you think to have there an getter in MyObject2, do reach MyObject1, not delegating through different facade-methods in MyObject2) – Robin Kreuzer Apr 05 '21 at 16:16
  • in my first comment here i had a second question: what if i have a MyObject3 which depends only on MyObject1 and not on MyObject2? a god-facade in MyObject3 wouldnt be anymore possible, if it has no access to MyObject2, because it has only access to MyObject1, but as client i want to have access to ALL methods from MyObect1, MyObject2, MyObject3 (with only one root-Object)? – Robin Kreuzer Apr 05 '21 at 16:18
  • You will need to provide a *lot* more details about these classes in order to address that question. – Greg Burghardt Apr 05 '21 at 16:36
  • didnt you see my updated question? – Robin Kreuzer Jun 08 '21 at 23:03