dimanche 28 janvier 2018

Interface-oriented: Fragmentized interfaces to represent a data structure

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