It is often recommended to "program to an interface, not an implementation". It is useful to promote separation of concerns, and helps with unit testing. However, I was thinking about API programming.
Let's say I wrote an API and that API used a lot of "programming to interfaces". Let's also say that the API was insanely popular and used by many external clients. If one of the interfaces in the API had to change, that would require apps using the API to be recompiled.
My question is, how is such an issue avoided (or the impact of such changes reduced), or is it unavoidable? I am not an API programer and would like to know the best practice here. It seems to me that changing an interface that has existed for a long time and is widely used is a bad idea.
Published interfaces should never change. In the case that you have to augment functionality, just add a new interface.
To quote from MSDN:
When you create an interface, you are
creating a definition that can never
change after the interface definition
has been released. This interface
invariance is an important principle
of component design, because it
protects existing systems that have
been written to use the interface.
When an interface is clearly in need
of enhancement, a new interface should
be created. This interface might be
named by appending a "2" onto the
original interface name, to show its
relationship to the existing
interface.
I think a distinction can be made here between APIs to services and APIs to libraries.
In the case of services, those APIs should not be broken. Adding interfaces to these will not impact existing consumers.
Changing a library API only requires a recompile if the consumer wants to use the newer version of the library. This is likely going to go along with a recompile anyway, and simply adding to the interface won't require existing code change (you can mark deprecated methods with attributes, if applicable).
If you actually need to make a breaking change to the API, then yes, consumers will have to change their code to make it buildable.
While this is not to be taken lightly, there are many very popular libraries whose APIs have changed significantly over time (Fluent NHibernate comes to mind), and from my perspective, at least, the pain of updating my project is minimal, especially given the improvements that come along with those updates.
I think that for libraries, there is an expectation that some adaptation may be required when adopting a new version. Likewise, there is an expectation that where the API does not change, working code should not be rendered broken by a new version.
Related
I saw in many places whenc# programmers uses 3-tire architecture, they tend to use interfaces between each layer. for example, if the solution is like
SampleUI
Sample.Business.Interface
Sample.Business
Sample.DataAccess.Interface
Sample.DataAccess
Here UI calls the business layer through the interface and business calls the data access in the same fashion.
If this approach is to reduce the dependency between the layers, it's already in place with class library without additional use of the interface.
The code sample is below,
Sample.Business
public class SampleBusiness{
ISampleDataAccess dataAccess = Factory.GetInstance<SampleDataAccess>();
dataAccess.GetSampledata();
}
Sample.DataAccess.Interface
public interface IsampleDataAccess{
string GetSampleData();
}
Sample.DataAccess
public class SampleDataAccess:ISampleDataAccess{
public string GetSampleData(){
returns data;// data from database
}
}
This inference in between does any great job?
What if I use newSampleDataAccess().SampleData() and remove the complete interface class library?
Code Contract
There is one remarkable advantage of using interfaces as part of the design process: It is a contract.
Interfaces are specifications of contracts in the sense that:
If I use (consumes) the interface, I am limiting myself to use what the interface exposes. Well, unless I want to play dirty (reflection, et. al) that is.
If I implement the interface, I am limiting myself to provide what the interface exposes.
Doing things this way has the advantage that it eases dividing work in the development team among layers. It allows the developers of a layer to provide an cough interface cough that the next layer can use to communicate with it… Even before such interface has been implemented.
Once they have agreed on the interface - at least on a minimum viable interface. They can start developing the layers in parallel, known that the other team will uphold their part of the contract.
Mocking
A side effect of using interfaces this way, is that it allows to mock the implementation of the component. Which eases the creation of unit tests. This way you can test the implementation of a layer in isolation. So you can distinguish with ease when a layer is failing because it has a defect, and when a layer is failing because the layer below it has a defect.
For projects that are develop by a single individual - or by a group that doesn't bother too much in drawing clear lines to separate work - the ability to mock might be their main motivation to implement interfaces.
Consider for example, if you want to test if your presentation layer can handle paging correctly… But you need to request data to fill those pages. It could be the case that:
The layer below is not ready.
The database does not have data to provide yet.
It is failing and they do not know if the paging code is not correct, or the defect comes from a point deeper in the code.
Etc…
Either way the solution is mocking. In addition, mocking is easier if you have interfaces to mock.
Changing the implementation
If - for whatever reason - some of the developer decides they want to change the implementation their layer, they can do so trusting the contract imposed by the interface. This way, they can swap implementation without having to change the code of the other layers.
What reason?
Perhaps they want to test a new technology. In this case, they will probably create an alternative implementation as an experiment. In addition, they will want to have both versions working so they can test which one works better.
Addendum: Not only for testing both versions, but also to ease rolling back to the main version. Of course, they might accomplish this with source version control. Because of that, I will not consider rolling back as a motivation to use interfaces. Yet, it might be an advantage for anybody not using version control. For anybody not using it… Start using it!
Or perhaps they need to port the code to a different platform, or a different database engine. In this case, they probably do not want to throw away the old code either… For example, if they have clients that run Windows and SQL Server and other that run Linux and Oracle, it makes sense to maintain both versions.
Of course, in either case, you might want to be able to implement those changes by doing the minimum possible work. Therefore, you do not want to change the layer above to target a different implementation. Instead you will probably have some form of factory or inversion of control container, that you can configure to do dependency injection with the implementation you want.
Mitigating change propagation
Of course, they may decide to change the actual interfaces. If the developers working on a layer need something additional on the interface they can add it to the interface (given whatever methodology the team has set up to approve these changes) without going to mess with the code of the classes that the other team is working on. In source version control, this will ease merging changes.
At the end, the purpose of using a layer architecture is separation of concerns. Which implies separation of reason of change… If you need to change the database, your changes should not propagate into code dedicated to present information to the user. Sure, the team can accomplish this with concrete classes. Yet, interfaces provide a good and evident, well defined, language supported, barrier to stop the propagation of change. In particular if the team has good rules about responsibility (No, I do not mean code concerns, I mean, what developer is responsible of doing what).
You should always use an abstraction of the layer to have the ability
to mock the interfaces in unit tests
to use fake implementations for faster development
to easily develop alternative implementations
to switch between different implementations
...
WCF beginner's question: I've been told that changing the WCF contract is costly and requires constant maintenance (recreating the proxy in the client side), and therefore the preferred method is having one very generic point-of-contact method (which decides how to act, say, according to a given enum parameter).
This sounds quite smelly to me, but I haven't been able to find any information about this issue (bad choice of search keywords? probably).
Any advice, or maybe a useful link?
Thanks!
You don't need to generate the proxy again, you can simply ensure the client is built with the correct interface version. If you're very careful and only add methods, not remove or modify, that works just fine too. That's a lot of responsibility to manage, of course.
To use an interface rather than generate a client proxy, check my question from a while ago:
WCF Service Reference generates its own contract interface, won't reuse mine
You are confusing some terms here and I think you might be referring to a known flaw which has been fixed in .Net 3.5 SP1.
Recreating the WCF proxy used to be an expensive operation at runtime. This has been improved in .Net 3.5 to cache the proxy objects transparently MSDN Blog.
If you are referring to the "code maintenance" of the proxy, then all you are referring to is implementing an interface at the client. If you need to maintain the interface then this comes back to basic SOA. If your services provide access and as much information as possible, assuming that your service will be used for purposes you haven't yet considered then you will likely not need to modify the interface after it is created. You should also consider your upgrade paths as well.
Juval Lowy has a good discussion about this problem in his book which is a little dense but has some pretty good information in it.
A piece of advice: WCF has a whole lot of features designed to make your code really simple and elegant. If you are worreid about maintenance, what you may be driven to do is write an interface:
string ServiceMethod(string xml) //returns XML
Don't do this. Take the time to design a good maintainable interface and a good data/message contract. This will let WCF provide all the extras you get for free when hosting your service for interaction.
Generic (as in non-specific, monolithic) interfaces are hard to understand and program to. The reason not to define a single method as the API is that it's impossible for clients to understand what's going on, and when you change the (implicit) API of this interface, your clients will break in horrible ways that you won't detect at compile time.
It's been a while since I touched WCF, but if your clients are internal (same codebase, versioning and deployment schemes), then regenerating the WCF proxies is very easy, and having a "strong" detailed API will make your life so much easier than a generic one.
It depends on what kind of change you mean. Change to the service contract is indeed costly and should not happen. Service contracts are (or should be) at a sufficiently high level of granularity that change is very rare.
More common are changes to the types which are exposed on the service. These changes are more common and therefore you do need to approach your change in such a way as to avoid breaking existing clients if possible.
There are several ways you can do this, such as exposing your types polymorphically using an interface, but the simplest way is to simply ensure that changes to your types on add new data member fields and make the new fields non-mandatory. If you can limit your changes to these then this is has the lowest impact to existing clients and enables new clients to use the new fields.
Hope this helps.
This is true that modifying the service contract (interface) would also required the client to recreate the proxy class at their end using the new published WSDL and may even require the client to change their code as par the new proxy. I don't think you can create such a generic interface that can handle all changes further down the road in the contract. A contract has to be written very carefully so that it doesn't change often and if there is a need to change the contract then it is better to deploy the service with a different version so that your old client can still work with the old version.
Let's assume I am in charge of developing a Scrabble game, being that one of the principal requirements of the client is the ability to later try out different ways and modes of the game. I already made a design that is flexible enough to support those kinds of changes. The only question left is what to expose to the client(objects' access modifiers), and how to organize it (how to expose my objects in namespaces/packages).
How should I define things such that the client can both easily use my standard implementation (a standard Scrabble game, and yet be able to make all the modifications that he wants? I guess what I need is a kind of framework, on which he can work on.
I organized my classes/interfaces in a non-strict layered system:
Data Types
Contains basic data types that might be used in the whole system. This package and its members can be accessed by anyone in the system. All its members are public.
Domain
Contains all the interfaces I've defined and that might be useful to be able to make client's new Scrabble's implementations. Also contains value types, like Piece, that are used in the game. All its members are public.
Implementations
Contains all the needed classes/code to implement my standard Scrabble game in a Implementations.StandardScrabble package. If the client decides to implement other variants of the game, he can create them in Implementations.XYZ, for example.
These classes are all package protected and the only thing that is available to the outside of the package is a Game façade. Uses both Domain and Data Types packages.
UI
Contains the UI class that I have implemented so that both the client and the users of the program can run the game (my implementation). Can access all the other layers.
There are several drawbacks to the way I am organizing things, the most obvious being that if the client wants to create its own version of the game, he will have to basically implement almost everything by himself(I share in the Domain the interfaces, but he can do almost nothing with them). I feel I should maybe pass all the Implementation's classes to the Domain and then only have a Façade that builds up my standard Scrabble in the Implementations namespace?
How would you approach this? Is there any recomended reading on how to build this kind of programs (basically, frameworks)?
Thanks
I think that you're trying to give too much freedom to a client. This must be making things that difficult for you to handle. Based on what you have described it seems that a client will be able to modify almost all parts of your game - model, logic, UI... I think it would be better to restrict modifiable areas in your application but expose some via general Plugin interface set. This would make it easier for a user as well - he will only need to learn how plugins work, not the entire application's logic. Define areas for your plugins if you want - UI plugin, game mode plugin and so on. Many production applications and games work in such way (recall Diablo II and that AMAZING variety of plugins it has!).
For the algorithms and strategies I would define interfaces and default implementations, and provide abstract superclasses which are extended by you own implementations, so that all the boilerplate code is in the abstract superclass. In addition I would allow the client to subclass your impl. Just make more than one impl, and you see what to place where.
But most important: Give your client the code. If he needs to understand where to place his code, he should be able to see what you have coded, too. No need to hide stuff.
Whatever design you come up with, I would err on the side of hiding as much of the implementation as possible. Once you expose an implementation, you cannot take it back (unless you're ready to wage a flame war with your client base). You can always provide default implementations later as you see fit.
Generally, I'd start with only providing thin interfaces. Then, before providing abstract classes, I might offer utility classes (e.g., Factories, Builders, etc.).
I'd recommend reading Effective Java by Josh Bloch for useful general practices when designing object-oriented code.
MVC/Compund Pattern
You may release earlier version of your package.
later on you can upgrade it based on user requirement.
If you are using MVC or other compound pattern wisely, I believe you also can upgrade your package easily.
I often hear/read about interfaced based programming but I am not exactly clear on what that really means. Is interfaced based programming an actual stand alone topic that actually has books written about it? If so, can anyone recommend any good ones?
I came across interface based programming as I was reading about how good APIs are designed and would like to learn more about it. Right now I am not clear how to properly go about designing an API around interfaces.
Any info is greatly appreciated.
It's basically a matter of expressing your dependencies in terms of interfaces instead of concrete classes (or worse, static methods). So if one of your classes needs to perform authentication, it should be provided an IAuthenticator (or whatever).
This means that:
You can write your code before implementing the real dependency
You can test via mocking really easily (without having to mock classes, which gets ugly)
It's clear what you depend on in terms of the API instead of implementation (i.e. you have looser coupling)
See if these very popular discussions help:
What is the best analogy to help non-oop developers grok interface based programming?
Why would I want to use Interfaces?
When are interfaces needed?
When should one use interfaces?
What is the purpose of interfaces?
Good Case For Interfaces
What does it mean to “program to an interface”?
Chapter 6 of "Practical API Design" by Jaroslav Tulach is titled "Code Against Interfaces, Not Implementations". It explains that, by coding against an interface rather than a specific implementation, you can decouple modules (or components) in a system and therefore raise the system quality.
Bertrand Meyer in OOSC2 explains clearly why "closing" a system and making it more modular raises its quality.
What you refer to as "interface based programming" is more commonly referred to as programming to an interface. Here is an example below. The benefit is hiding the actual implementation of the interface and allowing your code to be more flexible and easily maintained in the future.
YourInterface foo = CreateYourInterface();
foo.DoWork();
foo.DoMoreWork();
CreateYourInterface() would return a concrete implementation of YourInterface. This allows you to change the functionality of the application by changing one line:
YourInterface foo = CreateYourInterface();
If you google for interfaces, you will find plenty of information about how useful interfaces may be.
The concept is to define clear interfaces, which will be used by the various components/parts/classes/modules to communicate and interact. Once you have defined what should be the input/output of these interfaces, you can let the various teams to develop whatever is needed to fulfill the interface requirements, including the input/output testing, ... etc
If you follow this pattern, various teams can start developing their part without waiting for the other parts to be ready. In addition to that you can use Unit testing (using fake objects to simulate the other parts which you are not developing, and test your part).
This method is quite the standard for any new programming project and everybody will take this for granted.
This is something that I don't recommend using heavily in C# development.
Interface-based programming is basically programming to interfaces. You develop the interfaces you're going to use an Contracts, and the actual implementation of the interfaces is hidden behind these contracts.
It was very common prior to .NET, as the best way to get reusable components in Windows was via COM, which worked via interfaces everywhere. However, given .NET's ability to support multiple languages with a single runtime (the CLR), as well as it's superior support for versioning when compared with native code, the usefulness of interface based programming is lessened dramatically when you're programming in C# (unless you're trying to make COM components, in which case, you'll still be creating the COM interfaces indirectly from your C# classes).
Interface based programming can be thought of as decoupling the implementation of functionality and how you access the functionality.
You define an interface
interface ICallSomeone {
public bool DialNumber(string number);
}
and you write your implementation
public class callsomeone: ICallSomeone {
public bool DialNumber(string number) {
//dial number, return results
}}
You use the interface without caring about the implementation. If you change the implementation, nothing cares because it just uses the interface.
From a very abstract view, interface based programming is akin to the components used by a plumber (pipe joints and pipes).
As long as the pipes and the joints are manufactured according to the interface specified (the number of threads and the spacing, etc) various manufactures can provide joints to pipes that were potentially manufactured by some other vendor (but adhering to the aforementioned joint/pipe interface).
Thus, there is more interoperability of components and freedom for the plumber to choose from various vendors, price ranges etc in order to create a functional plumbing system.
Replace the pipes and joints with software components and the parallels are astonishingly simple.
This is more like a good practise question. I want to offer different generic libraries like Logging, caching etc. There are lots of third party libraries like MS enterprise library, log4Net, NCache etc for these.
I wanted to know if its a good practise to use these directly or create wrapper over each service and Use a DI to inject that service in the code.
regards
This is subjective, but also depends on the library.
For instance, log4net or NHibernate have strictly interface based API's. There is no need to wrap them. There are other libraries which will make your classes hard to test if you don't have any interfaces in between. There it might be advisable to write a clean interface.
It is sometimes good advise to let only a small part of the code access API's like for instance NHibernate or a GUI library. (Note: This is not wrapping, this is building abstraction layers.) On the other side, it does not make sense to reduce access to log4net calls, this will be used in the whole application.
log4net is probably a good example where wrapping is just overkill. Some people suffer of "wrappitis", which is an anti-pattern (sometimes referred to as "wrapping wool in cotton") and just produces more work. Log4net has such a simple API and is highly customizable, they made it better then your wrapper most probably will be.
You will find out that wrapping a library will not allow you to just exchange it with another product. Upgrading to newer versions will also not be easier, rather you need to update your wrapper for nothing.
If you want to be able to swap implementations of those concepts, creating a wrapper is the way to go.
For logging there already is something like that available Common.Logging.
Using wrapping interfaces does indeed make unit testing much easier, but what's equally important, it makes it possible to use mocks.
As an example, the PRISM framework for Silverlight and WPF defines an ILoggerFacade interface with a simple method named Log. Using this concept, here's how I define a mocked logger (using Moq) in my unit tests:
var loggerMock = new Mock<ILoggerFacade>(MockBehavior.Loose);
loggerMock.Setup(lg => lg.Log(It.IsAny<string>(), It.IsAny<Category>(), It.IsAny<Priority>()))
.Callback((string s, Category c, Priority p) => Debug.Write(string.Format("**** {0}", s)));
Later you can pass loggerMock.Object to the tested object via constructor or property, or configure a dependency injector that uses it.
It sounds like you are thinking of wrapping the logging implementation and then sharing with different teams. Based on that here are some pros and cons.
Advantages of Wrapping
Can abstract away interfaces and
dependencies from implementation.
This provides some measure of protection against breaking changes
in the implementation library.
Can
make standards enforcement easier and
align different project's
implementations.
Disadvantages of Wrapping
Additional development work.
Potential additional documentation
work (how to use new library).
More
likely to have bugs in the wrapping
code than mature library. (Deploying your bug fixes can be a big headache!)
Developers
need to learn new library (even if
very simple).
Can sometimes be
difficult to wrap an entire library
to avoid leaking implementation
interfaces. These types of wrapper
classes usually offer no value other
than obfuscation. e.g. MyDbCommand
class wraps some other DbCommand
class.
I've wrapped part of Enterprise Library before and I didn't think it added much value. I think you would be better off:
Documenting the best practices and usage
Providing a reference implementation
Verifying compliance (code reviews
etc.)
This is more of a subjective question but IMO it's a good thing to wrap any application/library specific usage into a service model design that has well thought out interfaces so you can easily use DI and later if you ever need to switch from say EntLib Data Application Block to NHibernate you don't need to re-architect you're whole application.
I generally create a "helper" or "service" class that can be called statically to wrapper common functionality of these libraries.
I don't know that there is a tremendous amount of risk in directly referencing/calling these, since they are definitely mature projects (at least EntLib and Log4Net), but having a wrapper isolates you from the confusion of version change, etc. and gives you more options in the future, at a fairly low cost.
I think it's better to use a wrapper, personally, simply because these are things you don't want to be running when your unit tests run (assuming you're unit testing also).
Yes if being able to replace the implementation is a requirement now or in a reasonable future.
No otherwise.
Defining the interface that your application will use for all logging/enterprising/... purposes is the core work here. Writing the wrapper is merely a way to make the compiler enforce use of this interface rather than the actual implementation.