面向接口:用于表示数据结构的Fragmentized接口

时间:2018-01-28 16:22:01

标签: c# design-patterns interface

我从界面实现的封装中获得灵感。当对象共享公共属性和方法时,接口是一个强大的工具。面向接口的设计是将实体和管理它们的管理器分离的设计。他们不需要知道任何实现细节和确切类型,典型的良好接口设计是通过方法调用的对象可以在运行时热插拔。

所以我设法将我的对象转换为通过接口公开。

假设我有LoginModule,其中包含处理Form Client提交的Username的业务逻辑。例如,客户可以通过输入PasswordMobileNo或使用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; } }

登录
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
  }
}

然后业务逻辑层将查看请求。

LoginByMobileNo

在此示例中,两个逻辑非常相似,LoginByUserName最终可以在通过在数据库中查找Username获取MobileNo后直接调用UserLoginForm。< / p>

但是你知道,它只是不能,因为我们需要Login(string username, string password)来调用它,或者我们只是创建一个单独的方法CokeRequest来让两个login方法都调用它。

实际考虑的不是如何重建这两种方法,因为有许多其他类型的请求,例如int RoomNo请求向int Countpublic interface ILoginModule { void LoginByUsername(XXX xxx); } 发送焦炭。 .. ...

XXX

第一个问题:UserLoginForm是什么?

此界面无法访问XXX,他不知道该表格是否存在。如果我正确地进行了界面设计,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 应该是一个他可以知道它存在的界面。

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

那时噩梦开始了。我发现客户端的每个请求都需要一个专用接口

  

一个有趣的观察:

     

服务接口是仅限方法的接口

     

请求接口是仅限属性的接口

我认为这不是处理接口的正确方法。

如果我们破坏接口,也不会。

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

因为我们仍然需要数百个接口(与请求的种类相同) 的也不

DoWork(form,form,form,form,form,form,form,form)

它闻起来很糟糕,因为我们与逐个传递字符串内容没有什么不同。如果请求包含8个参数,则该方法将变为LoginByUsername

我真的无法弄清楚为什么我会陷入这种讽刺。如果我有n种类型的请求,将它们交给m个模块进行处理是正常的,它总共还有n个方法。如果我们使用接口,它会添加n个接口来表示n请求,这无助于随时热插拔数据,因为每个接口只能获得一个实现

在这种情况下,LoginModule甚至无法从中受益:在任何情况下找到与Username对应的MobileNo之后无法致电car

大多数界面教程都采用了busracecar以及void StartEngine(),其中var e = document.querySelector('[name="os0"]'); var strUser = ""; e.addEventListener("change", function(){ strUser = e.options[e.selectedIndex].innerHTML; alert("You have chosen " + strUser); }); ...虽然很少用于体系结构或层之间的通信,例如,MVC模型。

我不是说接口坏了,但我需要一种正确实现它的方法,或者我应该在这种情况下实现它。任何误用的模式都是反模式的,毫无疑问。 我希望听到任何声音。

1 个答案:

答案 0 :(得分:-1)

经过数小时的考虑,发现起点存在问题,导致问题解决。

使用接口表示数据结构的答案是 nope 。声明仅限属性的接口是没用的。

客户提交的请求在业务逻辑上只需要获取其属性并完成工作时就会很贫乏。

也就是说,定义ILoginModule的{​​{1}}已足以处理请求,而不会将void LoginWithMobile(string MobileNo, string Password)本身作为参数传递。

  

接口对于&#34;它的作用是什么&#34;代替   &#34;它包含什么&#34;。因此,所有旨在存储数据的对象   没有自己管理它们就不应该实现任何接口。