代码之家  ›  专栏  ›  技术社区  ›  WW.

当创建的类还需要运行时值时进行依赖项注入?

  •  7
  • WW.  · 技术社区  · 14 年前

    Assume you divide up your systems in Value objects and Services objects (as suggested in "Growing Object-Oriented Software, Guided by Tests". Misko Hevery calls these "newables" and "injectables".

    What happens when one of your value objects suddenly needs to access a service to implement it's methods?

    Let's say you have a nice simple Value object. It's immutable, holds a few bits of information and that's about it. Let's say we use it something like this:

    CreditCard card = new CreditCard("4111-1111-1111-1111", "07/10");
    if (card.isValid())
    {
      // do stuff
    } 
    else
    {
      // don't do stuff
    }
    

    到现在为止,一直都还不错。 isValid() 对卡号执行校验位算法并返回真/假。

    Now, let's say I wish to enhance the system by validating the expiry date against the current time. How would you suggest this is done without breaking the Value object/Service object paradim? I should like this class to continue to be unit testable.

    • CreditCard now has a dependency, but because of the way it is created it can not be injected, so dependency injection is out.
    • 这个 信用卡 class should not be calling out to Singletons (I am of the position that global access to a Singleton is bad practice)
    • 把行为放在 CreditCardVerificationService.validateCard() means all the existing code has to be revisited. isvalid()的实现正在泄漏。

    我知道有很多事情可以解决这个问题,但最干净的方法是什么?

    3 回复  |  直到 13 年前
        1
  •  4
  •   expedient    14 年前

    I would argue that it isn't a CreditCard object's job to validate anything. A factory would validate the check digits to ensure that it is instantiating a conforming card, while a verification service would validate the card for expiration/$ limit.

        2
  •  1
  •   ewernli    14 年前

    我想这么说 CreditCard 不是值对象。

    C2 wiki :

    价值对象的例子是 比如数字、日期、金钱和 串。通常,它们都很小 他们的身份是基于他们的状态 而不是他们的对象身份。 这样,您可以有多个副本 相同的概念值对象。

    值对象不是 业务对象/引用对象。一 BusinessObject/ReferenceObject是 你在世界上发现的东西,而 ValueObject是度量值或 某物的描述。

    如果 CreditCardNumber 可能是一个值对象, 信用卡 看起来更像包含一些业务逻辑的业务对象,例如验证。

    I usually have Value Object, Service and Business Object. I don't know about "Growing Object-Oriented Software", but restricting yourself to only Value Object and Service seems odd to me.

        3
  •  0
  •   Rogério    13 年前

    我会打电话 CreditCard 实体 而不是 价值对象性 因为它很可能是持久的,并且具有唯一的身份。

    Anyway, it should be perfectly fine for an entity class to use service classes. If the implementations of said services don't need to be selected at runtime based on external configuration, then I would simply instantiate and use the desired service class inside the client method. Contrary to what some may think, this doesn't preclude unit testing, as a mocking tool can be used for isolation.

    如果服务实现 需要在运行时选择,而不是 服务定位器 可以使用。This pattern can provide direct support for mocking/faking, without the need for a specialized mocking tool. Use of a DI framework supporting injection into "newed" objects would be another alternative.