首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重构相似with方法但返回类型不同

重构相似with方法但返回类型不同
EN

Stack Overflow用户
提问于 2019-08-09 14:21:00
回答 1查看 57关注 0票数 0

我有两种方法:

代码语言:javascript
复制
public ActionResult<IEnumerable<IDataObject>> GetRelatedObjects([CanBeNull] string className, [CanBeNull] string primaryKey, [CanBeNull] string relationName)
{
  if (string.IsNullOrWhiteSpace(primaryKey))
  {
    return BadRequest("Primary key cannot be empty.");
  }

  if (!TryGetClass(className, out var metaClass))
  {
    return NotFound($"Class [{className}] does not exist.");
  }

  if (!metaClass.Properties.TryGetValue(relationName, out var property))
  {
    return NotFound($"Class [{metaClass}] does not contain property [{relationName}].");
  }

  if (!(property is IMetaRelation relation))
  {
    return BadRequest($"Property [{relationName}] is not a relation.");
  }

  if (relation.Target.Cardinality != MetaCardinality.Multiple)
  {
    return BadRequest(`$"Relation [{relationName}] has multiple cardinality."`);
  }

  if (!_primaryKeyHandler.TryParsePrimaryKey(metaClass, primaryKey, out var primaryKeyValues))
  {
    return BadRequest("Cannot convert the primaryKey to the correct type.");
  }

  if (!_dataCalculator.SupportsData(metaClass))
  {
    return BadRequest($"The class [{className}] is not persisted");
  }

  var metaObject = _dataAccess.GetObject<IDataObject>(DataSession, metaClass, primaryKeyValues);
  if (metaObject == null)
  {

    return NotFound($"The metaObject for the primaryKey [{primaryKey}] nad the class [{className}] cannot be empty.");
  }





  // The validations above are the same as for GetRelatedObject()




  try
  {
    var list = _dataAccess.GetRelatedList<IDataObject>(DataSession, metaClass, primaryKeyValues, relation);

    return new ActionResult<IEnumerable<IDataObject>>(list);
  }
  catch (InvalidAuthorizationException)
  {
    return Unauthorized();
  }
}

第二项是:

代码语言:javascript
复制
public ActionResult<IDataObject> GetRelatedObject([CanBeNull] string className, [CanBeNull] string primaryKey, [CanBeNull] string relationName)
{
  if (string.IsNullOrWhiteSpace(primaryKey))
  {
    return BadRequest("Primary key cannot be empty.");
  }

  if (!TryGetClass(className, out var metaClass))
  {
    return NotFound($"Class [{className}] does not exist.");
  }

  if (!metaClass.Properties.TryGetValue(relationName, out var property))
  {
    return NotFound($"Class [{metaClass}] does not contain property [{relationName}].");
  }

  if (!(property is IMetaRelation relation))
  {
    return BadRequest($"Property [{relationName}] is not a relation.");
  }

  if (relation.Target.Cardinality == MetaCardinality.Multiple)
  {
    return BadRequest($"Relation [{relationName}] has multiple cardinality.");
  }

  if (!_primaryKeyHandler.TryParsePrimaryKey(metaClass, primaryKey, out var primaryKeyValues))
  {
    return BadRequest("Cannot convert the primaryKey to the correct type.");
  }

  if (!_dataCalculator.SupportsData(metaClass))
  {
    return BadRequest($"The class [{className}] is not persisted");
  }

  var metaObject = _dataAccess.GetObject<IDataObject>(DataSession, metaClass, primaryKeyValues);
  if (metaObject == null)
  {
    return NotFound($"The metaObject for the primaryKey [{primaryKey}] nad the class [{className}] cannot be empty.");
  }



  // The validations above are the same as for GetRelatedObjects()


  try
  {
    var relationValue = metaObject.GetObject<IDataObject>(relation);

    return new ActionResult<IDataObject>(relationValue);
  }
  catch (InvalidAuthorizationException)
  {
    return Unauthorized();
  }
}

正如代码中的注释所标记的那样,验证在这两种方法中是相同的。在这两种方法中,有一小部分代码是不一样的。而且,返回类型在这两种方法中都是不同的。

我正在尝试将方法中的验证重构为一个单独的方法。

以下是我的尝试:

代码语言:javascript
复制
private void RelatedObject(string className, string primaryKey, string relationName, out IMetaRelation metaRelation, out IDataObject metaObject, out ActionResult<IDataObject> actionResult, out IDictionary<IMetaProperty, object> primaryKeyValues, out IMetaClass metaClass)
    {
      actionResult = null;
      metaRelation = null;

      if (string.IsNullOrWhiteSpace(primaryKey))
      {
        actionResult = BadRequest("Primary key cannot be empty.");
      }

      if (!TryGetClass(className, out metaClass))
      {
        actionResult = NotFound($"Class [{className}] does not exist.");
      }

      if (!metaClass.Properties.TryGetValue(relationName, out var property))
      {
        actionResult = NotFound($"Class [{metaClass}] does not contain property [{relationName}].");
      }

      if (!(property is IMetaRelation relation))
      {
        actionResult = BadRequest($"Property [{relationName}] is not a relation.");
      }

      if (relation.Target.Cardinality == MetaCardinality.Multiple)
      {
        actionResult = BadRequest($"Relation [{relationName}] has multiple cardinality.");
      }

      if (!_primaryKeyHandler.TryParsePrimaryKey(metaClass, primaryKey, out primaryKeyValues))
      {
        actionResult = BadRequest("Cannot convert the primaryKey to the correct type.");
      }

      if (!_dataCalculator.SupportsData(metaClass))
      {
        actionResult = BadRequest($"The class [{className}] is not persisted");
      }

      metaObject = _dataAccess.GetObject<IDataObject>(DataSession, metaClass, primaryKeyValues);
      if (metaObject == null)
      {
        actionResult = NotFound($"The metaObject for the primaryKey [{primaryKey}] nad the class [{className}] cannot be empty.");
      }
    }

