Design Problem - Is Inheritance the right way to simplify this code? - c#

I have a design problem I'd like to solve.
I have an interface, lets call it IProtocol, which is implemented by two separate classes. We're looking at over 600 lines of code here. The vast majority of the stuff they do is the same, except for some specific areas, like DiffStuff();
Current structure is something like this:
public class Protocol1 : IProtocol
{
MyInterfaceMethod1()
{
Same1();
DiffStuff();
Same2();
}
}
And
public class Protocol2 : IProtocol
{
MyInterfaceMethod1()
{
Same1();
Same2();
}
}
I'm concerned with having copy-paste errors and the classic problem of code duplication if I keep the two protocols separate. We're talking about a full 600 lines of code each, not some simple methods.
I'm considering changing the implementation of Protocol1 to inherit from protocol2, like this (Protocol2 would mostly stay the same, except I'd have to wrap Same1() and Same2() into private methods.)
public class Protocol1 : Protocol2
{
void Same1()
{
base.Same1();
}
void Same2()
{
base.Same2();
}
MyInterfaceMethod1()
{
Same1();
DiffStuff();
Same2();
}
}
Is this the right way to go about dealing with this problem?
Edit:
Many people helped me with this question, thanks for the clear understanding. In my case, the two objects are not of the same type, even though much of their implementation is shared, so I went with Bobby's suggestion to use abstract base class, creating small methods to encapsulate changes between the classes. Additional Thanks to:
jloubert
Hans Passant
Jeff Sternal

/// <summary>
/// IProtocol interface
/// </summary>
public interface IProtocol
{
void MyInterfaceMethod1();
void Same1();
void Same2();
}
then...
public abstract class ProtocolBase : IProtocol
{
#region IProtocol Members
public void MyInterfaceMethod1()
{
// Implementation elided...
}
public void Same1()
{
// Implementation elided...
}
public void Same2()
{
// Implementation elided...
}
public abstract void DiffStuff();
#endregion
}
finally...
public sealed class Protocol1 : ProtocolBase
{
public override void DiffStuff()
{
// Implementation elided...
}
}
public sealed class Protocol2 : ProtocolBase
{
public override void DiffStuff()
{
// Implementation elided...
}
}

Not quite. There's no point in adding the Same1 and Same2 methods, you inherit them from ProtocolBase. And DiffStuff() should be a virtual method so that you can override it and give it different behavior.

You're awfully close to describing the template method pattern, which has a long pedigree as an effective solution to problems like yours.
However, you should consider using composition instead of inheritance. The two approaches offer different advantages and disadvantages, but composition is often (usually?) better *:
public class Protocol {
private ISpecialHandler specialHandler;
public Protocol() {}
public Protocol(ISpecialHandler specialHandler) {
this.specialHandler = specialHandler;
}
void Same1() {}
void Same2() {}
public void DoStuff() {
this.Same1();
if (this.specialHandler != null) {
this.specialHandler.DoStuff();
}
this.Same2();
}
}
Callers can then pass in object instances (strategies) that provide specialized algorithms to handle whatever case is at hand:
Protocol protocol1 = new Protocol(new DiffStuffHandler());
protocol1.DoStuff();
*See Patterns I Hate #2: Template Method for a detailed explanation of why composition is usually better than inheritance in your case.

You might want to consider whether this type of pattern works:
public class ProtocolHelper
{
public void Same1() {}
public void Same2() {}
}
public class Protocol1 : IProtocol
{
private readonly ProtocolHelper _helper = new ProtocolHelper();
void MyInterfaceMethod1()
{
_helper.Same1();
DiffStuff();
_helper.Same2();
}
}
You can tell if this makes sense by seeing if you can come up with a good name for the 'ProtocolHelper' class. If a name naturally arises from your logic, then this is a good way to break up the class. You might need to pass in some dependencies (such as private fields) as parameters to the methods in order to make this work.

