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

    +73

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    public boolean alwaysAllowed(String player) {
    		return getServer().getPlayer(player).hasPermission("over9000homes.alwaysAllowed");
    	}
    	
    	public boolean remoteAccess(String player) {
    		return getServer().getPlayer(player).hasPermission("over9000homes.remote");
    	}
    	
    	public boolean canUse(String player) {
    		return getServer().getPlayer(player).hasPermission("over9000homes.use");
    	}
    	
    	public boolean canInvite(String player) {
    		return getServer().getPlayer(player).hasPermission("over9000homes.caninvite");
    	}
    	
    	public boolean infiniteHomes(String player) {
    		return getServer().getPlayer(player).hasPermission("over9000homes.infinite");
    	}
    	
    	public boolean noWarmup(String player) {
    		return getServer().getPlayer(player).hasPermission("over9000homes.nowarmup");
    	}
    	
    	public boolean noCooldown(String player) {
    		return getServer().getPlayer(player).hasPermission("over9000homes.nocooldown");
    	}
    	
    	public boolean freeSetHome(String player) {
    		return getServer().getPlayer(player).hasPermission("over9000homes.freesethome");
    	}
    	
    	public boolean freeHome(String player) {
    		return getServer().getPlayer(player).hasPermission("over9000homes.freehome");
    	}

    Всё тот же Bukkit проект.

    Запостил: Uhehesh, 12 Октября 2011

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

    • В Java есть макропрекомпилятор?
      Ответить
    • public boolean hasPermission(String player, String permission) {
          return getServer().getPlayer(player).hasPermission("over9000homes." + permission);
      }
      fixed?
      Ответить
      • Извините, но хотя бы "canInvite" необходимо оставить...
        Ответить
      • Ваша функция гуд,но чем плохи функции обертки для каждого отдельного права ?
        Тем более эти функции судя по названиям не проверяют права как таковые, вот если бы они например назывались hasInvitePermission, то другое дело. А так результат функции canInvite помимо наличия права у player может зависеть от других параметров.
        Я бы оставил вашу функцию и поместил ее вызов во все остальные, ну и конечно изменил бы названия некоторых функции на более говорящие, в частности бы добавил к ним can, как сделано у canInvite, хотя может для меня они не говорящие из-за того, что я не владею предметкой проекта
        Ответить
        • Порочна сама идея в принципе. Большое количество однотипных методов делает класс слишком статичным. Вероятность появления новых полномочий, судя по всему, довольно велика, потому имеет смысл сделать один метод, проверяющий полномочия, и отдельно иметь список всех возможных полномочий. Я бы выразил этот список в Enum'е (они специально спроектированы для дальнейшего расширения). Опять же, меньше будет проблем с сериализацией и прочими неочевидными вещами.
          Ответить
          • С одной стороны я с вами согласен, но скажем вы удалили эти функции и оставили только свою hasPermission,

            У вас везде по коду будут вызовы hasPermission(player, "caninvite") вроде все хорошо, но допустим в последующем потребуется изменить логику определения имеет ли игрок возможность делать инвайт (canInvite), скажем это будет еще зависеть от какого-либо атрибута игрока и вам придется ходить по всему коду и менять логику: hasPermission(player, "caninvite") && player->needAttribute

            Вынеся все это в отдельные методы вы избавите себя от возможного геморроя, Также мне кажется что будет неплохо разнести эти функции и функции проверки прав по разным классам. Еще раз смотря на выложенный код, я думаю, что вашу функцию я поместил бы в другой класс и использовал ее внутри этих методов
            Ответить
            • Если нужна более мощная функциональность, используем аналог паттерна Command: передаём в универсальную функцию специальный объект (если использовать Enum, для этого потребуются минимальные изменения, не затрагивающие клиентский код). Пример:
              public boolean hasPermission(String player, Permission p) {
                  return getServer().getPlayer(player).hasPermission("over9000homes." + p) &&
              p.applyConstraints(player);
              }
              Вариантов может быть много, Permission может быть интерфейсом с множеством реализаций и т.п. Мне такой вариант представляется более расширяемым.
              Ответить
              • Логика может быть разной и всю ее в одну универсальную функцию не поместишь, скажем если вам потребуется добавить возможность доступа на govnokod то логика может быть такой
                public boolean canAccessToGovnokod(String player) {
                    return hasPermission(player, "accesstointernet") && player->isGoodMan && SomeGlobalStatesClass::canAccessAllUserToInternet
                }


                Вы предлагаете инкапсулировать все эти знания в одной функции, а я в одном классе
                Ответить
                • вообще-то я предлагал вынести каждое полномочие в отдельный класс / элемент енума, и помещать всю логику туда. А функция будет лишь фасадом для вызова соответствующей логики. Тогда появляется легко комбинировать полномочия по необходимости:
                  //client code
                  Permission hasAccessToGK = Permission.Or(
                          Permission.InternetAccess, Permission.GoodMan);
                  if (hasPermission("me", hasAccessToGK)) {
                      sayWithPleasure("Fuck Yeah!");
                  }
                  Ответить
                  • > Permission.And
                    fixed
                    Ответить
                  • Оверинжениринг. То, что часто случается в жаве.
                    Ответить
                    • На самом деле в Java меня вполне устроил бы первый вариант. Java скорее останавливаем меня от описанного гибкого и типобезопасного подхода, нежели подталкивает к нему (больше букв получится, чем следовало бы для такой простой идеи).
                      Ответить
          • Чтоб не было недопонимания, если мы имеем ввиду что это класс для проверки привилегий то ваш вариант идеален.

            Но если мы говорим о классе для проверки доступности какого-либо действия для пользователя то в принципе выложенный код нормален.
            Ответить
            • А чем привилегии отличаются от возможности выполнить действие?
              Ответить
              • Ну скажем вот вы находитесь на форуме, у вас есть привилегия писать в тему, но тема закрыта (в закрытые темы обычно не пишут).

                Привилегия есть а возможности нет.
                Ответить
                • Согласен, логика в этом есть.
                  Ответить
                • В любом случае можно игнорировать привилегии в зависимости от состояния темы и прочего-прочего.
                  Ответить
                  • Поясните свой комментарий, я не до конца его понял
                    Ответить
                    • Тема открыта: проверяем привилегий - предоставляем соответствующие возможности.
                      Иначе не предоставляем никаких возможностей, либо не предоставляем возможностей редактирования темы, а, например, перемещение и удаление в соответствии с привилегиями.

                      Говоря короче - отталкиваться в первую очередь от состояния темы. А уж потом от привилегий пользователей.

                      Это всего лишь предположение. Я жеж студентота xD
                      Ответить
                      • Возможно пример с форумом не самый удачный, но он был выбран что пояснить разниму между привилегией и возможностью выполнить действие, что это не одно и тоже.

                        А по теме вашего коммента, если я вас правильно понял, то большой разницы не вижу, напишите вы так
                        if (theme->isOpen) {
                            canWrite  = hasPermission("write");
                         }
                         canDelete  = hasPermission("delete");


                        или вот так
                        canWrite  = hasPermission("write") && theme->isOpen;
                            canDelete  = hasPermission("delete");


                        У нас шла речь маленько о другом, что выложенный в топике код имеет право на жизнь и что в одном случае он может быть и говном, а в другом нет. Я попытался показать ситуацию когда этот по моему мнению не будет ГК.
                        Ответить
                    • То есть, в принципе будет 3 блока.
                      тема открыта:...проверка привилегий...
                      тема закрыта:...проверка привилегий...
                      проверка привилегий не зависящих от состояния темы

                      Как-то так. Мне интересно послушать чужое мнение пока я не начал в учебных целях писать движок форума с помощью технологии JSP.
                      Ответить
                      • Если вам интересно моё мнение, я бы использовал spring security и теги, которые он предоставляет. В результате получилось бы что-то вроде этого:
                        <sec:authorize access="hasRole('ROLE_USER')">
                            <c:if test="${!theme.closed}">
                                <button id="add-comment" value="Add a comment"/>
                            </c:if>
                        </sec:authorize>
                        Ответить
                        • Благодарю, почитаем)
                          Ответить
                          • Только нужно не забыть на методы контроллеров @Secured('ROLE_USER') повесить и проверять внутри возможность добавления коммента. А то могут найтись умники, которые и без кнопки запостить смогут.
                            Ответить
                        • Программирование на XML?
                          Ответить
                          • А вы таки хотите макет страницы на Java компоновать? Удачи. GWT в помощь.
                            Ответить
                            • Лучше продолжу держаться подальше от веба.
                              Ответить
                              • А где, по вашему, вы запостили этот коммент? :)
                                Ответить
                                • А мне стало интересно в какой сфере работает и насколько загружен день :D
                                  Ответить
                                  • Сейчас не работаю, до этого - системное на C++
                                    Ответить
                                • Имею ввиду программирование веба :-)
                                  Ответить
                                  • По мне так это очень интересно. Системное программирование тоже люблю, да. Гуишки и игрушки не люблю :(
                                    Ответить
                                    • Игрушки - очень широкая тема. http://ai-contest.com/ - это тоже игрушки :-)
                                      Ответить
                              • Напомнило:
                                Мужчина заходит в бар и заказывает стакан виски и шесть соломинок, соединяет соломинки в одну и через эту длинную соломинку начинает пить виски. Бармен недоуменно спрашивает:
                                - Почему вы так делаете?
                                - Мне доктор велел держаться подальше от спиртного.
                                Ответить
        • Именно так.
          Ответить
    • показать все, что скрытоvanished
      Ответить

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