下面是GetRelatedObject内部的调用:

代码语言:javascript
复制
public ActionResult<IDataObject> GetRelatedObject([CanBeNull] string className, [CanBeNull] string primaryKey, [CanBeNull] string relationName)
{
  RelatedObject(className, primaryKey, relationName, out var relation, out var metaObject, out var actionResult, out var primaryKeyValues, out var metaClass);
  if (actionResult != null)
  {
    return actionResult;
  }

  try
  {
    var relationValue = metaObject.GetObject<IDataObject>(relation);

    return new ActionResult<IDataObject>(relationValue);
  }
  catch (InvalidAuthorizationException)
  {
    return Unauthorized();
  }
}

下面是GetRelatedObjects内部的调用:

代码语言:javascript
复制
public ActionResult<IEnumerable<IDataObject>> GetRelatedObjects([CanBeNull] string className, [CanBeNull] string primaryKey, [CanBeNull] string relationName)
    {
      RelatedObject(className, primaryKey, relationName, out var relation, out var metaObject, out var actionResult, out var primaryKeyValues, out var metaClass);
      if (actionResult != null)
      {
        return actionResult;
      }

      try
      {
        var list = _dataAccess.GetRelatedList<IDataObject>(DataSession, metaClass, primaryKeyValues, relation);

        return new ActionResult<IEnumerable<IDataObject>>(list);
      }
      catch (InvalidAuthorizationException)
      {
        return Unauthorized();
      }
    }

我的尝试有很多问题:

  1. GetRelatedObjects和GetRelatedObject有不同的返回类型,我的重构方法只能支持一种
  2. 有些out变量不是使用GetRelatedObject,而是使用GetRelatedObjects和反转

为了改善我的解决方案,我可以摆脱我的问题,需要做哪些改变?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-09 14:40:57

您在代码中已经指出,每个方法的验证都是相同的.不过他们不是。

来自GetRelatedObject:

代码语言:javascript
复制
if (relation.Target.Cardinality == MetaCardinality.Multiple)
{
    return BadRequest($"Relation [{relationName}] has multiple cardinality.");
}

来自GetRelatedObjects:

代码语言:javascript
复制
if (relation.Target.Cardinality != MetaCardinality.Multiple)
{
    return BadRequest("The cardinality is not multiple");
}

尽管如此,我还是会这样做,并将验证合并到一个方法中,以减少代码重复,添加一个参数在多个/单个基数之间切换。

没有经过测试,所以我不知道它是否真的会起作用;)

代码语言:javascript
复制
public ActionResult<IDataObject> GetRelatedObject([CanBeNull] string className, [CanBeNull] string primaryKey, [CanBeNull] string relationName)
{
    var validationError = ValidateRequest(className, primaryKey, relationName, allowMultipleCardinality: false);
    if (validationError) return validationError;

    try
    {
        var relationValue = metaObject.GetObject<IDataObject>(relation);
        return new ActionResult<IDataObject>(relationValue);
    }
    catch (InvalidAuthorizationException)
    {
        return Unauthorized();
    }
}

public ActionResult<IEnumerable<IDataObject>> GetRelatedObjects([CanBeNull] string className, [CanBeNull] string primaryKey, [CanBeNull] string relationName)
{
    var validationError = ValidateRequest(className, primaryKey, relationName, allowMultipleCardinality: true);
    if (validationError) return validationError;

    try
    {
        var list = _dataAccess.GetRelatedList<IDataObject>(DataSession, metaClass, primaryKeyValues, relation);

        return new ActionResult<IEnumerable<IDataObject>>(list);
    }
    catch (InvalidAuthorizationException)
    {
        return Unauthorized();
    }
}

private ActionResult ValidateRequest([CanBeNull] string className, [CanBeNull] string primaryKey, [CanBeNull] string relationName, bool allowMultipleCardinality)
{
    if (string.IsNullOrWhiteSpace(primaryKey))
    {
        return BadRequest("Primary key cannot be empty.");
    }

    if (!TryGetClass(className, out var metaClass))
    {
        return NotFound($"Class [{className}] does not exist.");
    }

    if (!metaClass.Properties.TryGetValue(relationName, out var property))
    {
        return NotFound($"Class [{metaClass}] does not contain property [{relationName}].");
    }

    if (!(property is IMetaRelation relation))
    {
        return BadRequest($"Property [{relationName}] is not a relation.");
    }

    if (AllowMultipleCardinality)
    {
        if (relation.Target.Cardinality != MetaCardinality.Multiple)
        {
            return BadRequest("The cardinality is not multiple");
        }
    }
    else
    {
        if (relation.Target.Cardinality == MetaCardinality.Multiple)
        {
            return BadRequest($"Relation [{relationName}] has multiple cardinality.");
        }
    }

    if (!_primaryKeyHandler.TryParsePrimaryKey(metaClass, primaryKey, out var primaryKeyValues))
    {
        return BadRequest("Cannot convert the primaryKey to the correct type.");
    }

    if (!_dataCalculator.SupportsData(metaClass))
    {
        return BadRequest($"The class [{className}] is not persisted");
    }

    var metaObject = _dataAccess.GetObject<IDataObject>(DataSession, metaClass, primaryKeyValues);
    if (metaObject == null)
    {
        return NotFound($"The metaObject for the primaryKey [{primaryKey}] nad the class [{className}] cannot be empty.");
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57432029

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档