Я хочу создать простой конструктор, в котором я могу передать функцию и получить результат, но я хочу иметь ограничения. Например, я создал:

class Compute {
    public Compute count(Function func){ ... }
    public Compute result() {...}
}

И теперь я могу назвать это так: compute.count(function).result(), но я не могу найти, как предотвратить, прежде чем делать это compute.count(function).count(function) после count я мог только вызвать result() и не мог вызвать count. Также я хочу назвать это в этом стиле: compute.count(function).result().count(function).result(), но не хочу вызывать одни и те же методы подряд. Как решить эту проблему?

0
Developus 23 Окт 2019 в 17:31
Вероятно, вложенный статический класс для result()?
 – 
Deadpool
23 Окт 2019 в 17:34
Я считаю, что вам следует переосмыслить, почему вы разработали оба этих API для возврата Compute, а затем решить, когда разорвать цепочку. Почему бы не позволить им возвращать разные типы?
 – 
Naman
23 Окт 2019 в 19:29

1 ответ

Если вы хотите создать шаблонный код, вот безопасный способ добиться того, чего вы хотите (это всего лишь пример, вы можете настроить его по своему усмотрению):

static class User {

    static WithName builder() {
        return name -> age -> new User(name, age);
    }

    private User(String name, int age) {
        // whatever you want here
    }
}

interface WithName {

    WithAge withName(String name);
}

interface WithAge {

    User withAge(int age);
}

И вызывающий абонент выглядит так:

public static void main(String[] args) {
    User u = User.builder()
                 .withName("Bob")
                 .withAge(18);
}

Как только вы проверите это, вы увидите, что методы можно вызывать только в определенном порядке.

0
Eugene 23 Окт 2019 в 17:38
Я не уверен, могу ли я позвонить сейчас withName после withAge?
 – 
Developus
23 Окт 2019 в 17:46
Ты не можешь. в этом вся суть. вы запрещаете пользователям создавать User только определенным образом, это не сильно отличается от того, что вы хотите.
 – 
Eugene
23 Окт 2019 в 17:47
Я понимаю, но, как я уже сказал, я не хочу вызывать только одни и те же методы подряд, поэтому после withAge я мог бы вызвать withName, но после withName или withAge я не может вызывать одни и те же методы.
 – 
Developus
23 Окт 2019 в 17:49
Вы пробовали то, что я написал? ты видимо путаешь себя и меня тут
 – 
Eugene
23 Окт 2019 в 18:18
1
Ваш пример является хорошим применением шаблона построителя, но, по-видимому, ОП не может адаптировать его к реальной проблеме вопроса, который не имеет терминальной операции, а скорее должен разрешать чередующиеся вызовы. Итак, вам нужно что-то вроде interface A { B foo(); } interface B { A bar(); }, чтобы разрешить foo().bar().foo().bar(), но ни foo().foo(), ни bar().bar().
 – 
Holger
23 Окт 2019 в 19:59