How can a variant of the Template Method pattern be implemented whereby the concrete class does not inherit from the base class, but the overall feature of the pattern is maintained. The reason it cannot inherit is that it's forced to inherit from another class and multiple-inheritance is unavailable.
For example, suppose the following Tempate Method pattern:
public abstract class BaseClass {
public void Alpha() {
Beta();
}
public abstract void Beta();
public void Gamma() {
Delta();
}
public abstract void Delta();
}
public ConcreteClass : BaseClass {
public override void Beta() {
Gamma();
}
public override void Delta() {
Console.WriteLine("Delta");
}
}
...
var object = new ConcreteClass();
object.Alpha(); // will outout "Delta"
How can I achieve the same result without ConcreteClass inheriting BaseClass?
Your base class could depend on an interface (or other type) that's injected via the constructor. Your template method(s) could then use the methods on this interface/type to achieve the pattern's desired outcome:
public class BaseClass
{
IDependent _dependent;
public BaseClass(IDependent dependent)
{
_dependent = dependent;
}
public void Alpha() {
_depdendent.Beta();
}
public void Gamma() {
_depdendent.Delta();
}
}
Effectively using composition rather than inheritance.
You can achieve this by providing a reference to the base class on method call:
public ConcreteClass {
public void Beta(BaseClass baseClass) {
baseClass.Gamma();
}
public void Delta() {
Console.WriteLine("Delta");
}
}
Related
I've been trying to apply SOLID principles more consciously on my current project. Using interfaces to create the abstraction and allowing classes that are handling the dependency injection to provide the concretions has really helped with decoupling some of the code and (hopefully!) making it more maintainable in the long run.
However, here and there I'm hitting a bit of a wall where it seems neither interfaces nor abstract classes work for the reason that there are functions for which I want an implementation defined.
This means:
Interfaces will not work since I can't define an implementation and obviously don't want to repeat the code in all implementing classes
Abstract classes will not work because I cannot derive from multiple classes
Some super simple code to illustrate the problem:
public abstract class Vehicle
{
public void MoveForward()
{
// Some code here
// This implementation is always the same
}
public abstract void PerformUniqueAbility(); // This is for the derived class to implement
}
public abstract class RadioSignalBroadcaster
{
public void StartBroadcast()
{
// Some code here
// This implementation is always the same
}
public abstract void PerformUniqueBroadcastingAbility(); // This is for the derived class to implement
}
Now of course what I'd like to do is this:
public class MyNewClass: Vehicle, RadioSignalBroadcaster
{
// Class that contains the implementations for both MoveForward() AND StartBroadcast() but also allows me to define
// bodys for the abstract methods
public override void PerformUniqueAbility()
{
// class specific code here
}
public override void PerformUniqueBroadcastingAbility()
{
// class specific code here
}
}
Of course I cannot do this because of the error:
Error CS1721 Class 'MyNewClass' cannot have multiple base classes: 'Vehicle' and 'RadioSignalBroadcaster'
What's the best way to approach these scenarios?
You could use interfaces with default implementations which were introduced in C# 8. Then you could derive from these interfaces.
Here's an example of how you could you provide default implementations for the MoveForward() and StartBroadcast() methods:
public interface IVehicle
{
void MoveForward()
{
// your code
}
void PerformUniqueAbility();
}
public interface IRadioSignalBroadcaster
{
void StartBroadcast()
{
// your code
}
void PerformUniqueBroadcastingAbility();
}
You can't inherit more than 1 class but you can inherit more than one interface. Is this what you are looking for?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3
{
internal class Program
{
static void Main(string[] args)
{
IVehicle vehicle = new Vehicle();
IRadioBroadcaster broadcaster = new RadioBroadcaster();
vehicle.MoveForward();
vehicle.PerformUniqueAbility();
broadcaster.StartBroadcast();
broadcaster.PerformUniqueAbility();
}
}
public interface IUniqueAbillity
{
void PerformUniqueAbility();
}
public interface IVehicle: IUniqueAbillity
{
void MoveForward();
}
public interface IRadioBroadcaster : IUniqueAbillity
{
void StartBroadcast();
}
public abstract class RealWorldObject : IVehicle, IRadioBroadcaster
{
public void MoveForward()
{
// Move forward
}
public abstract void PerformUniqueAbility();
public void StartBroadcast()
{
// Start broadcast
}
}
public class Vehicle : RealWorldObject, IVehicle
{
public override void PerformUniqueAbility()
{
// Do something
}
}
public class RadioBroadcaster : RealWorldObject, IRadioBroadcaster
{
public override void PerformUniqueAbility()
{
// Do something
}
}
}
C# classes can only inherit from one base class, but can inherit from any number of interfaces.
If your goal is to have multiple base classes being inherited to MyNewClass, you could change one of your abstract classes to inherit from the other, for example:
public abstract class RadioSignalBroadcast : Vehicle
{
// Implementation goes here
}
public class MyNewClass : RadioSignalBroacast
{
// Implementation goes here
}
However, as you can see from this approach, it violates Single Responsibility Principle as now RadioSignalBroadcast (and now MyNewClass) has more than one reason to change (if there's a change to Vehicle or RadioSignalBroadcast logic). Any change that happens to any of the base classes will propagate to all other classes which inherit from those base classes, which may or may not be what you're after.
What's the best way to approach these scenarios?
That entirely depends on the design of your application. Questions to ask yourself:
Do you require Vehicle and RadioSignalBroadcast to be abstract classes, or can it easily be an interface? By the looks of your implementation, you have a couple of methods which you want to share to your derived classes so I understand you wanting to keep them as base classes, but it's something to keep in mind. Also check out if the implementation of MoveForward and StartBroadcast can have a default interface implementation.
Does MyNewClass need to implement both base classes/interfaces? Couldn't two separate classes work out better? Separating out classes like this helps to focus each of the classes to have one single responsibility.
If MyNewClass is not truly a Vehicle or a RadioSignalBroadcast (as per the previous point), can this object be composed by a combination of either of the two, for example:
public class MyNewClass : Vehicle
{
private readonly RadioSignalBroadcast radio;
public MyNewClass(RadioSignalBroadcast radio)
{
this.radio = radio;
}
public void DoStuff()
{
// Do Stuff
this.radio.PerformUniqueBroadcastingAbility();
}
// Implementation goes here
}
Let me know if you want example or more points to point out.
I think Jonas gave you the best answer that you can use default interface implementations. However I keep my post, because it gives information, how to achieve same effect, using technology without this language feature.
public abstract class Example : IExample
{
private readonly IVehicle vehicle;
private readonly IRadioSignalBroadcaster;
public Example(IVehicle vehicle, IRadioSignalBroadcaster radioSignalBroadcaster)
{
this.vehicle = vehicle;
this.radioSignalBroadcaster = radioSignalBroadcaster;
}
public void MoveForward() => vehicle.MoveForward();
public void StartBroadcast() => radioSignalBroadcaster.StartBroadcast();
public void PerformUniqueAbility() => vehicle.PerformUniqueAbility();
public void PerformUniqueBroadcastingAbility() => radioSignalBroadcaster.PerformUniqueBroadcastingAbility();
}
public interface IExample : IVehicle, IRadioSignalBroadcaster
{
}
public interface IVehicle
{
void MoveForward();
void PerformUniqueAbility();
}
public interface IRadioSignalBroadcaster
{
void StartBroadcast();
void PerformUniqueBroadcastingAbility();
}
public abstract class Vehicle : IVehicle
{
public void MoveForward()
{
// ...
}
public abstract void PerformUniqueAbility();
}
public interface ICustomVehicle : IVehicle
{
}
public class CustomVehicle : Vehicle, ICustomVehicle
{
public void PerformUniqueAbility()
{
// ...
}
}
public abstract class RadioSignalBroadcaster : IRadioSignalBroadcaster
{
public void StartBroadcast()
{
// ...
}
public abstract void PerformUniqueBroadcastingAbility();
}
public interface ICustomRadioSignalBroadcaster : IRadioSignalBroadcaster
{
}
public class CustomRadioSignalBroadcaster : RadioSignalBroadcaster, ICustomRadioSignalBroadcaster
{
public void PerformUniqueBroadcastingAbility()
{
// ...
}
}
You will create another classes like that:
public class CustomExample : Example, ICustomExample
{
public CustomExample(ICustomVehicle customVehicle, ICustomRadioSignalBroadcaster customRadioSignalBroadcaster) : base(customVehicle, customRadioSignalBroadcaster)
{
}
}
public interface ICustomExample : IExample
{
}
I don't know how to use a dependency injection in an abstract class. Let me show you my problem in a simple example:
public abstract class Animal {
public abstract void Move();
public void Sleep()
{
restService.StartSleeping(1000); //how to get this service here?
}
}
public class Cat : Animal
{
public readonly IMotionService _motionService;
public Cat(IMotionService motionService)
{
_motionService = motionService;
}
public override void Move()
{
_motionService.Run();
}
}
public class Bird : Animal
{
public readonly IMotionService _motionService;
public Bird(IMotionService motionService)
{
_motionService = motionService;
}
public override void Move()
{
_motionService.Fly();
}
}
Every animal move in different way so the Move() function is implemented separately in every derived class. As you probably noticed the whole implementation comes from the motionService.
On the other hand all animals sleep in same way, so I want put the Sleep() implementation in a base abstract class to avoid a duplication code, but I can't use my restService with a Sleep implementation because I don't have idea how to inject a service class into an abstract class.
I thought about IServiceProvider but it should be injected too.
You pass it down like this:
public abstract class Animal
{
private readonly IRestService restService;
public Animal( IRestService restService )
{
this.restService = restService;
}
public abstract void Move();
public void Sleep()
{
restService.StartSleeping(1000);
}
}
public class Cat : Animal
{
// vv Should be private!
public readonly IMotionService _motionService;
public Cat(IMotionService motionService,
IRestService restService)
: base(restService) // pass on to base class ctor
{
_motionService = motionService;
}
public override void Move()
{
_motionService.Run();
}
}
// Same in `Bird` class
For reference: Using Constructors (C# Programming Guide)
I have a base ViewModel that has a public method. Things were pretty simple at first and its role was the same for all of its derived classes, but now we want the ViewModel to do different things depending on which derived class calls it.
So for example we have:
public void DoMethod()
{
DoThisMethod();
}
we want something like
public void DoMethod()
{
if (this.GetType().Name == "ThisName")
DoThisMethod();
else
DoAnotherMethod();
}
Is it wrong to do this?
This is a perfect scenario for using Method Overriding.
You should be using OOP concept of method overriding here:
public class BaseViewModel
{
public virtual void DoMethod()
{
DoThisMethod();
}
}
and now when you inherit some class from BaseViewModel, you can define different implement of DerivedViewModel using overrding:
public class DerivedViewModel:BaseViewModel
{
public override void DoMethod()
{
// implementation here
}
}
Now when you will call it using DerivedViewModel object it will the implementation of DoMethod() defined in DerviedViewModel type.
If you don't have access to implementation of BaseViewModel then you will have to use Shadowing Concept:
public class BaseViewModel
{
public void DoMethod()
{
DoThisMethod();
}
}
and in Derived Type:
public class DerivedViewModel:BaseViewModel
{
public new void DoMethod()
{
DoThisMethod();
}
}
But generally it is not considered good to use Shadowing.
You may read more about method overriding in this article
Yes, the solution that you propose is wrong for a design point of view. Your base class should be agnostic of the inherited type "ThisName". Using your naming you could resolve your problem by implementing it in this way:
public class ViewModel
{
public virtual void DoMethod()
{
DoAnotherMethod();
}
public void DoAnotherMethod() {...}
}
public class ThisName: ViewModel
{
public override void DoMethod()
{
DoThisMethod();
}
public void DoThisMethod() {...}
}
I am trying to create a comprehensive abstract BaseClass that defines the way in which all derived classes are created, but allows derived classes to specialize/aggregate the fields and methods used in the creation process. Here is a simplified example:
public abstract class BaseClass
{
public List<String> list;
public BaseClass()
{
defineList();
optionalDoSomething();
doSomething();
}
protected void defineList()
{
list = new List<String>();
}
protected void doSomething()
{
// do something w/ list here
}
protected void optionalDoSomething() {}
}
public class DerivedClass : BaseClass
{
protected void defineList()
{
base.defineList();
list.Add("something");
}
public DerivedClass() : base() { }
}
public class SecondDerivedClass : DerivedClass
{
protected void defineList()
{
base.defineList();
list.Add("somethingElse");
}
protected void optionalDoSomething()
{
// do something special
}
public SecondDerivedClass() : base() { }
}
This would free all derived classes from having to recreate the same initialization logic, and each derived class would only need to "overwrite" the necessary fields and methods used in the create process (and possibly elsewhere in the class).
The problem:
I cannot mark BaseClass' methods as virtual since you cannot call virtual methods in a base constructor (in any case, I would not want to use virtual methods since, for example, I would not want DerivedClass to use SecondDerivedClass' defineList method).
I can mark them abstract, but then I would not be able to put "default implementations" in BaseClass and each derived class would have to replicate/implement those defaults. Also, SecondDerived class would still need a way to "override" the implementations of DerivedClass.
It does not work to simply use the new key word "hide" less derived class' methods.
What is the correct way to obtain this pattern?
TLDR: as per my comment below:
If BaseClass is an abstract class with method A, and DerivedClass is a class derived from BaseClass (not necessarily a direct child of BaseClass), then calling A in BaseClass' constructor should call A() in every class in the inheritance hierarchy up to and including DerivedClass (but no further). We can assume that A (forced to be) defined on every intermediate class.
I think that you should refer to template-method-design-pattern
Define the skeleton of an algorithm in an operation, deferring some
steps to subclasses. Template Method lets subclasses redefine certain
steps of an algorithm without changing the algorithm's structure.
you can try something similar to this
abstract class AbstractClass
{
public List<String> list;
public abstract void PrimitiveOperation1();
public void TemplateMethod()
{
//initialize code that each class should perform
PrimitiveOperation1();
}
}
class DerivedClass: AbstractClass
{
public override void PrimitiveOperation1()
{
list.Add("something");
}
}
usage
AbstractClass abstractClass1 = new DerivedClass();
abstractClass1.TemplateMethod();
Try this solution, the implementation is implemented with protected virtual methods, so its not visible from the outside and not required in derived classes:
public abstract class BaseClass
{
public List<String> List { get; protected set; }
protected BaseClass()
{
defineList();
optionalDoSomething();
doSomething();
}
protected void defineList()
{
// default implementation here
List = new List<String>();
internalDefineList();
}
protected void doSomething()
{
// default implementation here
internalDoSomething();
}
protected void optionalDoSomething()
{
// default implementation here
internalOptionalSomething();
}
protected virtual void internalDefineList()
{
}
protected virtual void internalDoSomething()
{
}
protected virtual void internalOptionalSomething()
{
}
}
public class DerivedClass : BaseClass
{
protected override void internalDefineList()
{
var list = List;
}
protected override void internalDoSomething()
{
}
// this method is not required
/*
protected override void internalOptionalSomething()
{
}
*/
}
One way to achieve what you want is to add an explicit Initialize method to the base class and do the initializaiton logic there, e.g:
public abstract class BaseClass
{
public List<String> list;
public BaseClass()
{
}
public void Initialize()
{
defineList();
optionalDoSomething();
doSomething();
}
}
using System;
public class Base
{
public Base()
{
}
public void M1()
{
}
public void M2()
{
}
public void M3()
{
}
}
public class Derived : Base
{
//this class should get only method 1
}
public class SecondDerived : Base
{
//this class should get only method 2 and method3
}
The requirement is : the base class contains the 3 methods M1, M2, M3.
The derived class should inherit only M1 and SecondDerived should inherit only M2 and M3.
How can this be done?
You cannot selectively inherit methods like this. A derived class automatically inherits all public methods of the base class. I suggest you to split the Base class into two classes:
public class Base1
{
public Base1()
{
}
public void M1()
{
}
}
public class Base2
{
public void M2()
{
}
public void M3()
{
}
}
public class First : Base1
public class Second : Base2
You cannot do it in this way. Inheritance implies an "IS A" relationship.
If SecondDerived would not have a M1() then it would not be compatible with a reference to a the class Base.
So maybe you shouldn't be using inheritance for whatever problem you're solving.
It is not possible to do what you want with inheritance.
It seems you have no intention of overriding, you simply want to "inherit" behavior from the base class selectively. You could do this using a "has a" relationship:
public class Base
{
internal Base() {} //mark constructor as internal so it can not be used outside your assembly if necessary
public Foo Mehtod1() {...}
public Foo Mehtod2() {...}
public Foo Mehtod3() {...}
}
Then simply do the following:
class A
{
private Base internalBase;
public A() { this.internalBase = new Base(); }
public Foo Method1() { return this.internalBase.Method1(); }
}
class B
{
private Base internalBase;
public A() { this.internalBase = new Base(); }
public Foo Method2() { return this.internalBase.Method2(); }
public Foo Method3() { return this.internalBase.Method3(); }
}
UPDATE: A possible alternative solution is to make your Base class methods virtual and override them all in your derived classes, throwing NotSupportedExceptions in those methods that you do not want the class to make available. I don't really like this solution but it has the advantage of not loosing the polyphormism inheritance gives you which might be useful if you have some core base functionality which all derived classes will share (in your example you seem to imply they wont).
It is possible by adding Obsolete attribute
public class A
{
public virtual void M1() { }
public void M2() { }
public void M3() { }
}
public class B : A
{
[Obsolete("You can not use this", true)]
public sealed override void M1()
{
}
}
public class C : B
{
public void Test()
{
// Will show error
base.M1();
}
}