1. C# / Говнокод #4056

    +101

    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
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    88. 88
    89. 89
    90. 90
    private void SetValue(UserStructure item, int id, int tabKey, int elementKey, string newValue)
            {
                if (!item.Chats.ContainsKey(id))
                    throw new KeyNotFoundException(String.Format(
                        "Чат с id = '{0}' недоступен с этой учётной записи", id));
    
                if (item.UserName != item.Chats[id].Own)
                {
                    switch (item.Chats[id].UserPremission)
                    {
                        case UserPremission.AccountLocked:
                            throw new AccessViolationException(String.Format(
                                "Чат с id = '{0}' заблокирован", id));
                    }
                }
    
                int assemblyNumber = item.Chats[id].AssemplyNumber;
    
                if (!_contentManager.AssembplyContent.ContainsKey(assemblyNumber))
                    throw new NotImplementedException(String.Format(
                        "Для сборки = '{0}' контент не реализован", assemblyNumber));
    
                Dictionary<int, TabItem> tabs = _contentManager.AssembplyContent[assemblyNumber];
    
                if (!tabs.ContainsKey(tabKey))
                    throw new NotImplementedException(String.Format(
                        "Вкладка с ключём = '{0}' в сборке = '{1}' не существует", tabKey, assemblyNumber));
    
                if (!tabs[tabKey].Elements.ContainsKey(elementKey))
                    throw new NotImplementedException(String.Format(
                        "Элемент с ключём = '{0}' во вкладке = '{1}' и сборке = '{2}' не существует", 
                        elementKey, tabKey, assemblyNumber));
    
                ElementItem element = tabs[tabKey].Elements[elementKey];
    
                GetSetParametrs getSetParametrs = new GetSetParametrs(item.Chats[id]);
    
                switch (element.ContentType)
                { 
                    case ContentType.text_box:
                        switch (element.Resource)
                        { 
                            case ResourceType.file:
                                getSetParametrs.SetValueToFile(element.Value, newValue);
                                break;
    
    			...............................................
    
                            case ResourceType.change_login:
                                getSetParametrs.SetValueToChangeLogin(item.UserName, newValue);
                                break;
    
                            case ResourceType.change_password:
                                getSetParametrs.SetValueToChangePassword(newValue);
                                break;
                        }
                        break;
    
                    case ContentType.payment_button:
                        switch (element.Resource)
                        {
                            case ResourceType.extend_chat:
                                getSetParametrs.PayForChat();
                                break;
    
                            case ResourceType.clear_credentials:
                                getSetParametrs.SetValueToClearCredentials(element.Price);
                                break;
    
                            case ResourceType.clear_users:
                                getSetParametrs.SetValueToClearUsers(element.Price);
                                break;
                        }
                        break;
    
                    case ContentType.money_transfer:
                        switch (element.Resource)
                        {
                            case ResourceType.money_to_chat:
                                getSetParametrs.SetValueToMoneyTransfer(item.MainChat, newValue);
                                break;
                        }
                        break;
    
                    default:
                        throw new FieldAccessException(String.Format(
                            "Ресурс '{0}' с ключём = '{1}' во вкладке = '{2}' и сборке = '{3}' недоступен для редакирования",
                            element.Resource, elementKey, tabKey, assemblyNumber));
                }
            }

    Люди, не гавнокод ли?
    Напрягает объёмность метода.
    А сколько по вашему максимальное кол-во строк в методе?
    Кодинг мой, приму любую критику. По поводу использования встроенных исключений попрошу промолчать

    Запостил: Nigma143, 21 Августа 2010

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

    • Дак пол метода кидание исключений же. Имхо с учетом этого нормальная длина. Во всяком случае, длина вряд ли делает это говнокодом.
      Ответить
    • а почему
      switch (item.Chats[id].UserPremission)
                      {
                          case UserPremission.AccountLocked:
                              // ....
                      }

      а не
      if(item.Chats[id].UserPremission==UserPremission.AccountLocked)
         {
            // ....
         }

      а?

      и вообще, слишком много свитчей
      Ответить
      • Дык в будущем может добавится обработку ещё некоторых перечисления UserPremission и действие на них
        Ответить
        • Даешь полиморфизм !
          getSetParametrs - просто замечательно :)
          Ответить
      • >>и вообще, слишком много свитчей
        есть такой рефаторинг: "замена условной логики состоянием/стратегией"
        Ответить
        • столько сотен раз ты собираешься это повторить на гк =)?
          Ответить
          • у меня склероз.
            Я каждое утро забываю, что было вчера.
            Извините
            Ответить
          • ровно столько, сколько потребуется обьяснять нубам
            Ответить
    • да и вообще, писали же, что если метод не умещается в один "экран" (25 строк), то лучше его логически выделить его части и вынести в отдельные методы
      Ответить
      • например в книге "Совершенный код. издание 2" говорится о 150 строках максимум. По поводу не вместительности, можно юзать регионы
        Ответить
      • Берем стиль написания одного моего знакомого
        int x;int y=x=0;for(int z=0,y=5;x<y;x++)x*=100500;
        так и ось можно 2мя функциями написать))
        Надо, кстати, спиздить как-нить у его кусок, выложить. Хотя банально, но плотностью говнокода на 10 символов должен доставить.
        Ответить
        • "строка" обычно подразумевает предложение - как раз для таких любителей экономить место.
          Ответить
          • Предложение это ;? А еще for, while, и вопрос что еще. Всё, что отдаленно напоминает стандарт по этому поводу, что я видел,это где-то на http://www.dwheeler.com/sloccount/ и то пиздос как сомнительно.

            ЗЫ: тя кто-то минусит упорно день второй наверно.
            Ответить
            • предложение это то, что разделяется точкой с запятой. ну плюс вложенные и скобки(зависит от стиля). Но 25 строк - это всего лишь ориентировочное число. Как правило, метод должен делать ОДНУ задачу, а не десять
              Ответить
              • Задачи тоже разные бывают. Бывают и циклы больше любого экрана -- я же не буду алгоритм бить на части и делать лишние обходы ради "читабельности"? Да и вызовов становится больше... Инлайны, конечно, хорошо, но в дебаг-сборке скорость начинает угнетать.
                Не знаю, слишком спорный вопрос, чтобы ставить рамки. Хотя для шарпа их ставить проще, чем для плюсов и тем более сей.
                Да и все равно писать будет каждый подсознательно под свой экран. Если это вообще его колышит. Всё же это меньше всего влияет на читабельность.
                Ответить
                • конечно же, точных чисел нет и исключения бывают. Но исключения, как известно, лишь подтверждают правила
                  Ответить
            • по поводу ЗЫ - не кто-то, а все. И видно есть за что. Надо больше думать перед написанием комментов
              Ответить
    • Метод должен помещаться на экран.
      Если не помещается -- с помощью рефаторинга "extract method" дробим его на более мплкие
      Ответить
      • Или с помощью PgDown))
        А серьезно -- у меня экран 11", на работе 22", а у друга что-то за 30. Даже с 9 высотой шрифта я на 11" мало что-тто таких методов вижу, чтоб помещались.
        Ответить
        • Ну как минимум три одинаковых switch (element.Resource) замените на стратегию/состояние

          и вообще -- метод можно разнести как минимум на 4 аккуратненьких метода.

          "Любой кусок кода, которому ты можешь дать название -- выноси в метод" (с) Фаулер
          Ответить
          • Не знаю, как в ваших шарпах, но как плюсер могу сказать: на каждый чих делать методы не стОит. Кста, может даже наплодить дублированный код или заставит передавать больше аргументов.
            Этот конкретный метод -- согласен, я бы разнес, но больше так -- в целях самоорганизации.
            Ответить
            • шарпы не мои, а выносить конечно нужно с умом.
              Смысл всего лишь в том, что лучше вынести кусочек кода и дать ему понятное название, чем городить к нему комментарии например.

              Ну если конечно Вы пишете драйвер, и для Вас каждый вызов функции на счету -- то конечно не надо так делать
              Ответить
        • ну если логика метода становится непонятной, то это верный знак, что рефакторинг не помешает. А то и поможет
          Ответить
          • да. Этот метод правда не читаем
            Ответить
            • Ну почему же, вначале видно что проверяем права на изменение и всякое такое. Далее уже распознаём контент и далее уже ресурс.

              Думаю можно было сделать так:
              Свитчи по контенту оставить а ресурс уже вынести в отдельный метод
              Ответить
              • Три одинаковых строчки "switch (element.ContentType)" это запах кода по имени "дублирование".

                Я бы сказал, как это лечится, но прийдет xXx_totalwar и скажет что я уже это говорил)))
                Ответить

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