Hacker News new | ask | show | jobs
by Frieren 673 days ago
> u.isAdult()

Being adult is not a property of the user but of the jurisdiction that the user is in. In some places or some purposes it is 18 but it could be, e.g., 21 for other purposes.

If you software is not going to just run on the USA it is not a good idea to implement isAdult in the user but in a separated entity that contains data about purpose and location.

2 comments

With proper OO you could still implement that on the user object.

    boolean isAdult() {
        return this.age >= this.location.ageOfAdulthood();

        // or this.location.isAdult(this.age);  pick your poison!
    }

…anyway it’s just an example of how to introduce OO concepts. As everything in programming it depends
Just having some fun with bikeshedding here: Yeah, that could work but IMO in a big/international system the responsibility should ideally live elsewhere, since:

* You may need to determine adulthood for a different jurisdiction than where the person currently resides. Their citizenship may be elsewhere, or you may be running a report that expects "adulthood" to be by some other region's standards, etc.

* Sometimes the underlying kind of adult-need wanted is slightly different, like for consuming alcohol or voting.

* There may be a weird country or province has laws that need additional factors, like some odd place where it's a different age-cutoff for men and women.

Yes this is just extreme bike-shedding at this point. But none of this is impossible with more OO principles, like interfaces:

    class User {
        // Convenience function to check if the user is an adult in their current location
        boolean isAdult() {
            return this.location.isAdult(this);
        }


        boolean isOfDrinkingAge() {
            return this.location.isOfDrinkingAge(this);
        }
    }

    interface Location {
        boolean isAdult(User u);
        boolean isOfDrinkingAge(User u);
    }

    class WeirdLawsLocation implements Location {
        boolean isAdult(User u) {
            return switch (u.gender()) {
                case MALE -> u.age() >= 16;
                case FEMALE -> u.age() >= 18;
            }     
        }

        boolean isOfDrinkingAge(User u) {
            return u.age() >= 21
        } 
    }
In the hypothetical that you want to check somewhere the user is not currently:

    class SwedenLocation implements Location {
        boolean isAdult(User u) {
            return u.age() >= 18;
        }

        boolean isOfDrinkinAge(User u) {
            return u.age() >= 18;
        }
    }
    var sweden = new SwedenLocation();
    sweden.isOfDrinkingAge(user);
That feels like unnecessary levels of indirection to provide a method that shouldn't be on the User anyway.

    j = Jurisdiction.fromUserLocation(user);
    j.isOfDrinkingAge(user);
> that shouldn't be on the User anyway.

That’s just your opinion. It’s ok to provide convenience functions. I see no difference between the amount of indirection in our implementations, except mine is in the more natural place and you don’t have to know how to get a location or jurisdiction to answer the question: “is this user an adult?”. Knowing that it uses a location or jurisdiction is an implementation detail that you shouldn’t couple yourself to.

Cheers mate, I think I’m done moving goal posts for this conversation :)

On a side note, this discussion really made me realize how useful concise method bodies would be in Java: https://openjdk.org/jeps/8209434
Wow, thanks for proving that OOP was a mistake.
I challenge you to do it better then.

Also from the guidelines:

> Please don't post shallow dismissals, especially of other people's work. A good critical comment teaches us something.

> Being adult is not a property of the user but of the jurisdiction that the user is in.

It's a function of both. And I'd argue it's really mainly a function of the person: Independently of jurisdiction, there's at least a rough global consensus what "being adult" means, and most jurisdictions set rather similar (many of them, identical) limits.

A four-year-old isn't an adult anywhere; a fourty-year-old is everywhere.