Here is my question...
I work in Telecom industry and have a piece of software which provides the best network available for a given service number or a site installation address. My company uses the network of the wholesale provider and we have our own network as well. To assess what services a customer might be able to get, I call a webservice to find out the services available on a given telephone exchange and based on the services available, I need to run some checks against either our network or the network of the wholesale provider.
My question is how this can be modelled using interfaces in C#? The software that I have does not make use of any interfaces and whatever classes are there are just to satisfy the fact that code cannot live outside classes.
I am familiar with the concept of interfaces, at least on theoretical level, but not very familiar with the concept of programming to interfaces.
What I am thinking is along the following lines:
Create an interface called IServiceQualification which will have an operation defined : void Qualify(). Have two classes called QualifyByNumber and QualifyByAddress and both of these implement the interface and define the details of the operation Qualify. Am I thinking along the right lines or is there a different/better way of approaching this issue.
I have read a few examples of programming to interfaces, but would like to see this utilized in a work situation.
Comments/suggestions are most welcome.
I would probably make it go a little bit deeper, but you are on the right track. I would personally create IServiceQualification with a Qualify method and then below that an abstract class called ServiceQualification which would have an abstract method called Qualify that any kind of qualifier class could implement. This lets you define common behavior among your qualifiers (there is bound to be some) while still creating the separation of concerns at a high level.
Interfaces have a defined purpose and using them properly lets you implement in any way you want without having your code require that implementation. So, we can create a service that looks something like:
public bool ShouldQualify(IServiceQualification qualification)
And no matter the implementation we send it, this method will work. It becomes something you never have to change or modify once its working. Additionally, it leads you directly to bugs. If someone reports that qualifications by address aren't working, you know EXACTLY where to look.
Take a look at the strategy design pattern. Both the problem and the approach that you have described sound like a pretty close fit.
http://www.dofactory.com/Patterns/PatternStrategy.aspx
You should think of interfaces in terms of a contract. It specifies that a class implements certain function signatures meaning you class can call them with known parameters and expect a certain object back - what happens in the middle is upto the developer of the interface to decide. This loose coupling makes your class system a lot more flexible (it has nothing to do with saving key strokes surfash)
Heres an example which is roughly aimed at your situation (but will require more modelling).
public interface IServiceQualification{
bool Qualifies(Service serv);
}
public class ClientTelephoneService : IServiceQualification
{
public bool Qualifies(Service serv){
return serv.TelNumber.Contains("01234");
}
}
public class ClientAddressService : IServiceQualification
{
public bool Qualifies(Service serv){
return serv.Address.Contains("ABC");
}
}
//just a dummy service
public class Service{
public string TelNumber = "0123456789";
public string Address = "ABC";
}
//implementation of a checker which has a list of available services and takes a client who implements the
//interface (meaning we know we can call the Qualifies method
public class ClassThatReturnsTheAvailableServices
{
//ctor
List<Service> services = //your list of all services
public List<Service> CheckServices(IServiceQualification clientServiceDetails)
{
var servicesThatQualify = new List<Service>();
foreach(var service in services){
if(clientServiceDetails.Qualifies(service)){
services.Add(service);
}
}
return servicesThatQualify;
}
}
Related
I have an application with a service class that retrieves database metadata from a database and returns it to calling classes.
To connect to the database, the service class methods accept a parameter that details the connection credentials.
I'm considering a change whereby the credentials would be stored within the service class. One of the reasons for this is that calling classes (which have the responsibility, for example, of comparing schemas on different servers) may connect to multiple different databases/servers, so the calling class would basically have a collection of these service classes, rather than a collection of connection credentials (e.g., IConnectionInfo in the following example).
Another thing I might like to do within the application is to have implementation of this service class (IDatabaseService in the following example) for different types of RDBMS (e.g., SQL Server, Oracle, etc.), and this seems like the best way of leaving it open to that (the information returned from the service would be very generic and applicable to all supported types of RDBMS).
Example code for what the service class might look like:
public class DatabaseService : IDatabaseService
{
private readonly IConnectionInfo ConnectionInfo;
public bool IsConnected; // INotifyPropertyChanged
public string ServerName => IConnectionInfo.ServerName;
public string DatabaseName => IConnectionInfo.DatabaseName;
public DatabaseService(IConnectionInfo connectionInfo)
{
ConnectionInfo = connectionInfo;
}
public IEnumerable<Table> GetTables()
{
...
}
public IEnumerable<Column> GetTableColumns(Table table)
{
...
}
}
There are a few reasons I'm a bit doubtful of this approach:
I'm implementing INotifyPropertyChanged within this class so that I can update the UI to show the user whether or not they are connected (e.g., I could switch this to false if any calls to the server failed). For this reason it seems to behave like a ViewModel (as opposed to a Service).
I'm unsure as to whether it's good practice to have properties on a service class that represent its state, e.g., ConnectionInfo, IsConnected.
Does the above look like an acceptable design?
Update: Further Thoughts and Explanation
I suppose the specific programming problem I'm trying to solve is that, for example, I might have a class for SQL Server credentials, and a class for Oracle credentials, both of which would be IConnectionCredentials. I would then have several corresponding implementations of IDataService, which would accept IConnectionCredentials as an argument. The issue would be that not all implementations of IDataService would work with all implementations of IConnectionCredentials, which seems flawed to me, and so I thought it would make sense to combine the data access layer and the "data accessor" object into one class. I suppose it might be feasible to have IDataService contain logic to determine which version of the "real" data access interface to use. For example:
public class DataService : IDataService
{
private readonly RealDataServiceFactory RealDataServiceFactory;
public IEnumerable<Table> GetTables(IConnectionCredentials connectionCredentials)
{
return RealDataServiceFactory.Create(connectionCredentials).GetTables(connectionCredentials);
}
}
public class RealDataServiceFactory
{
public IRealDataService Create(IConnectionCredentials connectionCredentials)
{
if (connectionCredentials is SqlServerConnectionCredentials)
{
return new SqlServerDataService();
}
else if ...
}
}
Another reason I wanted the IsConnected property in the data access class is because there are other reasons that the service might not return data other than the connection not working, and I didn't feel the logic to determine that belonged in the calling class, and so liked the idea that the data service could simultaneously return null to some call and also state to the application and UI, "there's a problem with my connection". In the above implementation, I would also lose this, though I suppose it could be achieved by the data service marking IsConnected as false on the incoming IConnectionCredentials before returning.
It's ultimately up to you what to do, but it sounds like this design conflates two (or more?) concerns into one:
User interface updates (INotifyPropertyChanged)
Data access
This gives the class more than a single reason to change. In other words, it violates the Single Responsibility Principle (SRP).
Now, no-one says that you must obey the SRP. This, and the other SOLID principles, are guidelines for dealing with certain kinds complexity. If you don't have the problems that SOLID addresses, then you don't have to follow those principles.
In practice, though, it can be hard to predict future problems. A code base is rarely problematic from the outset. It slowly devolves from something simple to something more complicated.
While the proposed design sounds like it has mixed concerns (as opposed to separation of concerns), perhaps it's benign in practice. After all, INotifyPropertyChanged is a base class library interface, so you're aren't introducing coupling to some specific technology. I'd be wary of expanding the scope of UI-related updated on that class, though.
I have a class which contains a view dependencies (all interfaces). Basically the behavior of the class is defined through the implementation of those interfaces. I want to be able to have a "builder" which can create instances of this class with different implementations of the interfaces(or parts of it). Something like this:
public class API
{
private readonly ISomeInterface _someInterface;
private readonly ISomeOtherInterface _someOtherInterface;
private readonly ISomeAnotherInterface _someAnotherInterface;
API(ISomeInterface someInterface,ISomeOtherInterface someOtherInterface,ISomeAnotherInterface someAnotherInterface)
{*/implementation ommitted*/}
//Example method
public void DoSomethingWhichDependsOnOneOrMoreInterfaces()
{
//somecode
id(_someInterface != null)
_someInterface.SomeMethode();
}
public class MyApiBuilder()
{
// implementation ommitted
API CreateAPI(someEnum type)
{
switch(type)
{
case SpecificAPI32:
var speficImplementationOfSomeInterface = new ImplementsISomeInterface();
speficImplementationOfSomeInterface .Setup("someSetup");
var specificImplementationOfOtherInterface = new ImplementsISomeOtherInterface();
returns new API(speficImplementationOfSomeInterface,specificImplementationOfOtherInterface ,null);
}
}
}
What is the most elegant way of implementing this (if this makes sense at all)? I was first thinking of the Builder Design Patterns but as far as I understood it, its slightly different.
[Edit]
As pointed out, the way I am implementing it is a factory method but I am not fully satisfied with it. The API can contain a varity of different interfaces which can be totally independent of each other but some may depend on others.(but not mandatory) I would like to give the user (the developer using this "API") as much freedom as possible in creating the API he wants to use. Lets try to explain what I am basically up to:
Let's say I am developing a plugin for a game engine which can post achievments and other stuff to various social media channels. So basically there could be a Interface which implements the access to twitter,facebook,youtube,whathever or some custom server. This custom server could need some kind of authentification process. The user should be able to build at start the API in a nice (hmm fluent is nice..) way. So basically something like this:
var myTotallyForMyNeedsBuildAPI = API.CreateCustomApi().With(Api.Twitter).And(Api.Facebook).And(Api.Youtube).And(Api.CustomServer).With(Security.Authentification);
I actually do not know how to make that fluent but something like this would be nice.
It's a good practice to use Dependency Injection as you want to give the programmer the ability to compose the object with desired configuration.
Check MEF and Unity frameworks which are great for this job.
For example in Unity you can write this:
// Introducing an implementation for ISomeInterface
container.Register<ISomeInterface, SomeImplementation>();
// Introducing an implementation for ISomeOtherInterface
container.Register<ISomeOtherInterface, SomeOtherImplementation>();
// Introducing an implementation for ISomeAnotherInterface
container.Register<ISomeAnotherInterface, SomeAnotherImplemenation>();
container.Register<API, API>();
// and finally unity will compose it for you with desired configurations:
var api = container.Resolve<API>();
In this scenario the api will be composed with desired implementations.
What you have implemented is the Factory method pattern.
It's perfectly fine for what you are trying to do, but you could have a look at the other factory patterns (i.e. here) based on your context and how you think you're code will evolve in the future.
Anyway, I will also consider to not tie this three interface together in a single factory. If they are really so tighten together to be consumed together and built together, maybe they should not be three different interfaces in the first place, or at least all three implemented by the same class, so your factory will build the appropriate class with the proper implementation of these.
Probably what you are after is the Decorator pattern.
In your API class you invoke each interface if they have been provided to the API instance, which is the behaviour of the Decorator pattern.
With this pattern you obtain a modular implementation that allow you to add multiple behaviours to your API.
In my earlier question I was asking about implementing repository/unit of work pattern for large applications built with an ORM framework like EF.
One followup problem I cannot come through right now is where to put codes containing business logic, but still lower-level enough to be used commonly in many other part of the application.
For example here is a few such method:
Getting all users in one or more roles.
Getting all cities where a user has privileges within an optional
region.
Getting all measure devices of a given device type, within a given
region for which the current user has privileges.
Finding a product by code, checking if it's visible and throwing
exception if not found or not visible.
All of these methods use a UnitOfWork for data access or manipulation, and receive several parameters as in their specification. I think everyone could write a lot more example for such common tasks in a large project. My question is where shall I put tese method implementations? I can see the following options currently.
Option 1: Every method goes to its own service class
public class RegionServices {
// support DI constructor injection
public RegionServices(IUnitOfWork work) {...}
...
public IEnumerable<City> GetCitiesForUser(User user, Region region = null) { ... }
...
}
public class DeviceServices {
// support DI constructor injection
public DeviceServices(IUnitOfWork work) {...}
...
public IEnumerable<Device> GetDevicesForUser(User user, DeviceType type, Region region = null) { ... }
...
}
What I don't like about it is that if a higher-level application service needs to call for example 3 or these methods, then it needs to instantiate 3 services, and if I use DI then I even have to put all 3 into the constructor, easily resulting quite a bit of code smell.
Option 2: Creating some kind of Facade for such common data access
public class DataAccessHelper {
// support DI constructor injection
public DataAccessHelper(IUnitOfWork work) {...}
...
public IEnumerable<City> GetCitiesForUser(User user, Region region = null) { ... }
public IEnumerable<Device> GetDevicesForUser(User user, DeviceType type, Region region = null) { ... }
public IEnumerable<User> GetUsersInRoles(params string[] roleIds) { ... }
...
}
I don't like it because it feels like violating the SRP, but its usage can be much more comfortable however.
Option 3: Creating extension methods for the Repositories
public static class DataAccessExtensions {
public static IEnumerable<City> GetCitiesForUser(this IRepository repo, User user, Region region = null) { ... }
}
Here IRepository is an interface with generic methods like Query<T>, Save<T>, etc. I don't like it either because it feels like I want to give business logic to repositories which is not advisable AFAIK. However, it expresses that these methods are common and lower level than service classes, which I like.
Maybe there are other options as well?... Thank you for the help.
If you say that a certain piece of domain logic needs to look at 3 distinct pieces of information in order to make a decision then we will need to provide this information to it.
Further if we say that each of these distinct pieces can be useful to other parts of the domain then each of them will need to be in its own method also. We can debate whether each query needs to be housed in a separate class or not depending on your domain/design.
The point I wanted to make is that there will be a application service which delegates to one or more Finder classes (classes where your queries are housed), these classes house only queries and then accumulate the results and pass it down to a Domain Service as method params.
The domain service acts on on the received parameters executes the logic and returns the result. This way the domain service is easily testable.
psuedo code
App Service
result1 = finder.query1()
result2 = finder.query2()
result3= yetanotherfinder.query();
domainresult = domainservice.calculate(result1,result2,result3);
Repositories belong to the domain, queries do not (http://www.jefclaes.be/2014/01/repositories-where-did-we-go-wrong_26.html).
You could define explicit queries and query handlers and use those outside of your domain.
public class GetUserStatisticsQuery
{
public int UserId { get; set; }
}
public class GetUserStatisticsQueryResult
{
...
}
public class GetUserStatisticsQueryHandler :
IHandleQuery<GetUserStatisticsQuery, GetUserStatisticsQueryResult>
{
public GetUserStatisticsQueryResult Handle(GetUserStatisticsQuery query)
{
... "SELECT * FROM x" ...
}
}
var result = _queryExecutor.Execute<GetUserStatisticsQueryResult>(
new GetUserStatisticsQuery(1));
I'm adding my conclusion as an answer, because I quickly realized that this question is quite relative and not exact, heavily depends on personal favours or design trends.
The comments and the answers helped me in seeing more clearly how things like this should basically be implemented, thank you for all of your effort.
Conclusion
A "repository" should be responsible clearly only for data persisting. Because it doesn't hold any domain logic, or type specific logc, I think it can be represented and implemented as an IRepository interface with generic methods like Save<T>, Delete<T>, Query<T>, GetByID<T>, etc. Please refer to my previous question mentioned in the beginning of my original post.
On the other hand, I think (at least now with my current project) that introducing new class/classes for each lower-level domain logic (in the most cases some kind of querying logic) task is a bit over-engineered solution, which is not needed for me. I mean I don't want to introduce classes like GetUsersInRoles or GetDevicesInRegionWithType, etc. I feel I would end up with a lot of classes, and a lot of boilerplate code when refering them.
I decided to implement the 3rd option, adding static query functions as extensions to IRepository. It can be nicely separated in a Queries project folder, and structured in several static classes each named after the underlying domain model on which it defines operations. For example I've implemented user related queries as follows: in Queries folder I've created a UserQueries.cs file, in which I have:
public static class UserQueries {
public static IEnumerable<User> GetInRoles(this IRepository repository, params string[] roles)
{
...
}
}
This way I can easily and comfortable access such methods via extensions on every IRepository, the methods are unit-testable and support DI (as they are callable on any IRepository implementation). This technique fits best for my current needs.
It can be refactored even further to make it even cleaner. I could introduce "ghost" sealed classes like UserQueriesWrapper and use it to structure the calling code and this way not put every kind of such extensions to IRepository. I mean something like this:
// technical class, wraps an IRepository dummily forwarding all members to the wrapped object
public class RepositoryWrapper : IRepository
{
internal RepositoryWrapper(IRepository repository) {...}
}
// technical class for holding user related query extensions
public sealed class UserQueriesWrapper : RepositoryWrapper {
internal UserQueriesWrapper(IRepository repository) : base(repository) {...}
}
public static class UserQueries {
public static UserQueriesWrapper Users(this IRepository repository) {
return new UserQueriesWrapper(repository);
}
public static IEnumerable<User> GetInRoles(this UserQueriesWrapper repository, params string[] roles)
{
...
}
}
...
// now I can use it with a nicer and cleaner syntax
var users = _repo.Users().GetInRoles("a", "b");
...
Thank you for the answers and comments again, and please if there is something I didn't notice or any gotcha with this technique, leave a comment here.
I've just reviewed some code that looked like this before
public class ProductChecker
{
// some std stuff
public ProductChecker(int AccountNumber)
{
var account = new AccountPersonalDetails(AccountNumber);
//Get some info from account and populate class fields
}
public bool ProductACriteriaPassed()
{
//return some criteria based on stuff in account class
//but now accessible in private fields
}
}
There has now been some extra criteria added which needs data not in the AccountPersonalDetails class
the new code looks like this
public class ProductChecker
{
// some std stuff
public ProductChecker(int AccountNumber)
{
var account = new AccountPersonalDetails(AccountNumber);
var otherinfo = getOtherInfo(AccountNumber)
//Get some info from account and populate class fields
}
public bool ProductACriteriaPassed()
{
//return some criteria based on stuff in account class
// but now accessible in private fields and other info
}
public otherinfo getOtherInfo(int AccountNumber)
{
//DIRECT CALL TO DB TO GET OTHERINFO
}
}
I'm bothered by the db part but can people spell out to me why this is wrong? Or is it?
In a layered view of your system, it looks like ProductChecker belongs to the business rules / business logic layer(s), so it shouldn't be "contaminated" with either user interaction functionality (that belongs in the layer(s) above) or -- and that's germane to your case -- storage functionality (that belongs in the layer(s) below).
The "other info" should be encapsulated in its own class for the storage layers, and that class should be the one handling persist/retrieve functionality (just like I imagine AccountPersonalDetails is doing for its own stuff). Whether the "personal details" and "other info" are best kept as separate classes or joined into one I can't tell from the info presented, but the option should be critically considered and carefully weighed.
The rule of thumb of keeping layers separate may feel rigid at times, and it's often tempting to shortcut it to add a feature by miscegenation of the layers -- but to keep your system maintainable and clean as it grows, I do almost invariably argue for layer separation whenever such a design issue arises. In OOP terms, it speaks to "strong cohesion but weak coupling"; but in a sense it's more fundamental than OOP since it also applies to other programming paradigms, and mixes thereof!-)
It seems like the extra data grabbed in getOtherInfo should be encapsulated as part of the AccountPersonalDetails class, and thus already part of your account variable in the constructor when you create a new AccountPersonalDetails object. You pass in AccountNumber to both, so why not make AccountPersonalDetails gather all the info you need? Then you won't have to tack on extra stuff externally, as you're doing now.
It definitely looks like there might be something going haywire with the design of the class...but it's hard to tell without knowing the complete architecture of the application.
First of all, if the OtherInfo object pertains to the Account rather than the Product you're checking on...it's introducing responsibilities to your class that shouldn't be there.
Second of all, if you have a Data Access layer...then the ProductChecker class should be using the Data Access layer to retrieve data from the database rather than making direct calls in to retrieve the data it needs.
Third of all, I'm not sure that the GetOtherInfo method needs to be public. It looks like something that should only be used internally to your class (if, in fact, it actually belongs there to begin with). In that case, you also shouldn't need to pass around the accountId (you class should hold that somewhere already).
But...if OtherInfo pertains to the Product you're checking on AND you have no real Data Access layer then I can see how this might be a valid design.
Still, I'm on your side. I don't like it.
considering that an accountNumber was passed into the constructor you shouldn't have to pass it to another method like that.
A few points
The parameter names are pascal case, instead of camel (this maybe a mistake)
getOtherInfo() looks like it's a responsibility of AccountPersonalDetails and so should be in that class
You may want to use a Façade class or Repository pattern to retrieve your AccountPersonalDetails instead of using a constructor
getOtherInfo() may also be relevant for this refactor, so the database logic isn't embedded inside the domain object, but in a service class (the Façade/Repository)
ProductACriteriaPassed() is in the right place
I would recommend this:
public class AccountPersonalDetails
{
public OtherInfo OtherInfo { get; private set; }
}
public class ProductChecker
{
public ProductChecker(AccountPersonalDetails) {}
}
// and here's the important piece
public class EitherServiceOrRepository
{
public static AccountPersonalDetails GetAccountDetailsByNumber(int accountNumber)
{
// access db here
}
// you may also feel like a bit more convinience via helpers
// this may be inside ProductCheckerService, though
public static ProductChecker GetProductChecker(int accountNumber)
{
return new ProductChecker(GetAccountDetailsByNumber(accountNumber));
}
}
I'm not expert in Domain-Driven Design but I believe this is what DDD is about. You keep your logic clean of DB concerns, moving this to external services/repositories. Will be glad if somebody correct me if I'm wrong.
Whats good. It looks like you have a productChecker with a nice clear purpose. Check products. You'd refactor or alter this because your have a need to. If you don't need to, you wouldn't. Here's what I would probably do.
It "feels" clunky to create a new instance of the class for each account number. A constructor argument should be something required for the class to behave correctly. Its a parameter of the class, not a dependency. It leads to the tempation to do a lot of work in the constructor. Usage of the class should look like this:
result = new ProductChecker().ProductACriteriaPassed(accountNumber)
Which I'd quickly rename to indicate it does work.
result = new ProductChecker().PassesProductACriteria(accountNumber)
A few others have mentioned that you may want to split out the database logic. You'd want to do this if you want unit tests that are fast. Most programs want unit tests (unless you are just playing around), and they are nicer if they are fast. They are fast when you can get the database out of the way.
Let's make a dummy object representing results of the database, and pass it to a method that determines whether the product passes. If not for testibility, this would be a private. Testability wins. Suppose I want to verify a rule such as "the product must be green if the account number is prime." This approach to unit testing works great without fancy infrastructure.
// Maybe this is just a number of items.
DataRequiredToEvaluateProduct data = // Fill in data
// Yes, the next method call could be static.
result = new ProductChecker().CheckCriteria(accountNumber, data)
// Assert result
Now we need to connect the database. The database is a dependency, its required for the class to behave correctly. It should be provided in the constructor.
public class ProductRepository {} // Define data access here.
// Use the ProductChecker as follows.
result = new ProductChecker(new ProductRepository()).CheckCriteria(accountNumber)
If the constructor gets annoyingly lengthy (it probably has to read a config file to find the database), create a factory to sort it out for you.
result = ProductCheckerFactory().GimmeProductChecker().CheckCriteria(accountNumber)
So far, I haven't used any infrastructure code. Typically, we'd make the above easier and prettier with mocks and dependency injection (I use rhinomocks and autofac). I won't go into that. That is only easier if you already have it in place.
How does one go about create an API that is fluent in nature?
Is this using extension methods primarily?
This article explains it much better than I ever could.
EDIT, can't squeeze this in a comment...
There are two sides to interfaces, the implementation and the usage. There's more work to be done on the creation side, I agree with that, however the main benefits can be found on the usage side of things. Indeed, for me the main advantage of fluent interfaces is a more natural, easier to remember and use and why not, more aesthetically pleasing API. And just maybe, the effort of having to squeeze an API in a fluent form may lead to better thought out API?
As Martin Fowler says in the original article about fluent interfaces:
Probably the most important thing to
notice about this style is that the
intent is to do something along the
lines of an internal
DomainSpecificLanguage. Indeed this is
why we chose the term 'fluent' to
describe it, in many ways the two
terms are synonyms. The API is
primarily designed to be readable and
to flow. The price of this fluency is
more effort, both in thinking and in
the API construction itself. The
simple API of constructor, setter, and
addition methods is much easier to
write. Coming up with a nice fluent
API requires a good bit of thought.
As in most cases API's are created once and used over and over again, the extra effort may be worth it.
And verbose? I'm all for verbosity if it serves the readability of a program.
MrBlah,
Though you can write extension methods to write a fluent interface, a better approach is using the builder pattern. I'm in the same boat as you and I'm trying to figure out a few advanced features of fluent interfaces.
Below you'll see some sample code that I created in another thread
public class Coffee
{
private bool _cream;
private int _ounces;
public static Coffee Make { get { return new Coffee(); } }
public Coffee WithCream()
{
_cream = true;
return this;
}
public Coffee WithOuncesToServe(int ounces)
{
_ounces = ounces;
return this;
}
}
var myMorningCoffee = Coffee.Make.WithCream().WithOuncesToServe(16);
While many people cite Martin Fowler as being a prominent exponent in the fluent API discussion, his early design claims actually evolve around a fluent builder pattern or method chaining. Fluent APIs can be further evolved into actual internal domain-specific languages. An article that explains how a BNF notation of a grammar can be manually transformed into a "fluent API" can be seen here:
http://blog.jooq.org/2012/01/05/the-java-fluent-api-designer-crash-course/
It transforms this grammar:
Into this Java API:
// Initial interface, entry point of the DSL
interface Start {
End singleWord();
End parameterisedWord(String parameter);
Intermediate1 word1();
Intermediate2 word2();
Intermediate3 word3();
}
// Terminating interface, might also contain methods like execute();
interface End {
void end();
}
// Intermediate DSL "step" extending the interface that is returned
// by optionalWord(), to make that method "optional"
interface Intermediate1 extends End {
End optionalWord();
}
// Intermediate DSL "step" providing several choices (similar to Start)
interface Intermediate2 {
End wordChoiceA();
End wordChoiceB();
}
// Intermediate interface returning itself on word3(), in order to allow
// for repetitions. Repetitions can be ended any time because this
// interface extends End
interface Intermediate3 extends End {
Intermediate3 word3();
}
Java and C# being somewhat similar, the example certainly translates to your use-case as well. The above technique has been heavily used in jOOQ, a fluent API / internal domain-specific language modelling the SQL language in Java
This is a very old question, and this answer should probably be a comment rather than an answer, but I think it's a topic worth continuing to talk about, and this response is too long to be a comment.
The original thinking concerning "fluency" seems to have been basically about adding power and flexibility (method chaining, etc) to objects while making code a bit more self-explanatory.
For example
Company a = new Company("Calamaz Holding Corp");
Person p = new Person("Clapper", 113, 24, "Frank");
Company c = new Company(a, 'Floridex', p, 1973);
is less "fluent" than
Company c = new Company().Set
.Name("Floridex");
.Manager(
new Person().Set.FirstName("Frank").LastName("Clapper").Awards(24)
)
.YearFounded(1973)
.ParentCompany(
new Company().Set.Name("Calamaz Holding Corp")
)
;
But to me, the later is not really any more powerful or flexible or self-explanatory than
Company c = new Company(){
Name = "Floridex",
Manager = new Person(){ FirstName="Frank", LastName="Clapper", Awards=24 },
YearFounded = 1973,
ParentCompany = new Company(){ Name="Calamaz Holding Corp." }
};
..in fact I would call this last version easier to create, read and maintain than the previous, and I would say that it requires significantly less baggage behind the scenes, as well. Which to me is important, for (at least) two reasons:
1 - The cost associated with creating and maintaining layers of objects (no matter who does it) is just as real, relevant and important as the cost associated with creating and maintaining the code that consumes them.
2 - Code bloat embedded in layers of objects creates just as many (if not more) problems as code bloat in the code that consumes those objects.
Using the last version means you can add a (potentially useful) property to the Company class simply by adding one, very simple line of code.
That's not to say that I feel there's no place for method chaining. I really like being able to do things like (in JavaScript)
var _this = this;
Ajax.Call({
url: '/service/getproduct',
parameters: {productId: productId},
)
.Done(
function(product){
_this.showProduct(product);
}
)
.Fail(
function(error){
_this.presentError(error);
}
);
..where (in the hypothetical case I'm imagining) Done and Fail were additions to the original Ajax object, and were able to be added without changing any of the original Ajax object code or any of the existing code that made use of the original Ajax object, and without creating one-off things that were exceptions to the general organization of the code.
So I have definitely found value in making a subset of an object's functions return the 'this' object. In fact whenever I have a function that would otherwise return void, I consider having it return this.
But I haven't yet really found significant value in adding "fluent interfaces" (.eg "Set") to an object, although theoretically it seems like there could be a sort of namespace-like code organization that could arise out of the practice of doing that, which might be worthwhile. ("Set" might not be particularly valuable, but "Command", "Query" and "Transfer" might, if it helped organize things and facilitate and minimize the impact of additions and changes.) One of the potential benefits of such a practice, depending on how it was done, might be improvement in a coder's typical level of care and attention to protection levels - the lack of which has certainly caused great volumes grief.
KISS: Keep it simple stupid.
Fluent design is about one aesthetic design principle used throughout the API. Thou your methodology you use in your API can change slightly, but it is generally better to stay consistent.
Even though you may think 'everyone can use this API, because it uses all different types of methodology's'. The truth is the user would start feeling lost because your consistently changing the structure/data structure of the API to a new design principle or naming convention.
If you wish to change halfway through to a different design principle eg.. Converting from error codes to exception handling because some higher commanding power. It would be folly and would normally in tail lots of pain. It is better to stay the course and add functionality that your customers can use and sell than to get them to re-write and re-discover all their problems again.
Following from the above, you can see that there is more at work of writing a Fluent API than meet's the eye. There are psychological, and aesthetic choices to make before beginning to write one and even then the feeling,need, and desire to conform to customers demand's and stay consistent is the hardest of all.
What is a fluent API
Wikipedia defines them here http://en.wikipedia.org/wiki/Fluent_interface
Why Not to use a fluent interface
I would suggest not implementing a traditional fluent interface, as it increases the amount of code you need to write, complicates your code and is just adding unnecessary boilerplate.
Another option, do nothing!
Don't implement anything. Don't provide "easy" constructors for setting properties and don't provide a clever interface to help your client. Allow the client to set the properties however they normally would. In .Net C# or VB this could be as simple as using object initializers.
Car myCar = new Car { Name = "Chevrolet Corvette", Color = Color.Yellow };
So you don't need to create any clever interface in your code, and this is very readable.
If you have very complex Sets of properties which must be set, or set in a certain order, then use a separate configuration object and pass it to the class via a separate property.
CarConfig conf = new CarConfig { Color = Color.Yellow, Fabric = Fabric.Leather };
Car myCar = new Car { Config = conf };
No and yes. The basics are a good interface or interfaces for the types that you want to behave fluently. Libraries with extension methods can extend this behavior and return the interface. Extension methods give others the possibility to extend your fluent API with more methods.
A good fluent design can be hard and takes a rather long trial and error period to totally finetune the basic building blocks. Just a fluent API for configuration or setup is not that hard.
Learning building a fluent API does one by looking at existing APIs. Compare the FluentNHibernate with the fluent .NET APIs or the ICriteria fluent interfaces. Many configuration APIs are also designed "fluently".
With a fluent API:
myCar.SetColor(Color.Blue).SetName("Aston Martin");
Check out this video http://www.viddler.com/explore/dcazzulino/videos/8/
Writting a fluent API it's complicated, that's why I've written Diezel that is a Fluent API generator for Java. It generates the API with interfaces (or course) to:
control the calling flow
catch generic types (like guice one)
It generates also implementations.
It's a maven plugin.
I think the answer depends on the behaviour you want to achieve for your fluent API. For a stepwise initialization the easiest way is, in my opinion, to create a builder class that implements different interfaces used for the different steps. E.g. if you have a class Student with the properties Name, DateOfBirth and Semester the implementation of the builder could look like so:
public class CreateStudent : CreateStudent.IBornOn, CreateStudent.IInSemester
{
private readonly Student student;
private CreateStudent()
{
student = new Student();
}
public static IBornOn WithName(string name)
{
CreateStudent createStudent = new CreateStudent();
createStudent.student.Name = name;
return createStudent;
}
public IInSemester BornOn(DateOnly dateOfBirth)
{
student.DateOfBirth = dateOfBirth;
return this;
}
public Student InSemester(int semester)
{
student.Semester = semester;
return student;
}
public interface IBornOn
{
IInSemester BornOn(DateOnly dateOfBirth);
}
public interface IInSemester
{
Student InSemester(int semester);
}
}
The builder can then be used as follows:
Student student = CreateStudent.WithName("Robert")
.BornOn(new DateOnly(2002, 8, 3)).InSemester(2);
Admittedly, writing an API for more than three properties becomes tedious. For this reasons I have implemented a source generator that can do this work for you: M31.FluentAPI.