Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ruby中的类界面设计模式_Ruby_Design Patterns - Fatal编程技术网

ruby中的类界面设计模式

ruby中的类界面设计模式,ruby,design-patterns,Ruby,Design Patterns,我正在寻求有关设计模式的帮助。 我非常习惯java中的接口,我不知道如何在ruby中获得类似的机制。 它需要的是一种接口,它有一种方法,例如触点。为了获得联系人,我需要对api进行调用,可以是google、linkedid或任何Web服务。 所以我想使用一个接口,它为我提供了contacts方法,我不想知道任何关于提供者的信息 我的第一次尝试如下(伪代码): 但我真的不确定,这是否是“红宝石之路” 欢迎提供帮助、建议和建议。 最好的, Phil模块通常用于排除多个对象的常见行为。我相信在这种情况

我正在寻求有关设计模式的帮助。 我非常习惯java中的接口,我不知道如何在ruby中获得类似的机制。 它需要的是一种接口,它有一种方法,例如触点。为了获得联系人,我需要对api进行调用,可以是google、linkedid或任何Web服务。 所以我想使用一个接口,它为我提供了contacts方法,我不想知道任何关于提供者的信息

我的第一次尝试如下(伪代码):

但我真的不确定,这是否是“红宝石之路”

欢迎提供帮助、建议和建议。 最好的,
Phil

模块通常用于排除多个对象的常见行为。我相信在这种情况下,你所需要的只是鸭子打字。只需在Java解决方案中共享接口的所有类中实现方法
contacts

请注意,此解决方案允许您将不同类型的对象保存在一个集合中,当您对它们进行迭代(或以任何其他方式使用这些公共接口对象)时,您只需调用此
联系人
方法,而不必关心它们的实际类型


如果您需要实现此接口的所有类中的一些常见行为,您可以创建基于
联系人
方法的模块,并将其包含在所有可以使用它的类中。

有几种很好的方法。一种是将不同的功能封装到模块中:

module Google
  def contacts
    puts 'contacts from Google'
  end
end

module LinkedIn
  def contacts
    puts 'contacts from LinkedIn'
  end
end

class Impl
  def self.create provider
    o = new
    o.extend(provider)
  end
end

Impl.create(Google).contacts
Impl.create(LinkedIn).contacts
输出:

contacts from Google
contacts from LinkedIn

在这里,
Impl
上的
create
方法是一种工厂方法,用于从给定模块中添加方法的Impl实例。只需确保模块实现相同的方法名称并返回兼容的值。

这里可以应用策略模式

def Provider
  def contacts
    raise "Abstract method called"
  end
end

class Google < Provider
  def contacts
    data = # Google API call
  end
end

class LinkedIn < Provider
  def contacts
    data = # LinkedIn API call
  end
end

class Impl
  def initialize(provider)
    case provider
    when :google
      @provider = Google.new
    when :linkedin
      @provider = LinkedIn.new
    else
      raise "Unknown provider"
    end
  end

  def contacts
    @provider.contacts
  end
end

impl = Impl.new(provider)
impl.contacts
def提供程序
def触点
提出“抽象方法调用”
结束
结束
类Google
我非常喜欢@Bui The Hoa的答案,但我要补充以下内容:

我非常喜欢这种方法,尤其是在基本提供者类中引发错误。然而,我不认为在Impl中使用case语句是好的策略模式使用。它违反了单一目的原则,因为它使实现负责跟踪所有可能的提供者。它还违反了开放-关闭原则,即类可以扩展,但不能更改,因为当您添加新的提供者时,您必须更改case语句

为什么不直接做呢

impl = Impl.new(Google.new)
由于raise“Unknown provider”错误将通过以下方式处理:

impl = Impl.new(BadProvider.new) => Error

可能重复:使用heritance并使函数在父类中引发错误。
impl = Impl.new(BadProvider.new) => Error