Skip to content

Instantly share code, notes, and snippets.

@felipesere
Last active July 8, 2018 16:32
Show Gist options
  • Save felipesere/0df9b83948047665d12ec1bbade93732 to your computer and use it in GitHub Desktop.
Save felipesere/0df9b83948047665d12ec1bbade93732 to your computer and use it in GitHub Desktop.
Programmable Getter in Java 6

"Programmable" getter in Java 6.

The get(...) method takes a Question and evaluates it. Questions have a bunch of "modern" chainable methods like:

  • refineWith(Question q) or then (Question q)
  • or(Question) and orAsk(Question q) and orAsk(otherSubject, Question q) for a matching answer type
  • orDefaultTo(answer) in case of exceptions or null
    @Test
    public void useTheAlternativeWhenItThrows() {
        Person bob = new Person("Bob", "Sinclair");

        assertThat(bob.get(throwingQuestion().orAsk(lastName())), is("Sinclair"));
    }
    @Test
    public void alternativeQuestionsAreLazy() {
        Person bob = new Person("Bob", "Sinclair");

        assertThat(bob.get(firstName().orAsk(throwingQuestion())), is("Bob"));
    }

    @Test
    public void alternativeQuestionOfDifferentSubject() {
        Person bob = new Person("Bob", "Sinclair");
        Address address = new Address("Old Street");


        assertThat(bob.get(lastName().orAsk(address, streetName())), is("Sinclair"));
    }

    @Test
    public void stillARegularQuestion() {
        Person bob = new Person(null, null);

        Question<Person, String> anyName = firstName().or(lastName()).orDefaultTo("Pablo");
        assertThat(bob.get(anyName), is("Pablo"));
    }

    private Question<Person, String> throwingQuestion() {
        return new Question<Person, String>() {
            @Override
            public Answer<String> answer() {
                throw new RuntimeException("💥");
            }
        };
    }

 

    public Question<Person, String> firstName() {
        return new Question<Person, String>() {
            @Override
            public Answer<String> answer() {
                return Answer.with(subject.firstName);
            }
        };
    }

    public Question<Person, String> lastName() {
       return new Question<Person, String>() {
           @Override
           public Answer<String> answer() {
               return Answer.with(subject.lastName);
           }
       };
    }
    
     public Question<Address, String> streetName() {
        return new Question<Address, String>() {
            @Override
            public Answer<String> answer() {
                return Answer.with(subject.street);
            }
        };
    }
    
    public class Person extends AcceptsQuestions<Person> {
        private final String firstName;
        private final String lastName;

        public Person(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }
    }

    public class Address extends AcceptsQuestions<Address> {
        private final String street;

        public Address(String street) {
            this.street = street;
        }
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment