在客户端和服务器端实现接口

本文关键字:实现 接口 服务器端 客户端 | 更新日期: 2023-09-27 18:36:36

我有一个客户端(Android应用程序)和一个服务器(WebApi REST Web服务)。

该应用程序具有一个服务层,它调用它与 Web 服务进行通信以读取和写入记录。返回值从 Web 服务的控制器发回(即,当将新记录写入数据库并生成关联的记录 ID 时)。

我有许多不同的控制器,每个控制器都有多个方法,这些方法都返回不同数量和类型的值(它们主要返回 int 数组,但如果混有非整数值,偶尔我会返回一个对象数组)。

应用程序端的服务层会执行一些检查来验证参数,例如检查参数计数(数组元素)和检查预定义的无效/未初始化值(如 -9999)。

我不想通过定义一个接口来形式化这些参数操作,以便在一个位置显式指定两端使用的参数的计数和类型(所以我不会在两端都"翼它")。

但是,我遇到的困境是决定是定义一个同时指定客户端和服务器相关方法的接口,还是定义两个单独的接口,每个接口指定特定于通信端的方法。

如果我有一个界面,如下所示:

public interface IServiceParams
{
   object[] CreateParams(int recordId, string recordNumber);
   bool ParseParams(object[] paramz, out int recordId, out string recordNumber);
}

那么由于 CreateParams 只在 WS 端使用,而 ParseParams 在 App 端使用,所以我必须在两端声明空实现

网络服务端:

public class RecordController : ApiController, IServiceParams
{
   object[] IServiceParams.CreateParams(int recordId, string recordNumber)
   {
      return new[] { newRecordId, newRecordNumber };
   }
   bool IServiceParams.ParseParams(object[] paramz, out int recordId, out string recordNumber)
   {
      throw new NotImpementedException();
   }
   ////////////////////////////////////////////////////////////////////////////////////////////
   public object[] Put( Record record )
   {
      if( !DbLayer.Update(record) )
      {
         return null;
      }
      return CreateParams(record.RecordId, record.RecordNumber);
   }
}

应用端:

public class RecordService : IServiceParams
{
   object[] IServiceParams.CreateParams(int recordId, string recordNumber)
   {
      throw new NotImpementedException();
   }
   bool IServiceParams.ParseParams(object[] paramz, out string recordNumber)
   {
      if( paramz == null || paramz.Count != 4 )
      {
         return false;
      }
      if(!ParseInt(paramz[0].ToString(), out recordId) || recordIdNew == DEFAULT_RECORD_ID)
      {
         return false;
      }
      // ...
      return true;
   }
   ////////////////////////////////////////////////////////////////////////////////////////////
   public bool UpdateRecord( Record record )
   {
      object[] paramz = WebService.Put( record );
      int recordId; 
      string recordNumber;
      if(!ParseParams(paramz, out recordId, out recordNumber))
      { 
         return false;
      }
      record.RecordId = recordId;
      record.RecordNumber = recordNumber;
      return true;
   }
}    

或者,我应该定义两个接口,并在各自的端实现每个接口,从而消除对空实现的需求:

public interface IServiceParamsClient
{
   bool ParseParams(object[] paramz, out int recordId, out string recordNumber );
}
public interface IServiceParamsServer
{
   object[] CreateParams(int recordId, string recordNumber);
}

非常感谢您的帮助!

在客户端和服务器端实现接口

有什么理由需要在一个接口中声明这两种方法吗? 如果没有,请创建两个单独的接口,每个接口都反映其意图。 必须将方法实现为"不支持"是一种设计气味。请参阅:当我的操作并非所有实现者都支持时,设计界面的正确方法是什么?

选择两个界面设计。通过这样做,您可以使用更干净的 API 帮助自己。一个建议是您可以将参数逻辑封装在一个类中,以便现在您可以静态检查更强的类型,这不是一件小事。其次,我不确定 Web 服务了解应用程序客户端是否是一件好事。我认为应该是相反的。所以这是我会怎么做的:

public class Param //at server side
{
   public int recordId { get; set; }
   public int transToPropId { get; set; }
   public int receivedViaTypeId { get; set; }
   public string recordNumber { get; set; }
}
public interface IParamParser //at client
{
   //I do not know what object[] paramz is; I leave that to you; 
   //may be it needs encapsulation as well
   bool Parse(object[] paramz, Param p);
}
public interface IParamCreator //at server
{
   Param CreateParams(int recordId, int transToPropId, int receivedViaTypeId, 
                      string recordNumber);
}