Template method pattern - prevent direct method calls in derived classes - c#

I'm not sure if I understand template method pattern correctly.
Here is my simplified base class implementation:
public abstract class AlgorithmBase
{
protected void AlgorithmMethod()
{
if(!OnSimulationStart())
{
OnSimulationEnd(false);
return;
}
if(!DoSomeStep())
{
OnSimulationEnd(false);
return;
}
OnSimulationEnd(true);
}
protected abstract bool OnSimulationStart();
protected abstract bool DoSomeStep();
protected abstract void OnSimulationEnd(bool result);
}
As far as I understand it, base class knows algorithm flow and manages it.
The problem is that in real project I have many abstract methods and it would be nice if I could somehow prevent direct calling them in derived classes. It is unreadable when more than one class manages algorithm flow.

A trick based on explicit implementation of an interface can be used to prevent accidental invokes of method required by the base algorith implementation. However, it's such a safety measure, which can be broken, but the chances are high that the developer would know what he would be doing.
An interface declaring methods required by AlgorithmMethod:
public interface IAlgorithmMethodImpl
{
bool OnSimulationStart();
bool DoSomeStep();
void OnSimulationEnd(bool result);
}
Base abstract class that uses this interface, passed into its constructor, to call required methods:
public abstract class AlgorithmBase
{
protected AlgorithmBase(IAlgorithmMethodImpl impl)
{
Impl = impl;
}
// can be a property reasonable cases; however, a field
// fits well into our scenario
private IAlgorithmMethodImpl Impl;
protected void AlgorithmMethod()
{
if(!Impl.OnSimulationStart())
{
Impl.OnSimulationEnd(false);
return;
}
if(!DoSomeStep())
{
Impl.OnSimulationEnd(false);
return;
}
Impl.OnSimulationEnd(true);
}
// no abstract method declarations here — they are provided by 'Impl'
}
Then the specific algorithm class that inherits from AlgorithmBase uses explicit interface implementation to encapsulate implementation of the necessary methods (like with abstract methods declared in the base) class while preventing them being invoked accidentally:
public class MySuperAlgorithm : AlgorithmBase, IAlgorithmMethodImpl
{
public MySuperAlgorithm()
// pass a reference to this instance as the class
// that implements the required methods
: base(this)
{
}
// explicit implementation of IAlgorithmMethodImpl
bool IAlgorithmMethodImpl.OnSimulationStart() { ... implementation ... }
bool IAlgorithmMethodImpl.DoSomeStep() { ... implementation ... }
void IAlgorithmMethodImpl.OnSimulationEnd(bool result) { ... implementation ... }
}
The advantage of this approch — besides preventing accidental invoking of implementation methods — is that you can choose whether encapsulate the implementation in the descendant, or to decompose it into a separate class.

Related

Is it possible to require a derived class to implement a virtual method from base class?

I want a method to do a consistent thing in base class while derived classes can have it do something different (hence it being virtual), while requiring it be implemented in derived classes as if it were abstract. It being required would prevent forgetfulness of implementing it among myself and others working on it.
To break it down (this code is for a Unity project):
// Base
public abstract class Attack : MonoBehaviour
{
public virtual void AttackFinished()
{
Entity.StateController.SwitchToState<IdleState>();
}
}
// Child
public class PlayerSwordAttack : Attack
{
// I want this implementation to be required, not optional
// while having it still do the stuff it does in base
public override void AttackFinished()
{
base.AttackFinished();
// Extra stuff
}
}
In this case, I want PlayerSwordAttack or any other child classes to require implementing AttackFinished() without it being abstract.
Tl;dr: Essentially I want public abstract virtual void AttackFinished() which isn't possible as far as I know, but I hope to learn of a way to do it.
Given that I haven't found this question posted here or anywhere else, I'm expecting the answer to be "don't be silly, it's impossible" but thought I'd ask, since a friend of mine has had the same question.
Just break it down into two methods. One is non-virtual, non-abstract, so is not overridable. This will call the abstract method that derived classes are forced to implement.
public abstract class Attack
{
public void AttackFinished()
{
Entity.StateController.SwitchToState<IdleState>();
OnAttackFinished();
}
protected abstract void OnAttackFinished();
}
public class PlayerSwordAttack : Attack
{
protected override void OnAttackFinished()
{
// Extra stuff
}
}
Note that this is like forcing base.AttackFinished in your original code to be called in the derived classes' implementations. If you want derived classes to opt out of this, you can add an additional property:
public abstract class Attack
{
public void AttackFinished()
{
if (ShouldChangeStateAfterAttack) {
Entity.StateController.SwitchToState<IdleState>();
}
OnAttackFinished();
}
protected abstract void OnAttackFinished();
// could also be virtual instead to provide a default implementation
protected abstract bool ShouldChangeStateAfterAttack { get; }
}
public class PlayerSwordAttack : Attack
{
protected override void OnAttackFinished()
{
// Extra stuff
}
protected override bool ShouldChangeStateAfterAttack => false;
}
base.AttackFinished in your original code could also be called independently, from anywhere in the derived class. If you also want that, simply extract the line Entity.StateController.SwitchToState<IdleState>(); as another method.

