抽象工厂可以负责 "creating or finding an existing" 项吗?

Can an Abstract Factory be responsible for "creating or finding an existing" item?

我的 Ruby 代码有一个 Concrete Factory,它构建了一些复杂的对象:

author = Author::Factory.build(email: "john@example.com")

class Author
  class Factory < BaseFactory
    def self.build(email: nil)
      # ... Some data preparation and defaults
      Author.new(
        email: email
        # Map and assign more attributes
      )
    end
  end
end

现在,我 运行 遇到了一种情况,我要么需要构建一个新的,要么 或从现有集合中分配一个。在 数据库术语:UPSERT,或在 ActiveRecord 中:find_or_create_by.

而且我不确定这是不是:

  1. 是抽象工厂的正确任务并且
  2. 如果正确的实现方法是传递集合,或者 让工厂自己负责获取它。

传入:

author = Author::Factory.build(email: "john@example.com", existing: authors)

class Author
  class Factory < BaseFactory
    def self.build(email: nil)
      author = existing.find {|author| author.email == email }
      # If not found, prepare and build a new one, like above.
    end
  end
end

让工厂找到它:

author = Author::Factory.build(email: "john@example.com")

class Author
  class Factory < BaseFactory
    def self.build(email: nil)
      author = Author.find_in_existing_with(email: email)
      # If not found, prepare and build a new one, like above.
    end
  end
end

所以:每个工厂都应该负责寻找或建造吗?

如果是这样,工厂必须负责获取那些物品吗? 它必须匹配,或者调用者应该传递它们吗?

Factory 是一种创建模式,因此客户会期望从中获得新的实例。

当然,Factory 在内部执行的操作与使用代码无关。但是,如果 Author 是一个域实体,我看不出 Author 构建对象如何被消费者用于除 "real world" 在系统中添加新作者之外的任何其他用途。

除非你想在语义上不公平,并通过重用现有作者而不是实例化新作者来欺骗调用者。但这看起来不像您在生产中通常会做的事情。