Design pattern to use instead of multiple inheritance

后端 未结 8 2525
离开以前
离开以前 2020-12-09 03:16

Coming from a C++ background, Im used to multiple inheritance. I like the feeling of a shotgun squarely aimed at my foot. Nowadays, I work more in C# and Java, where you can

相关标签:
8条回答
  • 2020-12-09 03:30
    public interface  IMagician{ /* declare here all the getter/setter methods that you need; they will be implemented both in TypeA and TypeB, right? */ }
    
    public static class MyExtensions {
      public static void doMagic(this IMagician obj)
      { 
               // do your magic here
      }
    }   
    

    Now, the problem is if you REALLY need to use private properties/methods (as opposed to "internal" ones), this approach won't work. Well, actually, you may be able to do your magic if you can read those properties through reflection, but even if it works, it's a rather ugly solution :)

    [Note that "doMagic" will automatically appear to become a part of TypeA and TypeB,simply because you implement IMagician - there is no need to have any implementation there ]

    0 讨论(0)
  • 2020-12-09 03:31
    • In .Net, you can have extension methods apply to interfaces. It's really neat when it's possible, and applicable for you because it's a rare way to apply a common implementation to an interface. Certainly consider it, but it might not work for you since you say that DoMagic works with a lot of Private members. Can you package these private variables internal possibly? This way the extension method could access them.
    • Have the common functionality in another class. If there's a logical place to put this common functionality, pass your objects to this other class method (perhaps this is UI functionality, and you already have a UI helper . . .). Again, can you expose the private data with an internal/public property? (Security/encapsulation is a concern in all this of course. I don't know if your classes are for internal use only or will be exposed publicly.)
    • Otherwise, pass a separate functionality class (or specific function pointer) into the interface-defined method. You would have to have a little bit of duplicated code to pass your private variables to this external function reference, but at least it wouldn't be much, and your implementation would be in one place.
    • We might be making this too complicated. It won't make you feel all object-oriented when you go to sleep tonight, but could you have a static routine in your library somewhere that all IMagician implementers call?
    • In the end, Adapter might indeed be what you're looking for. Less likely but still worth consideration is the Decorator pattern.

    If nothing seems particularly good, pick what feel best, use it a couple times, and rearrange tomorrow. :)

    0 讨论(0)
  • 2020-12-09 03:40

    Replace inheritance with composition.

    Move your 'common' function to separate class, create an instance of that class, and insert it to TypeA object and to TypeB object.

    0 讨论(0)
  • 2020-12-09 03:42

    You can use the strategy pattern or something like it to use has a (composition) instead of is a (inheritance):

    public class TypeA : CustomButtonUserControl, IMagician {
        IMagician magicObj = new Magical();
        public void DoMagic() {
            magicObj.DoMagic();
        }
    }
    
    public class TypeB : CustomButtonUserControl, IMagician {
        IMagician magicObj = new Magical();
        public void DoMagic() {
            magicObj.DoMagic();
        }
    }
    
    public class Magical : IMagician {
        public void DoMagic() {
            // shared magic
        }
    }
    

    There are other ways to instantiate your private IMagician members (such as passing them as a param via constructor) but the above should get you started.

    0 讨论(0)
  • 2020-12-09 03:43

    You can use composition to have magician as a property of typeA and typeB

    class Magician : IMagician
    {
        public void DoMagic()
        {}
    }
    
    Class TypeA : CustomButtonUserControl
    {
       //property
       Magician magicianInTypeA
    }
    
    Class TypeB : CustomTextUserControl
    {
        //property
        Magician magicianInTypeB
    }
    
    0 讨论(0)
  • 2020-12-09 03:44

    The composite pattern is meant for complex objects, that means the focus is on one object being made up of other objects. The strategy-pattern can be regarded as a special case of that, but a strategy does not have to be an object. I think this would apply more to your case. Then again, this heavily depends on the nature of what DoMagic() does.

    0 讨论(0)
提交回复
热议问题