【问题标题】:Does this "call-inversion" pattern have a name?这种“调用反转”模式有名字吗?
【发布时间】:2015-08-24 04:18:46
【问题描述】:

我刚刚回答了另一个问题 (Select method based on field in class),我想知道该模式是否有名称。

调用action.applyX(a),其中X 取决于a 的某些属性(例如,示例中的type),因此您改为调用a.apply(action) 并让a(或Type)调用合适的applyX

这个有名字吗?

public enum Type {
    INTEGER {
        @Override
        public void apply(Action action, A a) {
            action.applyInteger(a);
        }
    },
    STRING {
        @Override
        public void apply(Action action, A a) {
            action.applyString(a);
        }
    };
    public abstract void apply(Action action, A a);
}

public interface Action {
    public void applyInteger(A a);
    public void applyString(A a);
}

public class A {
    private Type type;
    ...
    public void apply(Action action) {
        this.type.apply(action, this);
    }
}

更新

以上只是一个例子,使用type作为选择器并不是重点。

决定调用哪个X 方法的选择标准可以是任何东西。在骰子游戏中,X 可以是“奇数”或“偶数”,A 类可以是具有 1-6 int 值的“骰子”。

该示例使用抽象的enum 方法来避免switch 语句(不易出错)。抽象方法实现是一种切换技术,在这种情况下选择合适的X的方式。

更新 2

这个问题是关于用于避免 switch 语句在类之外执行“动作”逻辑的模式 (A),而不是关于更改 A (策略/策略) 的行为,其中“开关选择" 定义明确,例如作为类型枚举(上面的示例),或通过 A 的知名子类。

例如,A 可以定义一个表列。该类不应与实现代码紧密耦合,但会有许多不同的实现方法(“Actions”)必须以不同方式处理列类型。

操作可能是对ResultSet 上的适当getXxx 方法的调用,在PreparedStatement 上调用适当的setXxx 方法,格式化显示的值,将其呈现为XML 或Json,解析值,. ..

所有这些方法要么需要switch 声明,要么他们可以使用“类型化”方法实现接口,并要求类“请为我调用正确的方法”。

这个问题变得很长。对不起,如果我没有清楚地说明模式。

【问题讨论】:

  • 在策略模式中给猫剥皮的一种方法。
  • 当你提出一个合理的问题时,你不讨厌它吗?然后两年后,有人过来并没有任何解释地投票?碰巧注意到 -2 ... 在您的活动仪表板上。有趣的是,我们都从你今天早上对我的回答的评论中受益;-)
  • 我同意这是一种模式,自从我在 1990 年代看到我的第一个面向对象程序以来,我已经看过很多次了。恕我直言,它与访问者模式和策略模式都不完全相同,尽管我看到了两者的关系。换句话说,正如你的问题似乎暗示的那样,如果它有自己的名字会很好。

标签: java design-patterns


【解决方案1】:

这类似于Visitor pattern,因为您基本上是在不更改A 的情况下添加新操作(您将其操作外部化到单独的类中)。

this.type.apply(action, this);

扮演的角色:

visitor.visit(this);

如果添加了新操作(例如 applyBoolean),如果您使用了 switch 语句,则需要更改 A 的代码。但是,在您的实现中,您只需使用新的访问者子类(一个新的 Type 枚举常量),该子类会实现原本放在 A 中的代码。

【讨论】:

  • 谢谢,这就是我要找的。 wiki 显示了带有子类的示例,因此接口使用方法重载,但由于我的示例使用枚举,我的接口必须以不同的方式命名方法。相同的模式。
  • @Andreas 你在标题中的“呼叫反转”部分很准确:en.wikipedia.org/wiki/Double_dispatch
【解决方案2】:

这是Strategy Pattern的开始

这是一种行为模式,与更常见的结构模式相反。

在您的示例中,您没有充分利用该模式。由于您为所有策略使用单一界面

在计算机编程中,策略模式(也称为策略模式)是一种软件设计模式,可以在运行时选择算法的行为。

【讨论】:

  • 策略/策略模式是关于改变某些逻辑的行为。有问题的模式不是试图改变A 的行为,而是将一些逻辑external 实现为A,这取决于A 的某些属性,通常需要@987654327 @ 语句来实现。
  • @Andreas 策略模式不需要切换。通常它使用对基本类型变量的赋值,就像你正在做的那样。它可以看作是控制反转,因为具体的“策略”作为变量传入。 'A' 的行为没有被改变,只是在运行时交替选择策略。
【解决方案3】:

我认为这个名称只是使用的语言功能的名称,polymorphism

【讨论】:

  • 多态性不是更多关于子类化吗?由于我的示例使用 type 作为选择器,我可以理解为什么多态性 可能 是合适的,但我的问题是为了更通用。如果选择器是 A 的某个整数属性的奇偶测试呢?
【解决方案4】:

看起来像函数式语言中的类型分解

【讨论】:

  • 我并不精通函数式编程。一个简单的谷歌搜索“类型分解”似乎没有提供一个很好的参考。你有类型分解解释的链接吗?
  • 似乎与此类似。 def pCons(list: List[Int]): String = list match { case Nil => "nil" case x::xs => "(" + x + "." + pCons(xs) + ")" }
  • 确实链接似乎更好。试试这个:ascendant76.blogspot.ro/2012/10/…
  • 两者都实现的是根据参数的类型调用不同的东西。
【解决方案5】:

我会说这是使用strategy pattern 的示例。 Wikipedia 文章中的示例(用 C# 编写)也使用了枚举。

【讨论】:

  • 我没有看到那里使用的枚举。
  • 对不起,我看这个例子太仓促了。它不是一个实际的枚举,而是实现公共接口的内部类的(可枚举)列表。不过,您可以使用枚举更优雅地编写相同的内容。 This answer 实际上包含使用枚举用 Java 重写的示例。
猜你喜欢
  • 2011-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多