1. Java / Говнокод #14417

    +75

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    ObservableStorage.ConfigurationTuple<Integer, ObservableStorage.ConfigurationTuple<Foo, ObservableStorage.ConfigurationTuple<Foo, ObservableStorage.ConfigurationEnd>>> build = RemoteObservableStorage
            .configurationBuilder()
            .use("foo").as(Foo.class)
            .use("foo1").as(Foo.class)
            .use("ids").as(Integer.class)
            .build();

    И тут Остапа понесло :)
    Всем тайп сейфити посоны

    Запостил: myzone, 26 Января 2014

    Комментарии (30) RSS

    • А как этот build потом юзают?
      Ответить
      • https://gist.github.com/myzone/75684349191615a2e222

        где-то так :)
        Ответить
        • Хм, т.е. по туплу бегаем при помощи .next()?

          Чего не сделаешь ради типобезопасности.
          Ответить
          • Именно так.

            И, да, я понимаю, что джава не лучший способ делать такие вещи :)
            Ответить
            • > джава не лучший способ делать такие вещи :)
              Ага, в крестах его можно было бы индексировать: configuration.get<2>().
              Ответить
              • Я имел ввиду не это, а нормальный вывод типов с маджонгом и поэтессами.
                Чтобы можно было написать просто
                val configuration = RemoteObservableStorage
                                .configurationBuilder()
                                .use("foo").as(Foo.class)
                                .use("foo1").as(Foo.class)
                                .use("ids").as(Integer.class)
                                .build();

                Да и вообще круто их было бы именовать и потом по именам получать, но как такое сделать, идей нет :(
                Причем именовать не стрингами, а чем-то более безопасным.
                Ответить
                • > а чем-то более безопасным
                  Именами классов, больше то нечем ;)
                  Ответить
                  • Bот именно, что нечем, но я уверен, что есть языки, в которых есть такие средства
                    Ответить
                    • Кстати, что-то до меня сейчас дошло - а чем эта штука отличается от самого обычного POJO? :)

                      Набор полей - фиксированный.
                      Типы - проверяются.
                      Флюент - при желании вполне реализуем.

                      Пока вижу только один плюс - заставляет заполнить все поля.

                      P.S. Ааа, чтобы перехватить установку значений и куда-то их передать...
                      Ответить
                    • А если как-то так? http://ideone.com/Fa870W
                      Ответить
                      • Нужно больше типобезопасности!

                        Теперь "поля" разных "структур" нельзя смешивать:http://ideone.com/eKPhPl
                        Ответить
                • google lombok
                  Ответить
                  • это остров такой в индонезии
                    с клёвым пляжем и опасными аборигенами
                    Ответить
                  • google купил lombok project?

                    PS Лично я не одобряю такие, имплицитные типы - ладно, но методы - уже перебор
                    Ответить
                  • Та не, не хорошее решение :( Засоряет код херней всякой. В моей Яве раз в сто больше собачек, чем в типичном ПХП проекте. Объявления свойств / методов изза этого распухают вообще невероятно. Просто ради интереса посчитал: тот же в принципе класс написаный на Питоне: 6 строк, на Лиспе: 2 строки, на Яве: 60 строк...
                    Ответить
    • Напомнило
      http://www.functionaljava.org/examples/1.5/#HList.append
      Ответить
    • >.use("foo").as(Foo.class)
      .useAs("foo", Foo.class) ?
      Ответить
      • прошу прощения, у меня fluent interface головного мозга
        Ответить
        • btw, а это ведь просто частично применение, не?
          Ответить
      • кстати, хвалю - это отличный пример кода, где fi скорее запутывают, нежели помогают, т.к. для билдеров предполагается, что порядок вызовов неважен, а тут, получается, еще как!
        Ответить
        • я знал, что кто-то заметит, но могу огорчить.
          interface ConfigurationBuilder<T extends ConfigurationTuple<?, ?>> {
          
          	@NotNull BuildingPhase1<T> use(@NotNull String collectionName);
          
          	@NotNull T build();
          
          	interface BuildingPhase1<T extends ConfigurationTuple<?, ?>> {
          
          	    @NotNull <F> ConfigurationBuilder<ConfigurationTuple<F, T>> as(@NotNull Class<F> entityClass);
          
          	}
          
          }

          И да, фаз изначально было больше.
          И вообще, я не тру, ибо считаю с единицы :(
          Ответить
        • Или ты имел ввиду тот факт, что от последовательности вызовов тип будет другой?
          Ответить
          • я про обязательность связки use...as. действительно, лучше одним методом, так понятнее
            Ответить
            • Тогда я думаю, листинг выше расставил все по полочкам.
              У тебя не получится вызвать build() без вызова as(), и не получится вызвать as() без вызова use(), так что этот вопрос решен
              А вот вопрос того, что в списке типов важен порядок - реальная проблемка, если у кого есть решения буду рад выслушать.

              PS тут IRC канала нет?
              Ответить
              • Есть форум, который засрали спамеры и где пудак вебмастер постоянно проводит эксперименты.
                Ответить
                • Как говорится: все го на канал #govnokod на freenode.net, я создал :D
                  Ответить

    Добавить комментарий