0

I'm trying to implement my first domain driven application, after going through Eric Evan's book on Domain-Driven Design. I'm a bit confused on how to go about creating Value Objects.

So in my application, a user can purchase a service for getting them certain number of views on a video they post in Youtube, which is fulfilled by the other users of my app who watch those videos(Basically a replica of the many youtube promoter apps already available, for learning).

Say the service is represented in the app as an entity called WatchTime. The WatchTime entity contains some information like the MaxViews(max number of views purchased) and CurrentViews(number of views already fulfilled). The MaxViews and CurrentViews are value objects, and both are similar.

So the thing is, should I have a common 'Views' Value Object that is the type for both the MaxView and CurrentView domain concepts, something like this:

class Views extends ValueObject<Views> {
    @override
    bool fsameValueAs(Views other) {
       // Implementation
    }


    int mvalue;
}


class WatchTime extends Entity<WatchTime> {
    @override
    bool fsameIdentityAs() {
        // Implementation
    }



    Views mmaxViews;
    Views mcurrentViews;
}

or

should I make a seperate class for MaxViews and Current Views since they are domain concept and they should be explicit, kinda like this:

class Views {}

class MaxViews extends ValueObject<MaxViews> {
    // Other stuff

    Views mviews;
}

class CurrentViews extends ValueObject<CurrentViews> {
    //Other stuff

    Views mviews;
}

class WatchTime extends Entity<WatchTime> {
    @override
    bool fsameIdentityAs() {
        // Implementation
    }



    MaxViews mmaxViews;
    CurrentViews mcurrentViews;
}

or

something like this:

class MaxViews extends ValueObject<MaxViews> {
    // Other stuff

    int mviews;
}

class CurrentViews extends ValueObject<CurrentViews> {
    //Other stuff

    int mviews;
}

class WatchTime extends Entity<WatchTime> {
    @override
    bool fsameIdentityAs() {
        // Implementation
    }



    MaxViews mmaxViews;
    CurrentViews mcurrentViews;
}

I'm not really sure how I should go about this.

I'm also not sure about another thing from the book. So I understand that making concepts of the domain explicit will make the application more clearer and easier to navigate and read. So to make something explicit, is is necessary to make it an entity or a value object with the same name as the domain class, or is the variable name being the same as the domain concept sufficient.

For example, .

class Money {}

Money mSalary;

vs

class Salary {}

Salary mSalary;

I'm pretty sure my suggestions might look very stupid, I would be happy if you could give me better suggestions. Thanks.

Yamin Nather
  • 99
  • 1
  • 6

1 Answers1

2

I'm not really sure how I should go about this.

Either answer can be best, depending on your domain, how similar these things are to one another, how often they change, do they change for the same reasons, and so on.

A common sentiment is duplication is cheaper than the wrong abstraction. In other words, if you aren't yet sure that these implementations should all be derived from a common base, then keep them separate, and watch it.

You should also look into Item 19 of Effective Java, by Joshua Block. "Design and document for inheritance, or else prohibit it".

Designing a class for inheritance requires great effort and places substantial limitations on the class.... it is not uncommon to receive subclassing-related bug reports after modifying the internals of a nonfinal concrete class that was not designed and documented for inheritance.

Note that you also have the option of have two independent classes that implement one or more common interfaces, which can help to reduce the amount of coupling you have to worry about.


is is necessary to make it an entity or a value object with the same name as the domain class

No. It's common that you can have more than one data member of the same type; the name of the member does NOT have to match the name of the member's type.

VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91
  • Thanks a lot! For this case, for the first part i guess I'll stick to the first approach for now I guess. Regarding the second question, if a uniqueId of type string for some entity, which is a value object, does not have any validation or any specific behaviour attached to it, should I still model it as a class extending value object because its a domain concept or should I just make it a type of string? – Yamin Nather May 21 '21 at 16:09
  • 1
    @YaminNather It's common to have specific value types for IDs mostly to avoid ambiguity and use the wrong variable at the wrong place. For instance, `changeComment(String id, String comment)`, you could always make the mistake of `changeComment(comment, id)` and it would compile. The abstraction is also helpful should you need to change the way IDs are structured or whatever. – plalx May 23 '21 at 13:55
  • @plalx that makes a lot of sense, thank you so much! Its currently that way, I'm keeping it like that. Sorry for this, but I have another question too, https://stackoverflow.com/questions/67650055/confusion-regarding-bounded-contexts-and-interaction-between-them, could you help me out with that too :) – Yamin Nather May 23 '21 at 14:42