在某些情况下,抽象方法中的空实现和未使用的参数是一种好方法吗?
Is empty implementation and unused parameter in abstract methods a good approach in certain cases?
我有一种情况需要解析不同类型的对象。大多数类型都可以用通用的方式解析,但某些类型除外,这需要额外填充。为了简单起见,我们假设有一种类型需要执行一些特殊操作,并调用它的解析器 SpecialParser
.
在当前的实现中,我有一个名为 BaseParser
的基 class,它实现了一个接口 ICustomParser
。一个通用解析器,能够解析所有称为 GenericParser
和 SpecialParser
的常规类型。 GenericParser
和 SpecialParser
都继承自 BaseParser
class,后者实现了基本的通用功能。
所有解析器都使用接口引用,并通过 BaseParser
中实现的 public 方法调用。要使用的解析器类型是使用每个解析器中实现的 属性 来确定的,它指示它可以解析的类型。
构建解析对象的函数(BuildParsedObject()
)在所有解析器中都有一些共同的部分,但在特殊类型解析器中需要一些额外的逻辑。
目前,BaseParser
的实现如下所示:
public abstract class BaseParser : ICustomParser
{
// Common methods and functionalities
protected abstract Type GetParsedType(string typeIdentifier);
protected abstract void FillConcreteProperties(...);
public Object BuildParsedObject(JObject objectToBuild)
{
// Some common logic.
var parsedType = GetParsedType(typeIdentifier);
// Call the specific filling logic if needed.
// The order here is important. The concrete filling must be done before the general one.
FillConcreteProperties(...);
// (More common logic)
// Fill the general properties for all the types. This method is implemented here in the base class.
FillGeneralProperties(...);
// Cast the object to the parsedType and return it.
return objectToBuild.ToObject(parsedType);
}
}
GenericParser
看起来像这样:
public class GenericParser
{
protected override Type GetParsedType(string typeIdentifier)
{
// Perform certain checks on the given <typeIdentifier> and logic in
// order to determine the parsed object type and return it.
}
protected override void FillConcreteProperties(...)
{ // The implementation is empty here since no special filling is required for the regular types.
}
}
SpecialParser
看起来像这样:
public class SpecialParser
{
protected override Type GetParsedType(string typeIdentifier)
{
// The <typeIdentifier> parameter is never used, since the type is already known.
// So we always just return a hardcoded type for the parser (for e.g. A).
return typeof(A);
}
protected override void FillConcreteProperties(...)
{
// Contains an implementation for the specific type parsing and fills the object being built accordingly.
}
}
当前实现的优点是所有解析器只需要实现GetParsedType()
和FillConcreteProperties()
方法。所有解析逻辑都在基础 class 级别共享和完成,我们不需要复制 BuildParsedObject()
方法的实现。
缺点是 GenericParser
不需要实现 FillConcreteProperties()
方法,所以我们在那里得到一个空的实现。特殊的解析器不需要执行逻辑来确定输出类型,所以它们最终实现了一个虚拟的 GetParsedType()
方法,而不是在那里使用传递的参数。
抽象方法的空实现可以吗?以及已实现的抽象方法中未使用的参数?或者这是一种不好的做法,应该避免?
如果应该避免,将 BuildParsedObject()
的实现移动到子解析器 classes 并让每个解析器根据需要实现它是个好主意吗并删除 FillConcreteProperties()
和未使用参数的空实现的需要?尽管如此,它会在那里造成某种重复?
Is it fine to have an empty implementation of an abstract method?
不是真的。这通常表明违反了里氏替换原则。
And an unused parameter in an implemented abstract method? Or is it a bad practice and should be avoided?
这也是代码异味,说明你的class.
内聚性低
您可以做的是检查四人组的装饰器模式。这样您就可以创建扩展装饰器,根据您的业务逻辑丰富您的对象。
您可以通过这种方式删除不需要的函数,运行 基本函数,然后用您可能需要的任何新信息丰富您的对象。
我有一种情况需要解析不同类型的对象。大多数类型都可以用通用的方式解析,但某些类型除外,这需要额外填充。为了简单起见,我们假设有一种类型需要执行一些特殊操作,并调用它的解析器 SpecialParser
.
在当前的实现中,我有一个名为 BaseParser
的基 class,它实现了一个接口 ICustomParser
。一个通用解析器,能够解析所有称为 GenericParser
和 SpecialParser
的常规类型。 GenericParser
和 SpecialParser
都继承自 BaseParser
class,后者实现了基本的通用功能。
所有解析器都使用接口引用,并通过 BaseParser
中实现的 public 方法调用。要使用的解析器类型是使用每个解析器中实现的 属性 来确定的,它指示它可以解析的类型。
构建解析对象的函数(BuildParsedObject()
)在所有解析器中都有一些共同的部分,但在特殊类型解析器中需要一些额外的逻辑。
目前,BaseParser
的实现如下所示:
public abstract class BaseParser : ICustomParser
{
// Common methods and functionalities
protected abstract Type GetParsedType(string typeIdentifier);
protected abstract void FillConcreteProperties(...);
public Object BuildParsedObject(JObject objectToBuild)
{
// Some common logic.
var parsedType = GetParsedType(typeIdentifier);
// Call the specific filling logic if needed.
// The order here is important. The concrete filling must be done before the general one.
FillConcreteProperties(...);
// (More common logic)
// Fill the general properties for all the types. This method is implemented here in the base class.
FillGeneralProperties(...);
// Cast the object to the parsedType and return it.
return objectToBuild.ToObject(parsedType);
}
}
GenericParser
看起来像这样:
public class GenericParser
{
protected override Type GetParsedType(string typeIdentifier)
{
// Perform certain checks on the given <typeIdentifier> and logic in
// order to determine the parsed object type and return it.
}
protected override void FillConcreteProperties(...)
{ // The implementation is empty here since no special filling is required for the regular types.
}
}
SpecialParser
看起来像这样:
public class SpecialParser
{
protected override Type GetParsedType(string typeIdentifier)
{
// The <typeIdentifier> parameter is never used, since the type is already known.
// So we always just return a hardcoded type for the parser (for e.g. A).
return typeof(A);
}
protected override void FillConcreteProperties(...)
{
// Contains an implementation for the specific type parsing and fills the object being built accordingly.
}
}
当前实现的优点是所有解析器只需要实现GetParsedType()
和FillConcreteProperties()
方法。所有解析逻辑都在基础 class 级别共享和完成,我们不需要复制 BuildParsedObject()
方法的实现。
缺点是 GenericParser
不需要实现 FillConcreteProperties()
方法,所以我们在那里得到一个空的实现。特殊的解析器不需要执行逻辑来确定输出类型,所以它们最终实现了一个虚拟的 GetParsedType()
方法,而不是在那里使用传递的参数。
抽象方法的空实现可以吗?以及已实现的抽象方法中未使用的参数?或者这是一种不好的做法,应该避免?
如果应该避免,将 BuildParsedObject()
的实现移动到子解析器 classes 并让每个解析器根据需要实现它是个好主意吗并删除 FillConcreteProperties()
和未使用参数的空实现的需要?尽管如此,它会在那里造成某种重复?
Is it fine to have an empty implementation of an abstract method?
不是真的。这通常表明违反了里氏替换原则。
And an unused parameter in an implemented abstract method? Or is it a bad practice and should be avoided?
这也是代码异味,说明你的class.
内聚性低您可以做的是检查四人组的装饰器模式。这样您就可以创建扩展装饰器,根据您的业务逻辑丰富您的对象。
您可以通过这种方式删除不需要的函数,运行 基本函数,然后用您可能需要的任何新信息丰富您的对象。