Looking for other ways to hide abstract inheritance method from a subclass?

I want the inherited method Invoke() to be hidden from the final subclass ConcreteExecutablePlugin.
Whole situation:
public abstract class PluginBase
{
public abstract void Invoke(IDictionary parameters);
}
public abstract class JobPlugin : PluginBase
{
protected void CheckParameter(){//....}
public bool IsActive(){//....}
}
public class ConcreteJobPlugin : JobPlugin
{
public override void Invoke(IDictionary parameters){//...}
}
public abstract class ExecutableJobPlugin : JobPlugin
{
protected abstract void Initialize(IDictionary parameters);
public sealed override void Invoke(IDictionary parameters)
{
//final realization of Invoke() method
}
}
public class ConcreteExecutablePlugin : ExecutableJobPlugin
{
//here i want method Invoke() has been already hiden
//!!!OR use base.Invoke() better?
protected override void Initialize(IDictionary parameters)
{
//concrete plugin initialization
}
}
I have found only one solution. Now, I'm using sealed for this. What do you think about this solution?
Do you know another ways to hide abstract inheritance method?
Re: Visibility
A public method signals the design intention that it is visible to all - if this isn't the designed intention, change the method's visibility accordingly, e.g. protected (but obviously any subclass has access), or if all classes which are allowed to use Invoke are in the same assembly, then Invoke can be declared protected internal abstract.
Re: Sealed
As per Lasse's point, sealed override methods will disrupt the polymorphic virtual / override chain during inheritance, but still, it can not change the fact that the base method is public. However, applying sealed to a class will prevent other classes from inheriting it all, thus restricting access to all protected methods.
Solution
I believe the underlying problem relates to over-using inheritance - seemingly you want to inherit functionality to obtain reuse, but at the same time need to restrict access at some point in the chain to an "untrustworthy" subclass. Other than the point about making methods internal + moving all "trustworthy" subclasses into the base class assembly, you will have little control when using a full chain of subclasses.
I believe that decoupling your hierarchy via interfaces, and applying the principle of composition over inheritance, will better achieve what you are after. In fact, the Decorator pattern looks to be an option here.
You can also set the 'trustworthiness' boundary by making the 'last trustworthy' subclass (ExecutableJobPlugin) as sealed *.
Example:
// Expose just what is visible to your final Subclass on the interface
public interface IExecutableJobPlugin
{
bool IsActive { get; set; }
void CheckParameter();
void Initialize(IDictionary parameters);
}
// Sealed will prevent other classes from inheriting this class.
public sealed class ExecutableJobPlugin : JobPlugin, IExecutableJobPlugin
{
// Default implementation. NB, not abstract
public void Initialize(IDictionary parameters) {}
// This isn't visible on the interface
protected override sealed void Invoke(IDictionary parameters)
{
//final realization of Invoke() method
}
}
public class ConcreteExecutablePlugin : IExecutableJobPlugin
{
// Compose a decoupled IExecutableJobPlugin instead of direct inheritance
private readonly IExecutableJobPlugin _wrappedJobPlugin;
public ConcreteExecutablePlugin(IExecutableJobPlugin wrapped)
{
_wrappedJobPlugin = wrapped;
}
// Invoke() isn't on the interface so cannot be accessed here
public void Initialize(IDictionary parameters)
{
// Call 'super' if needed.
_wrappedJobPlugin.Initialize(parameters);
//concrete plugin initialization code here ...
}
public bool IsActive
{
get { return _wrappedJobPlugin.IsActive; }
set { _wrappedJobPlugin.IsActive = value; }
}
public void CheckParameter()
{
_wrappedJobPlugin.CheckParameter();
}
}
Notes
Because ConcreteExecutablePlugin is no longer a subclass of PluginBase, if you change method PluginBase.Invoke to protected, that ConcreteExecutablePlugin will have no access to it (aside from hacks like reflection).
All 'reused' methods and properties needed from the composed (née base) class ExecutableJobPlugin need to be rewired in the ConcreteExecutablePlugin. Although somewhat tedious, it does allow for additional interception, e.g. cross cutting concerns like logging.
The ExecutableJobPlugin class may no longer be abstract, since an instance will be needed for the composition to work.
Ideally, the ExecutableJobPlugin should be injected externally (as opposed to new within)
Decoupling via interfaces improves the testability of your class hierarchy
* Sealing ExecutableJobPlugin won't however prevent others from subclassing public superclasses like PluginBase and JobPlugin. To prevent this, you could keep all the base classes in the same assembly and mark these as internal, or continue to apply the interface decoupling / Decorator pattern instead of inheritance across the entire chain.
The pattern could obviously be repeated for multiple levels of your class hierarchy, and the interface segregation principle should be applied to ensure that your interfaces remain lean and focused.
It is impossible to hide public methods in derived classes. The whole point of public is that the method is accessible in the base class and any descendants of that class.
You could try using protected, and then simply have a public method like Initialize in your derived plugins, or you could try using internal (although that would probably not be preferable).

virtual calls on overridden interface implementations

If I have two classes that both implement an interface, but also inherit, do I need to make the function virtual? eg given:
interface IDoSomething
{
void DoSomething();
}
class A : IDoSomething
{
public void DoSomething()
{
//do A
}
}
class B : A
{
public new void DoSomething()
{
//do B
}
}
Would the following code do A or B?
IDoSomething doer = new B();
doer.DoSomething(); //do A or do B?
I'm getting confused because I'm under the impression that all inteface calls are effectively virtual, but obviously I am using the new operator to hide the base definition.
Here is the explanation. Already available at stackoverflow forums.
Quoting Jeffrey Ritcher from CLR via CSharp 3rd Edition here
The CLR requires that interface methods be marked as virtual. If you
do not explicitly mark the method as virtual in your source code, the
compiler marks the method as virtual and sealed; this prevents a
derived class from overriding the interface method. If you explicitly
mark the method as virtual, the compiler marks the method as virtual
(and leaves it unsealed); this allows a derived class to override the
interface method. If an interface method is sealed, a derived class
cannot override the method. However, a derived class can re-inherit
the same interface and can provide its own implementation for the
interface’s methods.
class A : IDoSomething
{
public virtual void DoSomething()
{
//do A
}
}
class B : A
{
public override void DoSomething()
{
//do B
}
}
I prefer leppie's solution. If that's not an option:
class A : IDoSomething
{
void IDoSomething.DoSomething()
{
//do A
}
}
class B : A
{
void IDoSomething.DoSomething()
{
//do B
}
}
But note that this will hide the implementation, so you can't do ((A)doer).DoSomething().
If you can't change class A to either of these solutions, I don't think there's a sure way to override it in all cases. You could both explicitly implement the interface and make a public new method on B. That way if it's statically known as an IDoSomething or as a B it will use B's implementation, but if it's known as an A it will still use A's implementation.
Although C# and .net allow derived classes to re-implement interface methods, it is often better to have the base class use a virtual method to implement the interface, and have the derived class override that method, in any situation where a derived class might wish to augment, rather than entirely replace, the base-class implementation. In some languages like vb.net, this can be done directly regardless of whether a class exposes a public member with the same name and signature as the interface member being implemented. In other languages like C#, a public method which implements an interface can be marked unsealed and virtual (allowing a derived class to override it and have that override call base.Member(params) but an explicit interface implementation cannot. In such languages, the best one can do is something like:
class MyClass : MyInterface
{
void MyInterface.DoSomething(int param)
{
doSomething(param);
}
protected virtual void doSomething(int param)
{
...
}
}
class MyClass2 : MyClass
{
protected override void doSomething(int param)
{
...
base.doSomething(param);
...
}
}
In some cases, having the interface implementation wrap a virtual call can be advantageous, since it allows the base class to ensure that certain things happen before or after the overridden function. For example, a non-virtual interface implementation of Dispose could wrap a virtual Dispose method:
int DisposingFlag; // System.Boolean doesn't work with Interlocked.Exchange
void IDisposable.Dispose()
{
if (Threading.Interlocked.CompareExchange(DisposingFlag, 1, 0) == 0)
{
Dispose(true);
DisposingFlag = 2;
Threading.Thread.MemoryBarrier();
GC.SuppressFinalize(this);
}
}
public bool Disposed { get {return (DisposingFlag != 0);} }
public bool FullyDisposed { get {return (DisposingFlag > 1);} }
This will (unlike Microsoft's default wrapper) ensure that Dispose only gets called once, even if multiple threads try to call it simultaneously. Further, it makes a Disposed property available. Using Microsoft's wrapper, every derived class that wants a Disposed flag would have to define its own; even if the base-class Disposed flag were protected or public, it wouldn't be safe to use because it wouldn't get set until after derived classes had already begun cleanup. Setting DisposingFlag within the wrapper avoids that problem.

C# best partial interface implementation in base/abstract class

.net does not allow partial interface implementation in base classes. As a mitigation I've come to 3 alternate solutions. Please help me decide which is more universal in terms of refactoring, compile/run time errors, readability.
But first a couple of comments.
Of course you may always cast object to IFoo and call any method without any compiler warning. But it's not logical, you wouldn't do that normally. This construct wouldn't occur as a result of refactoring.
I want maximum separation. Direct class contract (public methods and properties) should be separated with interface implementations. I use interfaces a lot to separate object interations.
My comparison:
BaseClass1/MyClass1:
con: Have to create virtual abstract in BaseClass1 for each not implemented method of IFoo.
con: Additional method wrap - slight productivity impact at runtime.
BaseClass2/MyClass2:
con: no compiler warning if no implementation of Method2 in MyClass2. Runtime exception instead. Refactoring with poor unit test coverage may potentially destabilize code.
con: has to put additional obsolete construct to prevent direct method call from child classes.
con: Method2 is public for BaseClass1 so it's part of class contract now. Have to put "Obsolete" construct to prevent direct call, not via IFoo.
BaseClass3/MyClass3:
pro: (Compared to #2). More readable. You see that MyClass2.Method2 is IFoo implementation, not just some overriden method.
public interface IFoo
{
void Method1();
void Method2();
}
public abstract class BaseClass1 : IFoo
{
void IFoo.Method1()
{
//some implementation
}
void IFoo.Method2()
{
IFooMethod2();
}
protected abstract void IFooMethod2();
}
public class MyClass1 : BaseClass1
{
[Obsolete("Prohibited direct call from child classes. only inteface implementation")]
protected override void IFooMethod2()
{
//some implementation
}
}
public abstract class BaseClass2 : IFoo
{
void IFoo.Method1()
{
//some implementation
}
[Obsolete("Prohibited direct call from child classes. only inteface implementation")]
public virtual void Method2()
{
throw new NotSupportedException();
}
}
public abstract class MyClass2 : BaseClass2
{
public override void Method2()
{
//some implementation
}
}
public abstract class BaseClass3 : IFoo
{
void IFoo.Method1()
{
//some implementation
}
void IFoo.Method2()
{
throw new NotSupportedException();
}
}
public abstract class MyClass3 : BaseClass3, IFoo
{
void IFoo.Method2()
{
//some implementation
}
}
I like this version, the base class can't be instantiated because its abstract, the derived class must list IFoo in its declaration or else it won't be implementing the interface and then it is solely responsible for implementing the rest of the interface.
One drawback I can see is you can't explicitly implement the interface methods in the base class (ie no IFoo:Method1), but otherwise this is a fairly low overhead version.
public interface IFoo
{
void Method1();
void Method2();
}
public abstract class BaseClass1
{
public void Method1()
{
//some implementation
}
}
public class MyClass1 : BaseClass1, IFoo
{
public void Method2()
{
//some implementation
}
}
Ok, you could try the following as BaseClass is abstract:
public interface IFoo
{
void Method1();
void Method2();
}
public abstract class BaseClass : IFoo
{
public void Method1()
{
// Common stuff for all BaseClassX classes
}
// Abstract method: it ensures IFoo is fully implemented
// by all classes that inherit from BaseClass, but doesn't provide
// any implementation right here.
public abstract void Method2();
}
public class MyClass1 : BaseClass
{
public override void Method2()
{
// Specific stuff for MyClass1
Console.WriteLine("Class1");
}
}
public class MyClass2 : BaseClass
{
public override void Method2()
{
// Specific stuff for MyClass2
Console.WriteLine("Class2");
}
}
private static void Main(string[] args)
{
IFoo test1 = new MyClass1();
IFoo test2 = new MyClass2();
test1.Method2();
test2.Method2();
Console.ReadKey();
}
It is extremely bad to design a class that doesn't implement a well-defined contract. It is extreme because you firstly say that a class is capable of doing something. You explicitly highlight that the class can do stuff, but later in the code you say nahh, screw it, this class can live without implementation. Compiler very wisely asks you to implement the contract, but it is left up to you to decide.
Here are some common solutions
Bad solution
Throw an exception (NonImplementedException or NotSupportedException, see sample)
Declare it as obsolete (design it good from the beginning)
Better solution
Explicit interface implementation, but you still implement it (just kind of hide it)
Best solution
Use interface segregation (split your fat interface into thinner and more manageable ones)
I'd suggest having the abstract base class implement the interface with methods that call protected abstract methods, as shown in your first example, except for methods which some derived classes may not implement (following the "throw everything into IList but don't have all the methods actually work" pattern); those could be protected virtual stubs which throw NotSupportedException.
Note that it is up to the child class whether to expose any particular member of the interface as a like-named public member (which could call the appropriate abstract member).
The proper pattern in VB.net would be something like MustOverride Sub IFoo_Method1() Implements IFoo.Method1, which would avoid the extra function call overhead, but C# doesn't provide any means of implementing an interface with a protected member. Using explicit interface implementation for any method which may have to be overridden in a child class is somewhat icky, because it's impossible for the child's re-implementation of the interface to chain to the parent's implementation.

Why doesn't C# support explicitly implemented virtual methods?

Interface methods in C# can be implemented explicitly, so that their implementation is invoked when an instance is explicitly cast to the interface type. Why is this not also supported on virtual methods of classes?
Although working around the 'multiple inheritance' issue is unique to interfaces, it seems that for every other reason that explicitly implemented members would be useful for interfaces, they would also be useful for virtual methods. A cleaner return-type covariance model springs to mind.
Edit: By request, an example:
public class Foo {
...
}
public class Bar : Foo {
...
}
class Base {
abstract Foo A ();
}
class Dervied {
private Bar _b;
Bar A () {
return _b;
}
Foo Base.A () {
return _b;
}
}
I am aware of using helper methods to simulate this, but the net effect seems to have any of the bad characteristics that explicit implementation would have, but with a dirtier API. The crux of my question is not how to do return type covariance, but why a similar mechanism for interfaces is not supported for virtual methods.
Some people recommend not having public virtual methods in the first place. But instead create one public non virtual method representing the consumer interface, and one protected virtual method representing the implementer interface.
I would not call separating the contracts for caller and implementer "muddying the design". In many cases it's cleaner IMO, but I'm usually too lazy to actually do it that way.
This design works much better with return type covariance and method hiding.
An additional benefit of this is that the public wrapper can add additional checking code and supports different contracts for the caller and implementer.
An example of how I'd emulate return type covariance:
public class Base
{
protected virtual Base FooOverride(int i){return new Base();};//FooOverride does not need to duplicate the argument checking
public Base Foo(int i)
{
if(i<0)
throw new ArgumentException("i<0");
return FooOverride(i);
}
}
public class Derived:Base
{
protected override Base FooOverride(int i){return new Derived();};
public new Derived Foo(int i)
{
return (Derived)base.Foo();
}
}
What benefit would that have, besides from allowing something like this?
class Base
{
virtual void M() { }
}
class Derived : Base
{
override void M() { }
override void Base.M() { }
}
This effectively bakes a violation of the Liskov Substitution Principle into the C# language - if I have a variable of type Base, calling M() on it can do entirely different things depending on whether the run-time type is Base or Derived.
Explicit interface implementation is different. Say you have this:
interface IFoo
{
void DoStuff();
}
interface IBar
{
void DoStuff();
}
class C : IFoo, IBar
{
void IFoo.DoStuff() { }
void IBar.DoStuff() { }
}
This preserves the LSP - if I have an IFoo variable that happens to be of run-time type C, calling DoStuff() on it will get the IFoo implementation of it. Likewise with IBar.

Categories