Naor
Naor

Reputation: 24063

how to solve this code duplication + add another method

I have 3 classes:

class First {
    public void SetA(){ ... }
    public void SetB(){ ... }
    public void SetC(){ ... }
    public void SetD(){ ... }
    public void SetZ(){ ... }
}

class Second {
    public void SetC(){ ... }
    public void SetD(){ ... }
    public void SetE(){ ... }
    public void SetF(){ ... }
    public void SetX(){ ... }
}

class Third{
    public void SetA(){ ... }
    public void SetB(){ ... }
    public void SetE(){ ... }
    public void SetF(){ ... }
    public void SetY(){ ... }
}

As you can see, I duplicate code in the same methods.
Yesterday I realized that sometimes I would like to add another commend inside each method.
So I am looking for a way to solve both those problems. One solution I thought about is:

  1. Create Interface:

    interface IAllMethods {
            void SetA();
            void SetB();
            void SetC();
            void SetD();
            void SetE();
            void SetF();
            void SetX();
            void SetY();
            void SetZ();
    }
    
  2. Create default implementation:

    class DefaultAllMethods {
            public void SetA(){ ... }
            public void SetB(){ ... }
            public void SetC(){ ... }
            public void SetD(){ ... }
            public void SetE(){ ... }
            public void SetF(){ ... }
            public void SetX(){ ... }
            public void SetY(){ ... }
            public void SetZ(){ ... }
    }
    
  3. Create another implementation using decorator pattern in order to add the extra command:

    class ExtraAllMethods {
            private IAllMethods _allMethods;
            public ExtraAllMethods (IAllMethods allMethods) {
                _allMethods=allMethods;
            }
            public void SetA(){ 
                _allMethods.SetA();
                extraMethod();
            }
            public void SetB(){ 
                _allMethods.SetB();
                extraMethod();
            }
            public void SetC(){ 
                _allMethods.SetC();
                extraMethod();
            }
            ..
            ..
            ..
    }
    
  4. Use the desire implementation inside classes First, Second and Third. For example:

    class Third{
        private IAllMethods  _allMethods;
        public Third(IAllMethods allMethods) {
            _allMethods=allMethods;
        }
        public void SetA(){ _allMethods.SetA(); }
        public void SetB(){ _allMethods.SetB(); }
        ..
        ..
        ..
    }
    

What do you think about this solution? Is there any better design to this need?

UPDATE
People ask for the real business, so here is it: I have 3 types of transmission: TransmissionA, TransmissionB, TransmissionC Each transmissions has many parameters (members or properties). For example, TransmissionA has WorkerId, CustomerId, MessageName and so on. TransmissionB has WorkerId and MessageName but no CustomerId. TransmissionC has WorkerId, CustomerId but no MessageName. These are example only - in my situation I have many more properties for each transmission. Each property has Set method.
Now there is a new need. Somewhere on the system there is an option called "Update Task". If the option is ON then I need to update relevant task in each Set method. This is why I thought on decorator pattern.

Upvotes: 2

Views: 165

Answers (4)

sll
sll

Reputation: 62494

Depends on what those methods are doing, so solutions could be different. But if these methods are not tied one to an other somehow logically I would suggest to abstract each method by an interface like

    interface ILogicBAware
    {
      void DoB();
    }

    interface ILogicCAware
    {
      void DoC();
    }

    interface IAllMethods : ILogicBAware, ILogicCAware
    {
       void DoAll();
    }

In this way you get much flexibility and less coupling. In this way you can move forward and decide how actual logic will be encapsulated. But again it depends of what is under the hood of classes and methods you've provided...

Upvotes: 0

Michael Sagalovich
Michael Sagalovich

Reputation: 2549

You could define an interface for each single method and default implementation for each interface and make your classes implement only needed interfaces and be parameterized via constructor with default implementations to decorate.

Upvotes: 0

mtijn
mtijn

Reputation: 3678

this will work but instead of introducing all-knowing interface and base implementation classes containing all methods (and thus having knowledge of the entirety of your collection of methods) you could also go for a more granular approach and just make a single interface and base implementation for each method. That would be more extensible and you could attach those just as easy in a plugin-like fashion if you set it up properly.

Upvotes: 0

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174299

  1. The interface is no good idea, because its implementors only provide functionality for a sub set of the methods provided by the interface.
  2. The decorator pattern can't be used here, because it is used to add functionality, it can't be used to change the API like adding methods. See this answer for more info.
  3. If you have the same method with the same code in different classes, this should be extracted into its own class and used by the others. Currently, your classes most likely violate the single responsible principle.

Upvotes: 2

Related Questions