Извлечение методов

Оценить
(0 голоса)

При помощи операции извлечения метода вы можете создать (или извлечь) новый метод из группы строк кода, единственной строки или выражения внутри данной строки кода. В каж­дом случае метод создается немедленно по образцу того метода, код которого извлекается. Извлеченный код заменяется вызовом нового метода.

В листинге 9.1 показан пример типичного слишком длинного метода. Для удобства ссылок мы добавили номера строк. Когда вы анализируете код, то такие методы встречаются часто и именно их вам и следует искать. Этот метод создан как статический вызов, который воз­вращает объект Object данного клиента (по идентификационному номеру клиента и иден­тификационному номеру заказа). Однако заказ, строки заказа и подробности о клиенте — все это поступается из разных запросов к базам данных и сохраняется в специфичных объ­ектах. Затем эти объекты сохраняются в заказе как свойства.

01   public static Order GetCustomerOrder(int customerld, int orderld) {

02

03   DataAccess.DAL dal = new DataAccess.DAL();

04   Order order = new Order();

06   // Получить подробности заказа

07   System.Data.DataTable dtOrder = dal.GetData("customerOrder", orderld);

09   // Проверить заказ по клиенту

10   if (customerld != (int)dtOrder.Rows[0][Mcustomer_idM]) {

11   throw new ApplicationException("Invalid order for the given customer.");

12   }

13   order.Id = (string)dtOrder.Rows[0]["id"];

14

«

15   // Получить позиции заказа

16   List<OrderItem> items = new List<OrderItem>();

17   System.Data.DataTable dtltems = dal.GetData("orderlterns", orderld);

18   foreach (System.Data.DataRow r in dtltems.Rows) {

19   Orderltem item = new Orderltem((int)r["product_id"], orderld);

20   item.Name = (string)r["name"];

21   item. Description = (string)r["description"];

22   item.Quantity = (int)r["quantity"];

23   item.UnitPrice * (double)r["unit_price"];

2    4 items. Add (item) ;

25   }

26   order.Items = items;

27

28   // Получить подробности по клиенту

29   System.Data.DataTable dtCustomer = dal.GetData("customer", customerld);

30   Customer cust = new Customer(customerld);

31   cust.Name = (string)dtCustomer.Rows[0]["name"];

32   order.Customer = cust;

33

34   return order; 1

35   }

Возможности по извлечению метода внутри данного метода весьма многочисленны. Вы можете извлечь вызов для инициализации объекта Order, вызов для получения позиций заказа, а также вызов для получения подробностей по клиенту. Это приведет к улучшению организации кода (и таким образом он станет более читабельным), появлению больших возможностей для его многократного использования, а также к упрощению его обслужива­ния. Давайте же рассмотрим выполнение этих извлечений.

Сначала вы извлекаете код, который настраивает заказ. Для того чтобы правильно выделить код для извлечения, необходимо иметь некоторый опыт работы с этим инструментом. В данном случае извлеките строки 3—13. Это извлечет код, начиная с настройки DataAccess и до инициализации заказа. Однако это несколько сбивает с толку операцию Extract Method, поскольку вы в первых двух операциях настраиваете и объект DataAccess, и объект Order. Операция Extract Method понимает, что позже в вашем ме,тоде вам будут нужны оба этих объекта. Поэтому она создаст оба объекта как выходные параметры метода. Вам же нужен метод, который вернет экземпляр объекта Order и настроит свой собствен­ный объект DataAccess. Вы можете добиться этого следующим образом:

1.   Выделите строки 4—13 (от создания заказа и до инициализации).

2.   Выберите операцию рефакторинга Extract Method (при помощи меню, щелчка правой кнопкой мыши или клавиатурного аккорда).

3.   Visual Studio выдаст диалоговое окно Extract Method (рис. 9.11). Это диалоговое окно предоставит новое имя метода (по умолчанию — NewMethod) и сигнатуру метода. Если сигнатура метода выглядит некорректно, то вы можете отменить операцию и уточнить выделенный блок кода. В данном случае метод статический; он возвращает объект Order и принимает объекты customerld, orderld и DataAccess. Последний в сигна­туре нашей функции нам не нужен, но с этим мы скоро разберемся.

4.   Переименуйте метод во что-нибудь имеющее смысл. В данном случае переименуйте его вInitCustomerOrder.

5.   Нажмите кнопку ОК для того, чтобы метод был извлечен.

6.   Будет создан новый метод, а старый метод заменится следующим вызовом:

