Extra Monad and Demeter Law in Java

while I was looking at some code, I came across this snippet.

List<User> users = /* Some code that initializes the list */;
users.stream()
     .filter(user -> user.getAddress().isPresent())
     .map(/* Some code */)
// And so on...

A method call user.getAddress()returns Optional<Address>. Following the famous Law of Demeter (LoD), the code above is not clean. However, I cannot figure out how to reorganize it to make it cleaner.

As a first attempt, you can add a class Usermethod hasAddress(), but this method will overcome the need to have Optional<Address>, IMO.

How do I reorganize the above code? In this case, is it worth satisfying LoD?

EDIT : I missed the indication that in the method mapI do not want to return the address.

+6
source share
5 answers

Well, you summarized it very well: if you wanted to connect more freely by entering hasAddress(), why return Optional.

Reading what LoD says means there is "limited" knowledge of "closely related" units. Sounds like a gray color to me, but later on he also mentions the rule "Only one point". However, I agree with the comments on your question that the zero check (or isPresent()) is completely fine (heck, the real check for zero information does not technically need a dot; P).

If you want to really encapsulate more, you can completely remove getAddress()and suggest instead:

class User {
    private Optional<Address> address;

    boolean hasAddress() {
        return address.isPresent();
    }

    // still exposes address to the consumer, guard your properties
    void ifAddressPresent(Consumer<Address> then) {
        address.ifPresent(then::accept);
    }

    // does not expose address, but caller has no info about it
    void ifAddressPresent(Runnable then) {
        address.ifPresent(address -> then.run());
    }

    // really keep everything to yourself, allowing no outside interference
    void ifAddressPresentDoSomeSpecificAction() {
        address.ifPresent(address -> {
            // do this
            // do that
        });
    }
}

, : /? / , . LoD KISS.


, , User. , // :

  • , User
  • (, UserDao, POJO? DAO ? , " " " "?)
  • ...
+3

, ( , getAddress ), Java 9 :

users.stream()
    .map(User::getAddress)
    .flatMap(Optional::stream)
    .map(/* Some code */)

users.stream()
    .flatMap(user -> user.getAddress().stream())
    .map(/* Some code */)
+1

, .

:

  • ,
  • .

, hasAddress(), . , Optional, . .

0

, LoD , - , (.. / ). "" - ; , .

, , . "" , 0 - - , , .

, isPresent, , . , SQL, , NULL SQL .

, ?

0

.

, . , LoD

0

All Articles