Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
razovy
0 / 0 / 0
Регистрация: 16.04.2010
Сообщений: 3
#1

Задача на логическое мышление на собеседовании

13.08.2013, 04:58. Просмотров 1654. Ответов 6
Метки нет (Все метки)

Имеется несколько классов. В каждом классе есть функция, внутри которой имеется длинный switch с одними и теми же логическими условиями для каждого класса но вызывающими свои уникальные "классовые" функции.

Вопрос : Как избавиться от переписывания одного и того же switch - a , чтобы в каждом классе был вызов ОДНОЙ и той же функции, где этот switch и реализуется?
Может как то с делегатами ???
Спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.08.2013, 04:58
Ответы с готовыми решениями:

Задачка на собеседовании
Дали задачку на собеседовании.A,B-булевские переменные. Есть выражение A?B:!B...

Вопросы по MS SQL на собеседовании .net junior
Доброго времени суток, друзья. В ходе подготовки к собеседованию в одну...

Какие вопросы надо задать на собеседовании?
Собственно наверно странный вопрос, но.... Какие вопросы надо задать на...

Какие вопросы могут задать на собеседовании по C# для начинающего программиста
Подскажите пожалуиста, какие вопросы могут задать на собеседовании по C# для...

на логическое мышление
Известна зарплата каждого из 12 работников фирмы за каждый месяц первого...

6
Psilon
Master of Orion
Эксперт .NET
5989 / 4842 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
13.08.2013, 08:06 #2
Razovy, полиморфизм.
Замена условного оператора полиморфизмом (Replace Conditional with Polymorphism)
Есть условный оператор, поведение которого зависит от типа объекта. Переместите каждую ветвь
условного оператора в перегруженный метод подкласса. Сделайте исходный метод абстрактным.
C#
1
2
3
4
5
6
7
8
9
10
11
double getSpeed() {
switch (_type) {
   case EUROPEAN:
      return getBaseSpeed();
   case AFRICAN:
      return getBaseSpeed() - getLoadFactor() * _numberOfCoconuts;
   case NORWEGIAN_BLUE:
      return (_isNailed) ? 0 : getBaseSpeed(_voltage);
}
throw new RuntimeException (“Should be unreachable”);
}
Задача на логическое мышление на собеседовании

Мотивировка
Одним из наиболее внушительно звучащих слов из жаргона объектного программирования является
полиморфизм. Сущность полиморфизма состоит в том, что он позволяет избежать написания явных условных
операторов, когда есть объекты, поведение которых различно в зависимости от их типа.
В результате оказывается, что операторы switch, выполняющие переключение в зависимости от кода типа,
или операторы if-then-else, выполняющие переключение в зависимости от строки типа, в объектно-
ориентированных программах встречаются значительно реже.
Полиморфизм дает многие преимущества. Наибольшая отдача имеет место тогда, когда один и тот же
набор условий появляется во многих местах программы. Если необходимо ввести новый тип, то приходится
отыскивать и изменять все условные операторы. Но при использовании подклассов достаточно создать новый
подкласс и обеспечить в нем соответствующие методы. Клиентам класса не надо знать о подклассах, благодаря
чему сокращается количество зависимостей в системе и упрощается ее модификация.
Техника
Прежде чем применять «Замену условного оператора полиморфизмом» ( Replace Conditional with
Polymorphism), следует создать необходимую иерархию наследования. Такая иерархия может уже иметься как
результат ранее проведенного рефакторинга. Если этой иерархии нет, ее надо создать.
Создать иерархию наследования можно двумя способами: «Заменой кода типа подклассами» ( Replace Type
Code with Subclasses ) и «Заменой кода типа состоянием/стратегией» (Replace Type Code with State/Strategy).
Более простым вариантом является создание подклассов, поэтому по возможности следует выбирать его.
Однако если код типа изменяется после того, как создан объект, применять создание подклассов нельзя, и
необходимо применять паттерн «состояния/стратегии». Паттерн «состояния/стратегии» должен использоваться
и тогда, когда подклассы данного класса уже создаются по другим причинам. Помните, что если несколько
операторов case выполняют переключение по одному и тому же коду типа, для этого кода типа нужно создать
лишь одну иерархию наследования.
Теперь можно предпринять атаку на условный оператор. Код, на который вы нацелились, может быть
оператором switch (case) или оператором if.
Если условный оператор является частью более крупного метода, разделите условный оператор на части и
примените «Выделение метода» ( Extract Method ).
При необходимости воспользуйтесь перемещением метода, чтобы поместить условный оператор в
вершину иерархии наследования.
Выберите один из подклассов. Создайте метод подкласса, перегружающий метод условного оператора.
Скопируйте тело этой ветви условного оператора в метод подкласса и настройте его по месту.
Для этого может потребоваться сделать некоторые закрытые члены надкласса защищенными.
Выполните компиляцию и тестирование.
Удалите скопированную ветвь из условного оператора.
Выполните компиляцию и тестирование.
Повторяйте эти действия с каждой ветвью условного оператора, пока все они не будут превращены в
методы подкласса.
Сделайте метод родительского класса абстрактным
1
Psilon
Master of Orion
Эксперт .NET
5989 / 4842 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
13.08.2013, 08:08 #3
Видно, что тут ручной рефакторинг, выделение метода давно уже существует в самой студии. Более подробно читайте оригинал.
0
turbanoff
Эксперт Java
4014 / 3749 / 741
Регистрация: 18.05.2010
Сообщений: 9,329
Записей в блоге: 11
Завершенные тесты: 1
13.08.2013, 08:56 #4
Цитата Сообщение от Razovy Посмотреть сообщение
Как избавиться от переписывания одного и того же switch - a , чтобы в каждом классе был вызов ОДНОЙ и той же функции, где этот switch и реализуется?
Унаследуйте все ваши классы от одного общего абстрактного класса.
В этот класс перенести switch. В case ветках вызывайте новые абстрактные методы, и, соответственно в потомках необходимо будет вынести вызов старых методов в реализацию новых методов.
0
kolorotur
Эксперт .NET
10008 / 8407 / 2063
Регистрация: 17.09.2011
Сообщений: 14,471
13.08.2013, 16:27 #5
Цитата Сообщение от Razovy Посмотреть сообщение
Задача на логическое мышление
Это, скорее, задача на знание паттернов проектирования и умение распознавать моменты, где эти паттерны надо применить.
0
razovy
0 / 0 / 0
Регистрация: 16.04.2010
Сообщений: 3
14.08.2013, 00:46 #6
Спасибо за ответы и советы - Я посмотрел original article on http://sourcemaking.com/refactoring.

Возможно, я не совсем полно сформулировал проблему , так как, к сожалению, реальная задача была более противная:
Для простоты предположим, что есть всего есть два (реально штук 10) класса (ClassA and ClassB) как бы никак не обьединяемых по общему признаку за исключением conditional operators cостоящих, для простоты же, из двух case-s (реально около 20 условий). Фукции в каждом классе совершенно разные как по параметрам там и по возвращаемым типам:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 
class ClassA
   {
 
      public void ClassAMethod(string sCondition, int iParam1, int iParam2, string sParam3)
      {
         int m = 0;
         string s = String .Empty ;
         switch (sCondition)
         {
            case "Condition 1": m=ClADo1(iParam1,   iParam2,   sParam3); break;
            case "Condition 2": s=ClADo2( sParam3); break;
             default: Console.WriteLine("Class1 - default"); break;
         }
      }
      int ClADo1(int iParam1, int iParam2, string sParam3) { Console.WriteLine("ClADo1");/* Do something */ return 2; }
      string ClADo2(string sParam3) { Console.WriteLine("ClADo2");/* Do something */ return "a"; }
   }
   class ClassB
   {
 
      public void ClassBMethod(string sCondition,  string sParam3)
      {
          
         int l = String.Empty;
         switch (sCondition)
         {
            case "Condition 1":   ClBDo1(sParam3); break;
            case "Condition 2": l = ClBDo2( ); break;
            default: Console.WriteLine("Class2 - default"); break;
         }
      }
      void ClBDo1(  string sParam3) { Console.WriteLine("ClBDo1");/* Do something */ return  ; }
      int ClBDo2() { Console.WriteLine("ClBDo2"); /* Do something */return  33  }
   }
Вот как их объединить, чтобы в абстрактном классе, если идти этим путем, не было "лишних" функций?
Или другой подход?

Спасибо.

Добавлено через 5 минут
Поправка:

int l = 0;
0
Psilon
Master of Orion
Эксперт .NET
5989 / 4842 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
14.08.2013, 08:59 #7
Razovy, ну метод общий можно сделать, но особый смысл в нем теряется.
0
14.08.2013, 08:59
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.08.2013, 08:59

Задача на мышление
помогите пож

Задача на собеседовании
Добрый день. Являюсь начинающим разработчиком и пытался проходить одно...

Задача на собеседовании
Доброго времени суток, написал задачу с собеседования прошу Вас посмотреть, и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru