Is this OOP approach doomed to fail or is there some merit in this?
Before I understood abstract classes I was getting more or less the same benefits of code reuse by using an interface class + a regular class that implements certain methods of the interface. For example
public interface IMyService
{
String Helloword1();
String Helloword2();
String Helloword3();
}
public class MyService
{
public String Helloword1(){return "1";}
public String Helloword2(){return "2";}
//Helloworld3 is not here so I would be forced to provide implementation in any subclass
//very similar to calling abstract on a method
}
public class SubClass1: MyService, IMyService
{
public String Helloword3(){return "3";}
}
public class SubClass2: MyService, IMyService
{
public new String Helloword2(){return "override method";}
public String Helloword3(){return "3";}
}
Can anyone see of any advantage of doing this or is this really providing the same advantages as an abstract class?
Can anyone see of any advantage of doing this or is this really providing the same advantages as an abstract class?
There is a big disadvantage to doing this. You allow people to subclass MyService without implementing Helloword3, since that's not part of the contract.
An abstract class would enforce that the type implements that member. Here, you trust that the user will implement the "required" interface.
In your example someone can actually construct an instance of MyService and use it without the use of the abstract method.
Honestly, there isn't even really any need to inherit form MyService in your two sub classes. If MyService can be created concretely, that type can be composed, rather than inherited from.
The real value in an abstract class is where the concrete methods actually use the abstract methods. Being able to write things like this:
public abstract class Foo
{
public abstract Guid CreateUniqueIdentifier();
public void SaveToDatabase()
{
Guid guid = CreateUniqueIdentifier();
//do stuff with guid
}
}
You cannot do something like this using your pattern; the concrete methods can never be dependent on the not-yet-implemented methods.
Related
Given an interface like:
public interface IFoo
{
string Bar();
}
And a class that implements it like:
public class Foo : IFoo
{
public string Bar()
{
returns "Bar";
}
public string SomeOtherMethod()
{
returns "Something else";
}
}
Is there a problem with this code? Should we add all methods to the interface?
One example: imagine a private method that grows complex enough to need unit tests. Could you make it public (so it can be called from the test project) but not add it to the interface (because no clients need to call it)?
If what a class does is simple enough that we can test its public methods and private methods at the same time, then we can just test the public methods.
If the private method grows so complex that between the public and private method we need too many combinations of tests then it's time to separate the private method into its own class. Making the private method public would break the encapsulation of the class. Even if we don't add the method to an interface, making the class method public still adds the method to the public interface of the class itself.
So if we have this:
public class ClassWithComplexPrivateMethod
{
public void DoSomething(int value)
{
PrivateMethodThatNeedsItsOwnTests(value);
}
private string PrivateMethodThatNeedsItsOwnTests(int value)
{
// This method has gotten really complicated!
return value.ToString();
}
}
We might refactor to something like this:
public interface IRepresentsWhatThePrivateMethodDid
{
string MethodThatNeedsItsOwnTests(int value);
}
public class RefactoredClass
{
private readonly IRepresentsWhatThePrivateMethodDid _dependency;
public RefactoredClass(IRepresentsWhatThePrivateMethodDid dependency)
{
_dependency = dependency;
}
public string DoSomething(int value)
{
return _dependency.MethodThatNeedsItsOwnTests(value);
}
}
And now a new class implements IRepresentsWhatThePrivateMethodDid.
Now when we test the refactored class we mock IRepresentsWhatThePrivateMethodDid, and we write separate unit tests for any classes that implement IRepresentsWhatThePrivateMethodDid.
It may seem like a contradiction to say that exposing the private method as public breaks encapsulation, but exposing it as its own separate class doesn't. There are two differences:
The refactored class doesn't depend on the new class containing what used to be the private method. It depends on the new interface.
The interaction between the refactored class and the interface is still hidden within its methods. Other classes that call its public methods don't "know" about how it uses its dependency. (In fact, other classes will likely depend on abstractions instead of directly on the refactored class.)
It's also easy to get carried away with this and introduce the separate dependency too soon, when we could have tested the class - including its private methods - through the public methods. I've done this lots of times, and it can result in lots and lots of unnecessary interfaces and extra classes. There's no perfection, just our best efforts to balance it.
One more thought: We tend to use interfaces to represent dependencies, but we don't have to. If what we're extracting was just a single private method, then perhaps we can represent it with a delegate or a Func instead, like this:
public class RefactoredClass
{
private readonly Func<int, string> _dependency;
public RefactoredClass(Func<int, string> dependency)
{
_dependency = dependency;
}
public string DoSomething(int value)
{
return _dependency(value);
}
}
Or we can use a delegate, which I like better than Func because it indicates what the function does.
Generally when a class implements an interface all members of an interface must be implemented, it does not go the other way around.
Also when implementing an interface member, the corresponding member of the implementing class must be public, non-static, and have the same name and parameter signature as the interface member. You can have methods, even public, in the class that are not defined in the interface.
On top of that, the interface itself provides no functionality that a class or struct can inherit in the way that it can inherit base class functionality. However, if a base class implements an interface, any class that's derived from the base class inherits that implementation.
Interface should represent just the required API without regard to unit-testing and smth else.
To test public-methods of class you should do nothing because Test-project has access to them. You just need to instantiate a class and inject all required dependency using Mock.
Example: testing class without any dependencies
Example: testing class with dependency
To test private methods of a class need to make them visible to test-project:
mark private methods as internal
make internal-method visible to test-project: add to AssemblyInfo.cs the directive [assembly: InternalsVisibleTo("Project.Tests")] (see InternalsVisibleToAttribute)
Is it possible to implement the interface in an abstract class and change the implemented interface method into abstract?
interface ITest
{
string GetData();
int ProcessData();
}
public abstract class MyAbstract:ITest
{
public int Process()
{
// some code
}
public abstract string GetData(); // Change the implemented method into abstract Is it Possible?
}
Yes, you can do it. Simply add the abstract keyword and remove the implementation. There's obviously a pitfall with this. Any class which inherits from your abstract class will have to implement GetData themselves now. Depending on how many classes are children of MyAbstract, this may lead to a lot of work and code duplication.
In your case, where the method in question is declared by the interface which MyAbstract implements, you can actually just drop GetData completely and rely on the declaration of this function in ITest.
I have a class similar to the following:
public abstract class Manager<T, TInterface> : IManager<T> where TInterface : IRepository<T>
{
protected abstract TInterface Repository { get; }
public virtual List<T> GetAll()
{
return Repository.GetAll();
}
}
This works perfectly fine, however, is there a way to get away from having the TInterface in the abstract class declaration and in the resulting class that extends my generic abstract class:
public class TestManager : Manager<TestObject, ITestRepository>, ITestManager
I am forced to use ITestRepository and make the Repository property abstract due to the fact that it can contain custom methods that I need to know about and be able to call.
As I continue to build layers, I will have to keep doing this process the whole way up the stack. Examples would be if I had a generic abstract controller or service layer:
public class TestService : Service<TestObject, ITestManager>, ITestService
Is there a better way to do this or is this the best practice to allow a generic class to call another generic class?
It seems that all you want to do is to make Manager<T> testable, and use a mock as a repository that you can query for special members.
If that's the case, maybe you can change your design to this:
public class Manager<T> : IManager<T> {
protected IRepository<T> Repository { get; set; }
// ...
public virtual List<T> GetAll() {
return Repository.GetAll();
}
}
Now, all the specifics of testing are in a testing subclass:
public class TestingManager<T> : Manager<T> {
public new ITestRepository<T> Repository {
get {
return (ITestRepository<T>)base.Repository;
}
set {
base.Repository = value;
}
}
}
When you write your unit tests, you create TestingManager<T> instances (referenced through TestingManager<T> declared variables and fields), and you provide them with a test repository. Whenever you query their Repository, you'll always get a strongly-typed test repository.
UPDATE:
There's another way to solve this, without a subclass. You declare your repository objects as test repositories that you pass to Manager<T>s and you query them directly, without going through the Manager<T>.
[Test]
public void GetAll_Should_Call_GetAll_On_Repository_Test() {
var testRepository = new TestRepository();
var orderManager = new Manager<Order>(testRepository);
// test an orderManager method
orderManager.GetAll();
// use testRepository to verify (sense) that the orderManager method worked
Assert.IsTrue(testRepository.GetAllCalled);
}
No, you can't get around it. You can try, but the result will be ugly and in some way incorrect. The reason is that you are asking generics not to be generic but still be generic.
If a new class uses a generic class, either in inheritance or composition, and it itself does not know enough to specify the type parameters to the generic class it is using, then it must itself be generic. It is analogous the method call chains, where a method may pass parameters along to another method. It can't make up the arguments to the inner method, but must rather take them as parameters itself from a caller that does know what they are. Type parameters are the same.
One thing that does make this feel like code smell is the fact that you can't have a variable of type Manager<,>. It has to be fully type-specified. One solution I've come up with is to have non-generic interfaces that the generic classes implement. These interfaces have as much of the public interface of the generic class as is possible (they can't have methods or properties that reference the type parameters). Then you can pass around variables of the type of the interface and not have to specify type parameters.
Example:
interface IExample {
string Name { get; }
void SomeNonGenericMethod(int i);
}
class Example<T> : IExample {
public string Name { get { ... } }
public void SomeNonGenericMethod(int i) {
...
}
public T SomeGenericMethod() {
...
}
}
This is something curious that I saw in my coding today.
Here is the sample code:
public class SomeClass
{
public IUtils UtilitiesProperty { get; set; }
}
public interface IUtils
{
void DoSomething();
}
public class Utils : IUtils
{
void DoSomething();
}
This compiles fine.
So what is UtilitiesProperty? Is it a Util? What if more than one class implemented IUTil? Would it fail the compile then?
It doesn't have any value until you give it one (or rather, it has the value null). If you assign it a Utils reference, then yes: it is a Utils, exposed via the IUtils interface. You can only give it null or things that implement IUtils.
It's a property that can hold an object that implements your IUtils interface. More classes can implement this interface and using the interface allows you a level of abstraction (the consumer doesn't care as long as the class adheres to the interface contract).
I'd suggest you read up on the use of interfaces, abstract classes and the like.
For example the MSDN docs.
I recently ran into a problem where it seems I need a 'static abstract' method. I know why it is impossible, but how can I work around this limitation?
For example I have an abstract class which has a description string. Since this string is common for all instances, it is marked as static, but I want to require that all classes derived from this class provide their own Description property so I marked it as abstract:
abstract class AbstractBase
{
...
public static abstract string Description{get;}
...
}
It won't compile of course. I thought of using interfaces but interfaces may not contain static method signatures.
Should I make it simply non-static, and always get an instance to get that class specific information?
Any ideas?
You can't.
The place to do this is with Attributes.
Eg
[Name("FooClass")]
class Foo
{
}
If you don't mind deferring to implementations to sensibly implement the Description property, you can simply do
public abstract string ClassDescription {get; }
// ClassDescription is more intention-revealing than Description
And implementing classes would do something like this:
static string classDescription="My Description for this class";
override string ClassDescription { get { return classDescription; } }
Then, your classes are required to follow the contract of having a description, but you leave it to them to do it sensibly. There's no way of specifying an implementation in an object-oriented fashion (except through cruel, fragile hacks).
However, in my mind this Description is class metadata, so I would prefer to use the attribute mechanism as others have described. If you are particularly worried about multiple uses of reflection, create an object which reflects over the attribute that you're concerned with, and store a dictionary between the Type and the Description. That will minimize the reflection (other than run time type inspection, which isn't all that bad). The dictionary can be stored as a member of whatever class that typically needs this information, or, if clients across the domain require it, via a singleton or context object.
If it is static, there is only one instance of the variable, I don't see how inheritance would make sense if we could do what you want to accomplish with static vars in derived classes. Personally I think you are going to far to try to avoid a instance var.
Why not just the classic way?
abstract class AbstractBase
{
protected string _Description = "I am boring abstract default value";
}
class Foo : AbstractBase {
public Foo() {
_Description = "I am foo!";
}
}
Combining static and abstract is somewhat meaningless, yes. The idea behind static is one need not present an instance of the class in order to use the member in question; however with abstract, one expects an instance to be of a derived class that provides a concrete implementation.
I can see why you'd want this sort of combination, but the fact is the only effect would be to deny the implementation use of 'this' or any non-static members. That is, the parent class would dictate a restriction in the implementation of the derived class, even though there's no underlying difference between calling an abstract or 'static abstract' member (as both would need a concrete instance to figure out what implementation to use)
A possible workaround is to define a Singleton of your derived class in your base class with the help of Generics.
import System;
public abstract class AbstractBase<T>
where T : AbstractBase<T>, new()
{
private static T _instance = new T();
public abstract string Description { get; }
public static string GetDescription()
{
return _instance.Description;
}
}
public class DerivedClass : AbstractBase<DerivedClass>
{
public override string Description => "This is the derived Class";
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(DerivedClass.GetDescription());
Console.ReadKey();
}
}
The trick is to tell your AbstractBase<T> some details about how DerivedClass is implemented:
It is newable with where T: new() so it can create a Singleton instance
It derives from itself with where T : AbstractBase<T> so it knows that there will be a implementation of Description
This way _instance contains the Description field which can be called in the static Method GetDescription().
This forces you to overwrite Descriptionin your DerivedClass and allows you to call its value with DerivedClass.GetDescription()
It's not static if it has to be called on an instance.
If you're not calling it on an instance, then there's no polymorphism at play (i.e. ChildA.Description is completely unrelated to ChildB.Description as far as the language is concerned).
You can...
In the abstract class...
protected abstract InWindow WindowInstance { get; set; }
In the derived class...
private static InWindow _instance;
protected override InWindow WindowInstance
{
get => _instance;
set => _instance = value;
}
You could make the "abstract" base method throw an Exception, so then a developer is "warned" if he tries to invoke this method on a child class without overriding.
The downside is that one might extend the class and not use this method. Then refer to other answers provided.