I better design (in my opinion)
public abstract class Protocol_common : IProtocol
{
MyInterfaceMethod1()
{
Same1();
DiffStuff();
Same2();
}
abstract void DiffStuff();
}
public class Protocol1 : Protocol_common
{
DiffStuff()
{
/// stuff here.
}
}
public class Protocol2 : Protocol_common
{
DiffStuff()
{
/// nothing here.
}
}
(That's actually more pseudo-code than proper C#, but I hit the high points)

I agree with MathEpic. I would use Template method pattern.

Related

Choosing allowed methods from Abstract Class

I have an abstract class with methods with logic.
Then i have childs but not all childs can have all methods from the abstract class. I have been thinking of a design pattern that allows me to keep the logic instead of using interfaces but can't think of anyhting other then using a static class with methods. But it would make my code very sloppy.
Another way of formulating my question is: How do i use interfaces with logic in them...
public abstract class Company
{
public virtual void Dowork1()
{
//logic
}
public virtual void Dowork2()
{
//logic
}
public virtual void Dowork3()
{
//logic
}
}
public class ItCompany : Company
{
//DoWork2 NOT callable
}
public class ManagementCompany : Company
{
//DoWork1 NOT callable
}
A pillar of object oriented programming is Liskov substitution principle. In practical terms this means that any implementation of Company need to implement all the methods. I.e. one implementation of a company should be possible to substitute for any other.
You seem to be concerned about implementation inheritance, i.e. allow any of the implementations to reuse the same logic without the need to reimplement it. This can be problematic since it couples the base class to the derived classes. However, you should be able to do what you describe by making the implementations protected.
public abstract class Company
{
protected virtual void DoworkImpl1()
{
//logic
}
protected virtual void DoworkImpl2()
{
//logic
}
protected virtual void DoworkImpl3()
{
//logic
}
}
This lets each implementation define what parts they want to expose:
public class ItCompany : Company
{
public void Dowork1() => DoworkImpl1();
public void Dowork3() => DoworkImpl3();
}
You may also add different interfaces for each type of company if you want to, as shown in other answers. However, if Company does not expose any public methods, you cannot really do anything with a object of the base type, except check what specific type it is, and this is often indicative of a problem in the class design. I would recommend reading Eric Lipperts article on Wizards and Warriors for some perspective.
A possible replacement is to move logic to static methods, for example using extension methods or default interface methods:
public static class CompanyHelpers{
public static void Dowork1(this ICompany company){
// Logic
}
}
This can be very useful with well designed interfaces that expose a minimal set of functions, and provides most extra functionality via extension methods. See LINQ for an example. But it may or may not be applicable in your specific situation.
I think you are looking at the problem from the wrong side. Let me rename your methods to make it more clear.
public abstract class Company
{
public virtual void ManagementWork()
{
//logic
}
public virtual void ItWork()
{
//logic
}
public virtual void BuildCompany()
{
//general logic
}
}
public class ItCompany : Company
{
//ManagementWork NOT callable
}
public class ManagementCompany : Company
{
//ItWork NOT callable
}
It would be better this way
public abstract class Company
{
public virtual void BuildCompany()
{
//general logic
}
}
public class ItCompany : Company
{
public virtual void ItWork()
{
//logic
}
}
public class ManagementCompany : Company
{
public virtual void ManagementWork()
{
//logic
}
}
I guess this is the better way :
interface IDoableWorkOne
{
void DoWork1();
}
interface IDoableWorkTwo
{
void DoWork2();
}
interface IDoableWorkThree
{
void DoWork3();
}
interface ICompany
{
//Other Company Shared Logics
}
public class ManagementCompany: IDoableWorkTwo, IDoableWorkThree, ICompany
{
/// Do your Business
}
public class ItCompany : IDoableWorkOne, IDoableWorkThree, ICompany
{
/// Do Your Business
}
Hope this helps.
Trying to stick with inheritance in such situation makes me think that you are trying to use the wrong tool for your job.
You may achieve code reuse by favoring composition over inheritance and refactor your code as follow:
public sealed class Company
{
public void Dowork1()
{
//logic
}
public void Dowork2()
{
//logic
}
public void Dowork3()
{
//logic
}
}
public sealed class ItCompany
{
private readonly Company _company;
public ItCompany(Company company) => _company = company;
//Call DoWork1 and DoWork3 whenever you want from _company
}
public sealed class ManagementCompany
{
private readonly Company _company;
public ManagementCompany (Company company) => _company = company;
//Call DoWork2 and DoWork3 whenever you want from _company
}
This code has the same benefits of code reuse than inheritance but without the burden of trying to hide normally public inherited methods.
Also you can be sure that no one ever can alter Company's behavior (such a central piece of logic for you) since the class is sealed, unlike solutions trying to stick with inheritance that allow overriding DoworkX() methods.

Pass-through constructors from its base class

An external framework has the following classes:
public class Boatmaker
{
}
public class Wood
{
}
public class Axe
{
}
public class Lake
{
}
public class Boat
{
public Boat(Wood wood, Axe axe) {
}
public Boat (Boatmaker maker) {
}
public Boat (Lake lake) {}
}
I need to do a lot of subclassing of Boat. For each of my subclasses, I have to assume that the external framework may want to instantiate it via any of the above constructors. So my subclasses get pass-through constructors. Notice how they never go away:
public class SmallBoat: Boat
{
public void DoSmallBoatStuff() {
// some code here
}
private void Initialize() {
this.DoSmallBoatStuff();
}
public SmallBoat(Wood wood, Axe axe): base(wood, axe) {
this.Initialize();
}
public SmallBoat (Boatmaker maker): base(maker) {
this.Initialize();
}
public SmallBoat (Lake lake): base(lake) {
this.Initialize();
}
}
public class Canoe: SmallBoat
{
public void DoCanoeStuff() {
// some code here
}
private void Initialize() {
this.DoCanoeStuff();
}
public Canoe(Wood wood, Axe axe): base(wood, axe) {
this.Initialize();
}
public Canoe (Boatmaker maker): base(maker) {
this.Initialize();
}
public Canoe(Lake lake): base(lake) {
this.Initialize();
}
}
I am wondering if there is a way to simplify the appearance of the code. The only difference between the way the constructors are written in SmallBoat and Canoe is the word SmallBoat or Canoe. Everything else is the same.
So if there were a way to write a constructor without actually using the name of the class in the constructor, it would help a lot. I could use direct copy and paste without a .tt file (which is not really viable for me -- most of my work is not done in Visual Studio). Is there a way to do that?
No. There is not. You have to specify which constructors of the base class you want to make available from the current class. There is no way to write the constructor without mentioning the real class name.
It might be a simplification you are showing, but if Initialize is the only method called, you might want to move that call to the base class calling a protected Initialize method you can override from the implementing classes. (You have to take in consideration the order of calling that method and instantiating properties/fields. You can run into trouble there, so it might not be viable in your situation)
1. Automation of code typing
There is code snippet : ctor that helps create "only" default constructor.
To use it type ctor an tabulation twice.
The original code snippet can be copied to create your own.
In Visual Studio, go in Tools menu/Code snippet manager.
You can see here the directories of the snippet files.
You can copy a snippet ( ctor.snippet for instance ) to "My Code Snippets", rename it and edit.
2. Design of the boat hierarchy
The boat hierarchy can also be designed so there is only a default constructor in the base class, and you have public properties or public method(s) in the base class to provide Lake, Axe, BoatMaker, ...
If you can change the design, I highly recommend separate object instantiation from the object itself. This way, the Factory Method combining with Template Method design pattern comes very helpful:
public abstract class BoatFactory
{ protected abstract void Initialize();
protected Wood Wood;
protected Axe Axe
protected Boatmaker Boatmaker ;
public Boat MakeBoat(Wood wood, Axe axe)
{
this.Wood = wood;
this.Axe = axe;
Initialize();
}
public Boat MakeBoat(Boatmaker maker)
{
this.Boatmaker = Boatmaker ;
Initialize();
}
public Boat MakeBoat(Lake lake)
{
this.Lake = lake;
Initialize();
}
}
public class SmallBoatFactory : BoatFactory
{
protected override void Initialize()
{
// do customized init operations here
}
}

Interface vs Class : Defining methods [duplicate]

This question already has answers here:
Interface vs Base class
(38 answers)
Closed 8 years ago.
I'm a bit new to OO programming and I'm trying to understand all facets of this kind of practice : inheritance, polymorphism and such, but there's a thing my brain DOESN'T WANT to fully understand: Interfaces.
I can understand the benefits of using interfacing instead of class-inheritance (mostly because a class can't inherit from multiple parents) but here's where I'm stuck:
Let's say I have something like this:
/** a bunch of interfaces **/
public interface IMoveable
{
void MoveMethod();
}
public interface IKilleable()
{
void KillMethod();
}
public interface IRenderable()
{
void RenderMethod();
}
/** and the classes that implement them **/
public class ClassOne : IMoveable
{
public void MoveMethod() { ... }
}
public class ClassTwo: IMoveable, IKilleable
{
public void MoveMethod() { ... }
public void KillMethod() { ... }
}
public class ClassThree: IMoveable, IRenderable
{
public void MoveMethod() { ... }
public void RenderMethod() { ... }
}
public class ClassFour: IMoveable, IKilleable, IRenderable
{
public void MoveMethod() { ... }
public void KillMethod() { ... }
public void RenderMethod() { ... }
}
By using interfaces here, I would have to declare MoveMethod, KillMethod and RenderMethod each time, in each classes... That means duplicating my code. There must be something wrong, because I don't find this really practical.
So should I implement interfaces only on a few classes? Or should I find a way to mix inheritance and interfaces?
Interfaces are like a contract to a class.. If some class states that it supports such an interface, it must have it's method defined as you properly sampled. Interfaces are great to expose common things that don't easily cross different class implementations.
Now, from your samples, you may be best to do a combination to prevent duplicate code by subclassing from a class and ALSO an interface. So you can get parent-structure code constant and expand as needed.
/** Based on same interfaces originally provided... and the classes that implement them **/
public class ClassOne : IMoveable
{
public void MoveMethod() { ... }
}
public class ClassTwo: ClassOne, IKilleable
{
// Move Method is inherited from ClassOne, THEN you have added IKilleable
public void KillMethod() { ... }
}
public class ClassThree: ClassOne, IRenderable
{
// Similar inherits the MoveMethod, but adds renderable
public void RenderMethod() { ... }
}
public class ClassFour: ClassTwo, IRenderable
{
// Retains inheritance of Move/Kill, but need to add renderable
public void RenderMethod() { ... }
}

Call abstract method from abstract class constructor

I would like to ask what are the risks of having something as follows:
abstract public class HtmlTemplateBuilder
{
HtmlSource source;
protected HtmlTemplateBuilder()
{
LoadTemplates();
}
public abstract void LoadTemplates();
}
The risk is if a derived class derives from the derived class:
DerivedClass2 -> #DerivedClass1 -> HtmlTemplateBuilder
This can be solved by sealing #DerviedClass1, but are there any more risks or better practices for implementing this functionality?
Thanks
The situation in which this pattern bit me is as follows: at some later stage you want to add a specialized HtmlTemplateBuilder, which can load different templates based on some criteria unknown to the class itself (maybe you decide you want some cool templates on a specific day of the year). That is:
public class SpecialHtmlTemplateBuilder : HtmlTemplateBuilder
{
private bool someCondition;
public override void LoadTemplates()
{
if (someCondition)
{
LoadTemplatesSet1();
}
else
{
LoadTemplatesSet2();
}
}
}
But how are you going to pass someCondition to the class? The following won't work:
public class SpecialHtmlTemplateBuilder : HtmlTemplateBuilder
{
private bool someCondition;
public SpecialHtmlTemplateBuilder (bool someCondition)
{
this.someCondition = someCondition;
}
// ...
}
because the assignment of this.someCondition will be done after calling the base constructor, i.e., after LoadTemplates() is called. Note that sealing derived classes does not solve this problem.
The way to solve this is as #Rahul Misra described: add an explicit Initialize method and call that after the constructor.
Have a look at this link which explains the perils with simple easy to understand examples
https://blogs.msmvps.com/peterritchie/2012/04/25/virtual-method-call-from-constructor-what-could-go-wrong/
I would remove the call to LoadTemplates from constructor and call Initialise on it when the templates actually need to be loaded and used.
abstract public class HtmlTemplateBuilder
{
HtmlSource source;
object locker = new object();
private bool initialised;
protected HtmlTemplateBuilder()
{
}
protected void Initialise()
{
lock (locker)
{
if(initialised)
{
LoadTemplates();
initialised = true;
}
}
}
public abstract void LoadTemplates();
}

How can I factor out the code duplication here?

So, I'd like to hear what you all think about this.
I have a project where three different inheritance paths need to all implement another base class. This would be multiple inheritance and isn't allowed in C#. I am curious how I can implement this without code duplication.
EDIT: I don't own the three classes. The three classes are from 3rd party code. So I cannot make them all extend my base class.
Right now I am using three different classes, each one extending a different base class. Then I have the same code in each of the three abstract classes.
I could use a single interface, but I would still need to duplicate the code.
I could make some kind of static class that implements the code and then reference that in each of the 3 abstract classes. It would eliminate the duplication, but, I am not sure how I feel about this. I could implement Extensions methods on the interface, but then the interface itself would be empty and the extension methods (containing the duplicate code) would be in a totally different file, which seems not quite right. Plus I can't implement properties in extension methods...
How can I factor out the code duplication here?
EDIT, inheritance tree:
class Class1 : 3rdPartyBaseClass1 { }
class Class2 : 3rdPartyBaseClass2 { }
class Class3 : 3rdPartyBaseClass3 { }
I have code I want to be in each of the above Classes, but I cannot add it to the 3rdPartyClasses.
Create an interface that Class1, Class2, and Class3 can implement. Then put your code in extension methods so it will apply to all.
interface IMyInterface {
void Foo(); //these are the methods that these
//classes actually have in common
void Bar();
}
public class Class1 : 3rdPartyBaseClass1, IMyInterface {
// whatever
}
public static class IMyInterfaceExtensions {
public static void CommonMethod(this IMyInterface obj) {
obj.Foo();
obj.Bar();
}
}
public static class Program {
public static void Main() {
var instance = new Class1();
instance.CommonMethod();
}
}
OK, you can do something similar to my previous suggestion, and also similar to recursive's suggestion. For the functionality you require in all three of your derived classes, you can create a single Interface along with a single class (call it "Implementer" for kicks) that implements that Interface (and that has the actual code you want executed with each call).
In each of your derived classes, then, you implement the Interface and create a private instance of Implementer. In each of the interface methods, you just pass the call along to the private instance of Implementer. Because Implementer and your derived classes all implement your Interface, any changes you make to the Interface will require you to modify Implementer and the derived classes accordingly.
And all your code is in one place, except for all the lines passings the calls on to the private instance of Implementer (obviously multiple inheritance would be better than this, but you go to war with the army you have, not the army you wish you had).
Update: what about just adding a public instance of your class to each of the derived classes?
public class DerivedClass1 : ThirdPartyClass1
{
public MyClass myClass = new MyClass();
}
Or if you care who Demeter is and you get paid by LOC:
public class DerivedClass1 : ThirdPartyClass1
{
private MyClass _myClass = new MyClass();
public MyClass myClass
{
get
{
return _myClass;
}
}
}
Then you'd just call the MyClass methods like this:
DerivedClass1 dc1 = new DerivedClass1();
dc1.myClass.DoSomething();
This way, we could all go to sleep.
Similar to MusiGenesis's suggestion, if you need the functionality of the 3rd party classes but do not have to descend from them, you could use composition as follows:
class ThirdPartyBaseClass1
{
public void DoOne() {}
}
class ThirdPartyBaseClass2
{
public void DoTwo() { }
}
class ThirdPartyBaseClass3
{
public void DoThree() { }
}
abstract class Base
{
public void DoAll() { }
}
class Class1 : Base
{
public void DoOne() { _doer.DoOne(); }
private readonly ThirdPartyBaseClass1 _doer = new ThirdPartyBaseClass1();
}
class Class2 : Base
{
public void DoTwo() { _doer.DoTwo(); }
private readonly ThirdPartyBaseClass2 _doer = new ThirdPartyBaseClass2();
}
class Class3 : Base
{
public void DoThree() { _doer.DoThree(); }
private readonly ThirdPartyBaseClass3 _doer = new ThirdPartyBaseClass3();
}
This also gives you the freedom to define whatever interfaces you want and implement them on your classes.
Sounds like you need to insert the new abstract class into the inheritance tree at whatever point those three paths come together, but there really isn't enough information to tell. If you could post some of your inheritance tree, that would help a lot.
I think you may want to use composition instead of inheritance. Exactly how to do this depends on what the third party classes look like, and what your own code looks like. Some more specific code relating to your problem would be helpful, but for example, suppose you want to have three different third party GUI widgets that all need to be customized with your own initializer code.
Case 1: Suppose your third party widgets look like:
public interface IThirdPartyWidget {
public void doWidgetStuff();
}
public class ThirdPartyWidget1: ThirdyPartyWidget implements IThirdPartyWidget {
...
}
public class ThirdPartyWidget2: ThirdPartyWidget implements IThirdPartyWidget {
...
}
You can do:
public class MyWidget implements IThirdPartyWidget {
private IThirdPartyWidget delegateWidget;
public MyWidget(IThirdPartyWidget delegateWidget) {
this.delegateWidget = delegateWidget;
}
public void doWidgetStuff() {
delegateWidget.doWidgetStuff();
}
}
Case 2: Suppose you absolutely need to extend those widgets, and you have to refactor your own code:
public class MyWidget1: ThirdPartyWidget1 {
public void myMethod() {
runMyCode();
}
private void runMyCode() {
//something complicated happens
}
}
public class MyWidget2: ThirdPartyWidget2 {
public void myMethod() {
runMyCode();
}
private void runMyCode() {
//something complicated happens
}
}
This can become:
public class MyCodeRunner {
public void runMyCode() {
//...
}
}
public class MyWidget1: ThirdPartyWidget1 {
private MyCodeRunner myCode = new MyCodeRunner();
public void myMethod() {
myCode .runMyCode();
}
}
public class MyWidget2: ThirdPartyWidget2 {
private MyCodeRunner myCode = new MyCodeRunner();
public void myMethod() {
myCode .runMyCode();
}
}
Hope this makes sense!

Categories