I have 3 interfaces with 2 methods each doing the same job.
Interface A
{
Void M1()
Void M2()
}
Interface B
{
Void M1()
Void M2()
}
Interface C
{
Void M1()
Void M2()
}
Now, There are 3 classes implementing each of these interfaces.
Public Class A1:A
{
Public void M1()
{
}
Public void M2()
{
}
}
Public Class B1:B
{
Public void M1()
{
}
Public void M2()
{
}
}
Public Class C1:C
{
Public void M1()
{
}
Public void M2()
{
}
}
Functionality of M1 and M2 is exactly same in 3 classes. Interfaces are a part of library, I cannot change the interface and also cannot declare a new interface.
I want to refactor this code so that this duplication can be removed. I thought of creating a common class containing this functionality and then calling common class from each of these classes.
Please suggest.
It sounds like you should declare your own interface, and then create an adapter - or possibly multiple adapters. For example:
public interface IUnified
{
void M1();
void M2();
}
public class UnifiedAdapter : IUnified
{
private Action m1;
private Action m2;
public UnifiedAdapter(A a)
{
m1 = () => a.M1();
m2 = () => a.M2();
}
public UnifiedAdapter(B b)
{
m1 = () => b.M1();
m2 = () => b.M2();
}
public UnifiedAdapter(C c)
{
m1 = () => c.M1();
m2 = () => c.M2();
}
public M1()
{
m1();
}
public M2()
{
m2();
}
}
(This uses delegates to avoid having to create multiple adapter classes. The best approach depends on your exact situation.)
public abstract class XX : X
{
public void M1()
{
}
public void M2()
{
}
}
public interface X : A, B, C
{
}
Given the odd restrictions (and if you can I really suggest trying to get the interfaces changed) I think this is the best you can do:
public class Base : A, B, C {
public void M1(){}
public void M2(){}
}
Now inherit from Base in A1, B1 and C1.
However, if an A cannot, or should not, also be a B then this pattern won't work.
Therefore you would indeed have to go for the next best thing - a common base with the common functionality:
public class Base {
protected void M1Impl() { /* put your common implementation in here */ }
protected void M2Impl() { /* put your common implementation in here */ }
}
As the comments say - put the duplicated M1 and M2 code in the M1Impl and M2Impl methods here.
Now you can reuse this base for A, B and C implementations:
//common base for any implementation of A
//repeat for B and C
public class A1Base : Base, A
{
public void M1() { M1Impl(); }
public void M2() { M2Impl(); }
}
public class A1 : A1Base { }
I've worked on the basis here that you might have many implementations of A or B or whatever, and therefore you want a common starting point for each of those. If that's not the case, then you can do away with A1Base and simply call it A1.
public class BaseClass : A, B, C
{
public void M1()
{
}
public void M2()
{
}
}
Then just inherit from BaseClass:
public class A1 : BaseClass
{
}
public class B1 : BaseClass
{
}
public class C1 : BaseClass
{
}
A1 still will implement interface A. B1 will implement interface B. Same with C1. So, all your existing code will remain working:
A a = new A1();
a.M1();
If you only want to avoid to duplicate the implementation of those methods, then your initial approach is correct.
public class HelperClass
{
public static void M1()
{
// implementation code
}
public static void M2()
{
// implementation code
}
}
public class A1:A
{
public void M1()
{
HelperClass.M1();
}
public void M2()
{
HelperClass.M2();
}
}
public class B1:B
{
public void M1()
{
HelperClass.M1();
}
public void M2()
{
HelperClass.M2();
}
}
public class C1:C
{
public void M1()
{
HelperClass.M1();
}
public void M2()
{
HelperClass.M2();
}
}
Even if interfaces A, B, and C have the same methods, they may have different semantics and may make sense to have them as separate interfaces. That is, making a class implement A, may mean something different than implementing B, even if their methods have the same signatures.
Adding additional interfaces or common base classes is overkill and adds unneeded coupling. As I said before, if you only need to avoid duplicating the methods' implementation, a helper class is the easiest and cleanest solution.
Related
Please consider the attached figure.
What I want is that the (technical-) "User" can use methods from class A, B or C by an instantiate of "HeadClass". What I try to avoid is, that I have to add a separate function for each method defined in Class A, B and C to call them through the "HeadClass". I tried to describe this in an other stackoverflow-request yesterday but have deleted it because it seemed to be unclear what I wanted to achieve. So here is an other approach.
Usually this would be achieved by inheritance (if only one class would be inherited from). But, as they told me in that deleted post, I should use Interface instead. Now, so far I thought that I know how interface work (using almost for every class), but I can't figure how I achieve this describe problem.
How would I have to fill the "???" in "HeadClass"?
I am happy for any input. Thx in adavnce!
class User
{
public User(IHeadClass headObj)
{
_headObj = headObj
}
public DoStuff()
{
_headObj.Method_1
_headObj.Method_2
_headObj.HeadMethod
}
}
public class HeadClass : IHeadClass, ???
{
???
public HeadClass( ??? )
{
???
}
void HeadMethod()
{
... do head stuff
}
}
public class Class_A : IClass_A
{
public void Method_1 () { }
}
public class Class_B : IClass_B
{
public void Method_2 () { }
public void Method_3 () { }
}
public class Class_C : IClass_C
{
public void Method_4 () { }
}
I have check out this describing how to use interfaces instead. But this doesn't solve the above problem.
If I understand correctly you can use composition here. Something like this:
public interface IClass_A
{
void Method_1 ();
}
public interface IClass_B
{
void Method_2 ();
void Method_3 ();
}
public interface IClass_C
{
void Method_4 ();
}
public interface IHeadClass : IClass_A, IClass_B, IClass_C
{
void HeadMethod();
}
public class HeadClass : IHeadClass
{
private readonly IClass_A _a;
private readonly IClass_B _b;
private readonly IClass_C _c;
public HeadClass(IClass_A a, IClass_B b, IClass_C c)
{
_a = a;
_b = b;
_c = c;
}
void HeadMethod()
{
... do head stuff
}
public void Method_1() => _a.Method_1();
public void Method_2() => _b.Method_2();
public void Method_3() => _b.Method_3();
public void Method_4() => _c.Method_4();
}
C# (unlike for example C++ or PHP) does not support multiple inheritance. Interfaces allows multiple inheritance, but they don't provide definitions of methods, only declarations.
I think solution could be pattern called fasade: write methods in HeadClass that calls methods in other classes. In this case interfaces are not necessary.
public class HeadClass
{
private Class_A _a;
private Class_B _b;
private Class_C _c;
public HeadClass( Class_A a, Class_B b, Class_C c )
{
_a=a;
_b=b;
_c=c;
}
void HeadMethod()
{
... do head stuff
}
public void Method_1 () {
_a.Method_1();
}
public void Method_2 () {
_b.Method_2();
}
public void Method_3 () {
_b.Method_3();
}
public void Method_4 () {
_c.Method_4();
}
}
May I suggest instead that you have an interface passed instead of Class definition in your constructor?
public class HeadClass
{
private IMethod1 _method1;
private IMethod2 _method2;
private IMethod3 _method3;
private IMethod4 _method4;
public HeadClass( IMethod1 method1, IMethod2 method2, IMethod3 method3, IMethod4 method4)
{
_method1=method1;
_method2=method2;
_method3=method3;
_method4=method4;
}
void HeadMethod()
{
... do head stuff
}
public void Method_1 () {
_method1.Method_1();
}
public void Method_2 () {
IMethod2.Method_2();
}
public void Method_3 () {
IMethod3.Method_3();
}
public void Method_4 () {
IMethod4.Method_4();
}
}
Now you have removed any direct coupling to a class, you are no only linked by interface.
Say you want to split method 2 and 3 into it's own two classes? this code, never has to change.
You can now reuse any class that has a definition of the interface, as a paramater. No code is defined twice, that does the same thing, in each input.
Because:
public class Method1 : IMethod1
{
}
public class Method2 : IMethod2
{
}
public class Method3 : IMethod3
{
}
public class Method4 : IMethod4
{
}
can now be parsed as parameters to HeadClass.
or, if you insist method 2 & 3 belong on the same class.
public class ClassA: IMethod1
{
}
public class ClassB: IMethod2, IMethod3
{
}
public class ClassC: IMethod4
{
}
Should be obvious from this example that the benefits lie in the fact that you can now do whatever you want in Headclass, and if you need behaviour to change, you can inject code via constructor, without having to retry the behaviour of headclass.
And headclass, doesn't know ClassA, B or C exist directly, only the interface.
I Believe this is called the Strategy pattern?
Is it possible to use a subset of methods as member methods in different classes in C#?
For instance, I have four functions the void A(), the void B(), the void C() and the void D().
And now I want to have three classes. The first class I would like to have the member methods A, B and C. The second I would like to have the B and D. And the third the A, C and D.
How could I achieve this? Is it possible to achieve this only by using interfaces or are there any other approaches?
If all your three classes should have different implementations for these methods, then classic interfaces are the way to go:
public interface IHaveA {
void A();
}
public interface IHaveB {
void B();
}
public interface IHaveC {
void C();
}
public interface IHaveD {
void D();
}
public class Class1 : IHaveA, IHaveB, IHaveC { // Implement A, B and C here }
public class Class2 : IHaveB, IHaveD { // Implement B and D here }
public class Class3 : IHaveA, IHaveC, IHaveD { // Implement A, C and D here }
If all your classes should have the same implementation of A, B, C and D, you could still use interfaces but you would have to duplicate code:
public static class StaticImplementation {
public void A(IHaveA sender) {
// Do stuff here
}
public void B(IHaveB sender) {
// Do stuff here
}
public void C(IHaveC sender) {
// Do stuff here
}
public void D(IHaveD sender) {
// Do stuff here
}
}
public class Class1 : IHaveA, IHaveB, IHaveC {
public void A() { StaticImplementation.A(this) }
public void B() { StaticImplementation.B(this) }
public void C() { StaticImplementation.C(this) }
}
public class Class2 : IHaveB, IHaveD { // Calls to StaticImplementation for B and D here }
public class Class3 : IHaveA, IHaveC, IHaveD { // Calls to StaticImplementation for A, C and D here }
There is no way to enforce that these three classes have the same implementation of these methods using interfaces, because the primary goal interfaces is to ensure that classes implement methods, specifically with different implementations!
This changes in C# 8.0 and .NET Core 3.0 where you can have default implementations for interface methods, and you could ensure that these implementations do not change by sealing them.
The code would become:
public interface IHaveA {
sealed void A() {
// Implementation here
}
}
public interface IHaveB {
sealed void B() {
// Implementation here
}
}
public interface IHaveC {
sealed void C() {
// Implementation here
}
}
public interface IHaveD {
sealed void D() {
// Implementation here
}
}
public class Class1 : IHaveA, IHaveB, IHaveC { // Nothing to do here }
public class Class2 : IHaveB, IHaveD { // Nothing to do here }
public class Class3 : IHaveA, IHaveC, IHaveD { // Nothing to do here }
using System;
public interface MA {}
public static class MAProvider {
public static void A(this MA obj) { Console.WriteLine("MA"); }
}
public interface MB {}
public static class MBProvider {
public static void B(this MB obj) { Console.WriteLine("MB"); }
}
public interface MC {}
public static class MCProvider {
public static void C(this MC obj) { Console.WriteLine("MC"); }
}
public interface MD {}
public static class MDProvider {
public static void D(this MD obj) { Console.WriteLine("MD"); }
}
public class First : MA, MB, MC {}
public class Second : MB, MD {}
public class Third : MA, MC, MD {}
public static class Program {
public static void Main() {
new First().A();
new First().B();
new First().C();
new Second().B();
new Second().D();
new Third().A();
new Third().C();
new Third().D();
}
}
The only issue which is left is the private members. Since we can not access them inside the extension methods.
We have a base class A which consists of 6 public methods :
public class A
{
public void method1()
{
// Implementation
}
public void method2()
{
// Implementation
}
.
.
.
.
public void method6()
{
// Implementation
}
}
We have two child class B and C which inherits from A. How can I implement it in such a way that Class B has access to only method1(),method2(),method3() and Class C has access to method4(),method5(),method6()??
You can't prevent something from using public class A methods, but you can definitely hide them with the proper use of interfaces.
interface IAOne
{
void method1();
void method2();
void method3();
}
interface IATwo
{
void method4();
void method5();
void method6();
}
class A : IAOne, IATwo
{
void method1() { }
void method2() { }
void method3() { }
void method4() { }
void method5() { }
void method6() { }
}
So now you have class B which never needs to know about A or about A's methods. It only knows about the IAOne interface. B can now also re-expose any methods (and even re-implement the interface) and delegate the implementation of those to A.
class B : IAOne
{
private IAOne _a;
public B(IAOne a) { _a = a; }
void method1() { _a.method1(); }
void method2() { _a.method2(); }
void method3() { _a.method3(); }
}
You basically can't do that. The fact that you're attempting to do it should serve as a warning that there is something wrong with your code.
I don't now why you have emphasize to use one class (A) with all 6 methods, but if you wanna get that may you should aspect programming design and put and interceptor on the head of your methods. Then you can check caller with MethodCallerInfo and control to each your child classes just call their own methods
public class A
{
private void MethodA(){}
}
public class B
{
private void MethodB() { }
}
public class C
{
private void MethodC() { }
}
I want to make sure that MethodA can be called only from MethodB. Other method can never call MethodA.
Make MethodA protected and use inheritance like this:
public class A
{
protected void MethodA()
{
}
}
public class B : A
{
private void MethodB()
{
//MethodA is accessible just here
}
}
public class C
{
private void MethodC()
{
//MethodA is not accessible here
}
}
But if you don't want to use inheritance and want all the classes in the same assembly you could only nest class B within class A and keep MethodA private. Like this:
public class A
{
private void MethodA()
{
}
public class B
{
private void MethodB()
{
A a = new A();
a.MethodA();
}
}
}
public class C
{
private void MethodC()
{
//MethodA is not accessible here
}
}
public class D : A
{
private void MethodC()
{
//MethodA is not accessible here
}
}
I note that S.Akbari's answer, though good, does not exactly meet your requirement. You said that you wanted MethodA to be callable only within B, but in their answer, MethodA is callable within A.
The solution to the problem you actually posed is to invert the nesting:
class B
{
private class A
{
public void MethodA() { }
}
}
Now MethodA can only be called from within B.
But the question is bizarre. If you have a method that can only be called from B then why is it not a member of B?
I am designing a System where the following scanario arise.
I have a method f1() for which behavior varies across implementation.
I have a method f2() for which behavior is same for all implementations.
I have designed as following:
interface I1
{
//Behaviour will vary across implementations
void f1();
//Same behaviour for all implementations
void f2();
}
abstract class C
{
//Implemented in the Base class
void f2()
{
}
}
public class C1:C,I1
{
//Implemented interface method
public f1()
{
}
}
public class C2:C,I1
{
//Implemented interface method
public f1()
{
}
}
Is the design is correct? Can anybody suggest any appropriate design in this sceanario ?
You should create just one abstract class with methods f1() and f2() as follows:
abstract class A
{
public abstract f1();
protected void f2()
{
}
}
class B : A
{
public override void f1()
{
}
}
Now whenever you create an class based upon A, they can specify their own behavior for method f1().
An alternative is to use a strategy pattern:
public interface IF1Strategy
{
void f1();
}
public sealed class C : I1
{
private readonly IF1Strategy _f1Strategy;
//strategy injected
public C(IF1Strategy strategy)
{
_f1Strategy = strategy;
}
void f2()
{
}
void f1()
{
//delegated to strategy
_f1Strategy.f1();
}
}
NB: Only suitable if your f1 strategy implementors do not need to call f2.
Advantages:
You can inject the appropriate strategy.
You can unit test strategies on their own.
Class C can change independant of the others i.e. that saves you maintaining a class heirachy. Note how I have sealed it.
In short, I am choosing Composition over inheritance
I am following OOPs design principle along with strategy pattern to provide a good solution for your problem.
these are the principle i follow:
1. Favor composition over inheritance.
2. Program to interface not implementation,
public interface I1VariedBehavior
{
void f1(); // Varies for the implementation.
}
public abstract class I1SameBehavior
{
public void f2()
{
Console.WriteLine("f2 same behavior");
}
}
public class F1Impl1 : I1VariedBehavior
{
public void f1() // f1 is own implementation
{
Console.WriteLine("F1 own implementation 1");
}
}
public class F1Impl2 : I1VariedBehavior
{
public void f1() // f1 is own implementation
{
Console.WriteLine("F1 own implementation 2");
}
}
public class C1 : I1SameBehavior
{
I1VariedBehavior strategy;
public C1(I1VariedBehavior strategy)
{
this.strategy = strategy;
}
public void f1()
{
strategy.f1();
}
}
public class Client
{
public static void Main(String[] args)
{
C1 c1 = new C1(new F1Impl1());
c1.f1();
c1.f2();
C1 c2 = new C1(new F1Impl2());
c2.f1();
c2.f2();
Console.Read();
}
}
output:
F1 own implementation 1
f2 same behavior
F1 own implementation 2
f2 same behavior
hope that helps.