Как создать цепочку строителей - PullRequest
0 голосов
/ 14 марта 2019

Я хотел бы создать цепочку построителей, где я могу предоставить различные наборы методов, основанные на значении i.Если я могу использовать эти промежуточные классы компоновщика, я могу ограничить доступные методы во время компиляции, а не полагаться на проверки во время выполнения.(Промежуточные классы компоновщика не предназначены для предоставления конечному пользователю, они просто предназначены для предоставления различных наборов методов после вызова set().)

public class SomeClass {
    public static class SomeClassBuilder {
        public <What should I return ?> set(int i) {
            switch (i) {
               case 1:
                   return new Case1Builder();
                   break;
               case 2:
               case 3:
                   return new Case2And3Builder();
                   break;
               case 4:
                   return new Case4Builder();
                   break;
               default:
                   return this;
            }
        }

        public SomeClass.SomeClassBuilder build() {
        }
    }

    public static final class Case1Builder() {
        public SomeClass.Case1Builder set1() {
        }
    }

    public static final class Case2And3Builder() {
        public SomeClass.Case1Builder set2And3() {
        }
    }

    public static final class Case4Builder() {
        public SomeClass.Case1Builder set4() {
        }
    }
}

А затем из моего класса драйверов, Я мог бы сделать ниже:

final SomeClass someClass = new SomeClass.SomeClassBuilder(1).set1().build();
final SomeClass someClass = new SomeClass.SomeClassBuilder(2).set2And3().build();

Возможно ли это?Может быть, с использованием дженериков?

Ответы [ 2 ]

1 голос
/ 14 марта 2019

Это невозможно. Вы можете вернуть один из нескольких типов, но так как возвращаемые типы - время компиляции, вы должны объявить супертип этих типов. Это было бы Object здесь. Очевидно, что возвращение Object не полезно.

Вы не можете вернуть один из трех типов и ожидать, что компилятор сможет предоставить доступ к различным методам, в зависимости от того, какой из трех будет возвращен. Фактический возвращаемый тип является артефактом времени выполнения, а список методов, которые вы можете вызвать, является решением во время компиляции.

Если вы хотите сделать это, вам понадобится несколько set методов.

public Case1Builder set1();
public Case2And3Builder set2Or3();
public Case4Builder set4();
public GenericCaseBuilder setOther();
0 голосов
/ 14 марта 2019

Чтобы делать вещи так, как вы пытаетесь их выполнить, вам нужно сделать что-то вроде этого:

public class SomeClass {
    public static class SomeClassBuilder implements CaseBuilder {
        public CaseBuilder set(int i) {
            switch (i) {
               case 1:
                   return new Case1Builder();
                   break;
               case 2:
               case 3:
                   return new Case2And3Builder();
                   break;
               case 4:
                   return new Case4Builder();
                   break;
               default:
                   return this;
            }
        }

        @Override
        public SomeClass build() {...}
    }

    public static final class Case1Builder() implements CaseBuilder {
        @Override
        public SomeClass build() {...}
    }

    public static final class Case2And3Builder implements CaseBuilder {
        @Override
        public SomeClass build() {...}
    }

    public static final class Case4Builder implements CaseBuilder {
        @Override
        public SomeClass build() {...}
    }


   public interface CaseBuilder {
      public SomeClass build();
   }
}

Однако, это намного сложнее, чем нужно, и на самом деле это не шаблон Builder. Я думаю, что вы на самом деле ищете фабричный шаблон или, возможно, FactoryFactory.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...