I'm inspired from encapsulation achieved by interfaces. Interface is a powerful tool when objects shares common properties and methods. Interface-oriented designs are designs that decouple entities and the manager that are managing them. They do not need to know any of the implementation details and the exact type, and a typical good interface design is that object that passed through the method call could be hot-plugged at runtime.
So I managed to turn my objects to expose through interfaces.
Suppose I have a LoginModule
, which contains the business logic to handle the submitted Form
by Client
. For example, the client may either login through enter Username
and Password
or with their MobileNo
public class UserLoginForm
{
public string Username { get; set; }
public string Password { get; set; }
}
public class MobileLoginForm
{
public string MobileNo { get; set; }
public string Password { get; set; }
}
Then the business logic layer is going to take a look at the request.
public class LoginModule
{
public int LoginByUsername(UserLoginForm form)
{
// DoSomething, such as CheckDbIfExist(form.Username);
// return the result, e.g. -1 stand for wrong password
}
public int LoginByMobileNo(MobileLoginForm form)
{
// DoSomething, such as CheckDbIfExist(form.Username);
// return the result, e.g. -1 stand for wrong password
}
}
In this example, the two logics are so similar that LoginByMobileNo
could eventually direct to call LoginByUserName
after getting the Username
by looking up MobileNo
in the database.
But you know, it just couldn't because we need a UserLoginForm
to call it, or we just create a separated method Login(string username, string password)
to let both login method to call it.
The actual consideration is not on how to reconstruct these two methods, as there are many other types of request, something like CokeRequest
that request a coke delivery to int RoomNo
and int Count
... ...
public interface ILoginModule
{
void LoginByUsername(XXX xxx);
}
First Question: What is that XXX
?
This interface have no access to UserLoginForm
, he don't know the existance of that form anyway. If I am doing the interface design correctly, XXX
should be an interface that he could know its existance.
public interface ILoginModule
{
void LoginByUsername(IUserLogin login);
void LoginByMobile(IMobileLogin login);
}
// LoginModule now implement ILoginModule
public interface IUserLogin
{
string UserName { get; set; }
string Password { get; set; }
}
public interface IMobileLogin
{
string MobileNo { get; set; }
string Password { get; set; }
}
// The the two Forms now implement the respective interface
By then the nightmare begun. I find to needing a dedicated interface for every Request that the client made
An interesting observation:
Service interfaces are Method-only interfaces
Request interfaces are Property-only interfaces
I do not believe it is the right way to do deal with interfaces.
Neither if we fragmentize the interfaces.
public interface ILoginModule
{
void LoginByUsername(IUserLogin login);
void LoginByMobile(IMobileLogin login);
}
// LoginModule now implement ILoginModule
public interface IPassword
{
string Password { get; set; }
}
public interface IUserLogin : IPassword
{
string UserName { get; set; }
}
public interface IMobileLogin : IPassword
{
string MobileNo { get; set; }
}
// The the two Forms now implement the respective interface
Because we are still needing hundreds of interface (which is of same variety as the requests to be) Nor
public interface ILoginModule
{
void LoginByUsername(IUser login1, IPassword login2);
void LoginByMobile(IMobile login, IPassword login2);
}
// LoginModule now implement ILoginModule
public interface IPassword
{
string Password { get; set; }
}
public interface IUser
{
string UserName { get; set; }
}
public interface IMobile
{
string MobileNo { get; set; }
}
// The the two Forms now implement the respective interface
It smells bad because we are no different from passing the string content one by one. If the request contains 8 param, then the method becomes DoWork(form,form,form,form,form,form,form,form)
I really can't figure out why I'm falling into this irony. If I have n types of requests, it is normal to give them to m modules to handle, it still n methods in total. If we use interface, it adds n interfaces to represent n request, and this didn't help to hot-plug data at anytime because each interface get only one single implementation.
In this situation the LoginModule can't even benefit from it: It could not call LoginByUsername
after finding out the Username
which corresponds to MobileNo
at any circumstances...
Most interface tutorial is taking about car
and bus
and racecar
in which they void StartEngine()
...While seldom for architecture, or communication between layers, just for instance, the MVC model.
I'm not saying interfaces are bad, but I need a way to correctly implement it or should I implement it in this situation. Any misused patterns are antipattern with no single doubt. I hope to hear any voices.
Aucun commentaire:
Enregistrer un commentaire