抽象:可选方法? [java](建模过滤器)

时间:2013-12-11 00:49:29

标签: java abstraction

背景

对于我的任务,我需要对基本级别的信号处理过滤器进行建模。过滤器可以接收任何类型的输入,并输出不同的类型,如果这是过滤器的实现方式。最简单的滤波器输出输入。其他示例过滤器是算术平均值,最大值或最小值过滤器,它们返回最大输入。类似的过滤器只能返回最后N个输入的平均值/最大值/最小值。某些过滤器可以重置,并且有一个“重置”方法,它接受相同类型的输入。因此,例如,max3过滤器返回最后三个输入的最大数量,或者自上次重置以来,包括重置方法所采用的输入。该任务更详细地描述了其他更复杂的过滤器,但我在最基本的层面上遇到了抽象问题。

尝试

所以我的第一次尝试是创建一个“Filter”接口,它有一个方法“filter”。这可以通过过滤器来实现,以满足他们自己的需求。我创建了一个抽象类“StorageFilter”,它存储了一个可以使用受保护的set / get方法访问的输入列表。然后我扩展了该类,在另一个抽象类“ResetableFilter”中实现了reset函数。因此,无法重置的过滤器会扩展第一个抽象过滤器和可以重置第二个过滤器的过滤器。但是我的实现并没有真正解决,因为过滤器比这复杂一点。我可以确定一些主要类型的过滤器。过滤:

  • 存储一个输入,例如最大/最小过滤器:只需将存储值与输入进行比较,如果是新的最大/最小值,则将存储的值设置为输入。我们称之为1型。
  • 存储输入列表,例如最后N个的最大/最小过滤器:仅存储最后N个输入,因此过滤方法可以遍历列表并找到最大值/最小值。我们将这种类型称为2.(这也可以以另一种方式实现,存储两个值,一个代表当前的最大/最小值及其“年龄”)
  • 存储输入列表和输出列表,例如复杂的标量线性滤波器,其使用等式使用两者来计算新输出。我们称之为3型。
  • 根本不存储像第一个例子这样的简单过滤器或只返回输入的双重过滤器。我们称之为4型

因此,过滤器可以存储许多类型的内容,但并非所有过滤器都可以重置。

问题

我的一般问题是如何在保持抽象的同时实现可选方法?此类型(过滤器)可以具有其子类型可以具有的可选方法(重置)。我不能只有一个空方法“重置”除了过滤器仍然可以调用之外什么都不做。在保持抽象的同时实现可选方法的最佳方法是什么?

潜在解决方案

  • 使用@Optional:使用此批注意味着不使用此方法的过滤器将抛出UnsupportedOperationException。这是一种可接受的维护抽象的方法,因为Java的Collections使用它,但由于涉及异常,因此不可取。
  • 创建一个“重置”界面,让每个可以重置的过滤器实现它:这也很糟糕,因为它几乎会使我必须考虑的过滤器类型加倍。 (即类型1过滤器,可重置类型1过滤器,...和类型4过滤器。由于类型4过滤器不存储任何东西,它们不会重置)
  • “Code Complete 2”一书描述了对Cat进行建模的场景。猫可以划伤,但有些猫被宣布,因此不能划伤。为猫可以做或不能做的事情创建不同的类使它复杂化,这样你最终会得到像ScratchlessTailess ...... Cat这样的类。本书提供的解决方案是创建一个包含在Cat类中的内部类“Claws”,或构建一个包含猫是否划伤的构造函数。由此我认为最佳解决方案是创建一个内部接口“ResetableContainer”,它具有一个方法重置,可以实现以适应不同类型。它可以容纳过滤器需要存储的任何内容,并且将根据存储的内容实现重置。问题仍然是如何实现它以避免存储的不同可能性(单个输入或输入列表)的所有复杂性?

2 个答案:

答案 0 :(得分:0)

您似乎遇到了概念设计问题,因为您希望Filter的用户始终确切地知道它能做什么和不能做什么。但与此同时,你希望过滤器能够做很多不同的事情......这两个想法不能完全融合。

可以做的是创建这些“可选”方法来返回执行值:

/**
 * Resets the filter.
 *
 * @returns
 *          false if this operation is not supported by the filter
 */
public boolean reset() {
    return false;
}

更好的方法:包括包含必须覆盖的其他方法,更常见的设计模式:有关示例,请参阅this question。如上所述,只有一个以上的界面也可能是好事。

答案 1 :(得分:0)

这听起来像是一项学校任务,所以你可能会受到限制而无法做到这一点,但我要做的就是保持简单:单一界面:

public interface Filter<In, Out> {
    public Out filter(In toFilter);
    public void reset();
    public boolean canReset();
}

然后可能是一个抽象基类,为那些拥有它们的方法提供良好的默认实现:

public abstract class BaseFilter<In, Out> implements Filter<In, Out> {
    public void reset() {}
    public boolean canReset() { return false; }
}

我甚至不会包括canReset,除了有时可重置且有时不可过滤的可能性。如果你不想支持那么你就可以删除canReset,只要你重置它就可以调用reset(),如果它是一个可重置的过滤器。