Order order = InitCustomerOrder(customerld, orderld, dal);

Примечание

Извлеченные методы создаются по умолчанию как закрытые (private).

У нас по-прежнему есть одна проблема с извлеченным методом: он принимает экземпляр DataAccess вместо того, чтобы создать собственный экземпляр. Описание: image204 

К счастью, вы можете ис­пользовать еще одну операцию рефакторинга для того, чтобы решить эту проблему. В дан­ном случае надо использовать операцию Remove Parameters (см. далее в этой же главе). Важно отметить, что удаление параметра приводит к его удалению как из сигнатуры метода, так и из вызова метода. Однако оно не вставляет в новый метод вызов для создания объекта DataAccess (и не удаляет его из старого метода).*Вы должны сделать это вручную.

Теперь давайте извлечем вызов для получения позиций заказа. Начнем с выделения строк 16—25 (см. листинг 9.1). Обратите внимание, что мы не хотим выделять вызов для настрой­ки свойств заказа (строка 26); мы просто хотим вернуть объект, который представляет все строки данного заказа. На рис. 9.12 показано выделение кода и извлечение метода. В дан­ном случае назовите новый метод Getorderitems. После извлечения метода он заменяется следующим вызовом нового метода:

List<OrderItem> items = GetOrderItems(orderId, dal);

Рис. 9.12. Извлечение кода в метод для возвращения позиций заказа

Опять у нас проблема с передачей объекта DataAccess в новый метод. Эту проблему нужно решить так "же, как вы делали это раньше.

Наконец, давайте рассмотрим извлечение той части метода, которая получает подробности по клиенту. Теперь эта процедура должна быть достаточно простой. Вы выделяете строки кода (строки 29—31) и выбираете операцию Extract Method. Вы называете новый метод GetCustomer и работаете с извлеченным параметром DataAccess.

Новый (и гораздо более короткий) метод выглядит наподобие листинга 9.2. Кроме того, у вас теперь имеются три новых метода, которые вы сможете повторно использовать в буду­щем (и, возможно, сделать открытыми). Эти новые методы можно увидеть в листинге 9.3.

Листинг 9,2. Статический метод после извлечений

public static Order GetCustomerOrder(int customerld, int orderld) {

Order order = InitCustomerOrder(customerld, orderld);

Извлечение методов

List<OrderItem> items = GetOrderltems (orderld) ; order.Items = items;

// Получить подробности по клиенту Customer cust = GetCustomer(customerld); order.Customer = cust;

return order;

}

private static Customer NewMethod(int customerld) {

DataAccess.DAL dal = new DataAccess.DAL();

System.Data.DataTable dtCustomer = dal.GetData("customer", customerld); Customer cust = new Customer(customerld); cust.Name = (string)dtCustomer.Rows[0]["name"]; return cust;

}

i

private static List<OrderItem> GetOrderltems(int orderld) { List<OrderItem> items = new List<OrderItem>();

DataAccess.DAL dal = new DataAccess.DAL();

System.Data.DataTable dtltems = dal.GetData("orderltems", orderld); foreach (System.Data.DataRow r in dtltems.Rows) {

Orderltem item = new Orderltem ( (int) r ["product_id" ], orderld);

item.Name = (string) r ["name"];

item.Description = (string)r["description"];

item.Quantity = (int)r["quantity"];

item.UnitPrice = (double)r["unit_price"];

items. Add (item) ;

}

return items;

}

0

private static Order InitCustomerOrder(int customerld, int orderld) { Order order = new Order();

// Получить подробности заказа DataAccess.DAL dal = new DataAccess.DAL();

System.Data.DataTable dtOrder = dal.GetData("customerOrder", orderld);

11   Проверить заказ по клиенту

if (customerld != (int)dtOrder.Rows[0]["customer_id"]) {

throw new ApplicationException("Invalid order for the given customer.");

}

order.Id = (string)dtOrder.Rows[0]["id"]; return order;

}

Примечание

Операция Extract Method не позволяет вам выбрать место для извлекаемого метода. Очень часто вы будете обнаруживать фрагменты кода, которые действительно нужно извлечь в метод другого класса. Для этого вам придется сначала извлечь метод, а за­тем перенести его вручную.

Извлечение единственной строки кода
Генерируем заглушку метода
Извлечение интерфейса
Доступ к операции Extract Interface
Извлечение интерфейсов

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


Защитный код
Обновить

© 2017 www.visualstudios.ru. Все права защищены.