开发者

C# - Is adding systematically an interface a good practice?

In the project I'm working on, I've noticed that for every entity class there is an interface. It seems that the original motivation was to only expose interfaces to other project/solutions.

I find this completely useless, and I don't see the point in creating an interface for every class. By the way, those classes don't have any me开发者_Python百科thods just properties and they don't implement the same interface.

Am I wrong? Or is it a good practice?

Thx


I tend to create an interface for almost every class mainly because of unit testing - if you use dependency injection and want to unit test a class that depends on the class in question, than the standard way is to mock an instance of the class in question (using one of the mocking frameworks, e.g. Rhino-Mocks). However, practically it is only possible only for interfaces, not concrete implementations (yes, theoretically you can mock a concrete class, but there are many painful limitations).


There may be more to the setup than described here that justifies the overhead of interfaces. Generally they're very useful for dependency injection and overall separation of concerns, unit testing and mocking, etc.. It's entirely possible that they're not being used for this purpose (or any other constructive purpose, really) in your environment, though.

Is this generated code, or were these manually created? If the former, I suspect the tool generating them is doing so to prepare for such a use if the developer were so inclined. If the latter, maybe the original designer had something in mind?

For my own "best practices" I almost always do interface-driven development. It's generally a good practice to separate out concerns from one another and use the interfaces as contracts between them.


Exposing interfaces publicly has value in creating a loosely-coupled, behaviour-driven architecture.

Creating an interface for every class - especially if the interface just exposes every public method the class has in a single interface - is a bad implementation of the concept, and (in my experience) leads to more complex code and no improvement in architecture.


It's useful for tests.

A method may take a parameter of type ISomething, and it can be either SqlSomething or XmlSomething, where ISomething is the interface, and SqlSomething and XmlSomething are classes that implement the interface, depending whether you're doing tests (you pass XmlSomething in this case) or running the application (SqlSomething).

Also, when building a universal project, that can work on any database, but aren't using an ORM tool like LINQ (maybe because the database engine might not support LINQ to SQL), you define interfaces, with methods that you use in the application. Later on, developers will implement the interfaces to work with the database, create MySQLProductRepository class, PostgreSQLProductRepository class, that both inherit the same interface, but have different functionality.

In the application code any method takes a parameter a repository object of type IProductRepository, which can be anything.


IMHO it sounds that writing interfaces for no reason is pointless. You cant be totally closed minded but in general doing things that are not immediatly useful tend to accumulate as waste.

The agile concept of Its either adding value or taking value comes to mind.

What happens when you remove them? If nothing then ... what are they there for?

As a side note. Interfaces are extremely useful for Rhino Mocks, dependency injection and so on ...


If those classes only have properties, then interfaces don't add much value, because there's no behavior that is being abstracted.

Interfaces can be useful for abstraction, so the implementation can be mocked in unit tests. But in a well-designed application the business/domain entities should have very little reasons to be mocked. Business/domain services on the other hand are a excellent candidate for interface abstraction.

I have created interfaces for my entities once, and it didn't add any value at all. It only made me realize my design was wrong.


It seems to be an interface is superior to an abstract base class primarily if/when it is necessary to have a class which implements the interface but inherits from some other base class. Multiple inheritance is not allowed, but multiple interface implementations are.

The main caveat I see with using interfaces rather than abstract classes (beyond the extra source code required) is that changing anything in an interface necessitates recompilation of any and all code which uses that interface. By contrast, adding public members to a base class generally only requires recompilation of the base class itself.(*)

(*) Due to the way extension methods are handled, adding members to a class won't "require" recompiling code which uses that class, but may cause code which uses extension methods on the class to change meaning the next time it (the extension-method-using code) is recompiled.


There is no way to tell the future and see if you're going to need to program against an interface down-the-road. But if you decide later to make everything use an interface and, say, a factory to create instances of unknown types (any type that implements the interface), then it is quicker to restrict everyone to programming against an interface and a factory up-front than to replace references to MyImpl with references to IMyInterface later, etc.

So when writing new software, it is a judgment call whether to program against an interface or an implementation, unless you are familiar with what is likely to happen to that kind of software based on previous experiences.

I usually keep it "in flux" for a time whether or not I have an interface, a base class, or both, and even whether the base class is abstract (it usually is). I will work on a project (usually a Visual Studio solution with about 3 to 10 projects in it) for a while (a couple of days, maybe) before I refactor and / or ask for a second opinion. Once a final decision is reached and the code is refactored and tested, I tell fellow devs that it is ready for use.


For unit testing, it's either interfaces everywhere or virtual methods everywhere.

Sometimes I miss Java :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