两步施工。有用还是只是代码味道?
Two step construction. Useful or just a code smell?
通常我希望一旦一个对象被构建,它就应该可以使用了,就这样。没有两步施工。如果您需要调用两个构造函数来使用一个对象,那就大错特错了……对吗?
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 给我 Contact 对象,但我不希望该服务根本不关心现有会话或授权。
我目前的方法是添加这个额外的 class:
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(...)
这个解决方案让我可以最自由地在核心域对象 Contact 中使用授权问题,在外部 class AuthorizationToken[ 中实现它们=30=] 并实现与当前用户会话无关的服务 SomeService。
然而,两步构建让我很痛苦。感觉很奇怪:一个对象没有为某些操作完全初始化???
这不是依赖注入的普通情况,更确切地说是上下文注入。所以Ruby中大部分关于避免DI的文章并没有真正解决我的问题。我想知道是否有 more Ruby 方法 来解决这个问题,或者这是尽可能干净的方法。
看起来您的 Contact
class 有两个目的 - 存储联系人数据和执行一些授权请求 - 所以是的,它确实违反了 Single Responsibility Principle。
这可以通过将 Contact
class 分成两部分来解决 - 一个可能是 Struct
甚至是普通哈希来存储数据,第二个可能是请求。
而且我认为最 Ruby 的方法是 return 来自 SomeService
的散列并用 [=14 实例化=]稍后。
通常我希望一旦一个对象被构建,它就应该可以使用了,就这样。没有两步施工。如果您需要调用两个构造函数来使用一个对象,那就大错特错了……对吗?
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 给我 Contact 对象,但我不希望该服务根本不关心现有会话或授权。
我目前的方法是添加这个额外的 class:
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(...)
这个解决方案让我可以最自由地在核心域对象 Contact 中使用授权问题,在外部 class AuthorizationToken[ 中实现它们=30=] 并实现与当前用户会话无关的服务 SomeService。
然而,两步构建让我很痛苦。感觉很奇怪:一个对象没有为某些操作完全初始化???
这不是依赖注入的普通情况,更确切地说是上下文注入。所以Ruby中大部分关于避免DI的文章并没有真正解决我的问题。我想知道是否有 more Ruby 方法 来解决这个问题,或者这是尽可能干净的方法。
看起来您的 Contact
class 有两个目的 - 存储联系人数据和执行一些授权请求 - 所以是的,它确实违反了 Single Responsibility Principle。
这可以通过将 Contact
class 分成两部分来解决 - 一个可能是 Struct
甚至是普通哈希来存储数据,第二个可能是请求。
而且我认为最 Ruby 的方法是 return 来自 SomeService
的散列并用 [=14 实例化=]稍后。