通常我希望一旦构造了一个对象,它就应该可以使用了。没有两步建设。如果你需要调用两个构造函数来使用一个对象,那么是非常错误的......对吗?
class Contact
attr_accessor :auth_token
def initialize(contact_hash)
...
end
def edit(...)
auth_token.can! :read, self
end
end
token = AuthorizationToken.new(session)
contact = SomeService.get_contact(...)
contact.edit(...)
# raise error because auth_token is not set
contact.auth_token = token
contact.edit(...)
上面的代码代表了我当前的困境:我希望 SomeService 给我联系对象,但我不希望该服务关注现有会话,或者授权。
我目前的做法是增加这个额外的课程:
class QueryService
def initialize(session)
token = AuthorizationToken(session)
end
def get_contact
contact = SomeService.get_contact(...)
contact.token = token
end
end
contact = QueryService.new(session).get_contact(...)
contact.edit(...)
此解决方案让我可以最自由地在核心域对象联系人中使用授权问题,在外部类 AuthorizationToken 中实现它们,并实现不关心的服务当前用户会话 SomeService 。
然而,这两步建设正在扼杀我。感觉很奇怪:某个操作没有完全初始化的对象???
这不是依赖注入的简单情况,更确切地说是上下文注入。所以关于在Ruby中避免DI的大部分文章并没有真正解决我的问题。我想知道是否有一个更多的Ruby方式来解决这个问题,或者这个问题就像它可以得到的一样干净。
答案 0 :(得分:0)
看起来您的Contact
类有两个目的 - 存储联系人数据并执行一些授权请求 - 所以是的,它确实违反了Single Responsibility Principle。
这可以通过将Contact
类拆分为两个来修复 - 一个可能是Struct
,甚至是一个普通的哈希来存储数据,第二个用于处理请求。
我认为最常用的 Ruby 方法是从SomeService
返回哈希值,稍后用Contact.new(data, auth_token)
实例化。