Перемі́щення ме́тоду (англ. Move Method) - це прийом рефакторингу, який базується на принципі перенесення методу з одного класу в інший, який більше його використовує.
Проблема
Певний створений метод після його створення, почав використовуватися іншим класом більше, ніж у власним.
Рішення
Потрібно створити новий метод в класі, який використовує його більше за інших, в який перенесться код із старого методу. При цьому код оригінального методу потрібно перетворити на звернення до нового методу в іншому класі або прибрати його взагалі.
Причини рефакторингу
- Рішення перемістити метод до класу, де знаходяться дані, з якими, в основному, і працює цей метод. Це призводить до підвищення пов'язаності всередині класів.
- Рішення перемістити метод, щоб прибрати або зменшити залежність класу, що викликає цей метод, від класу, в якому він знаходився. Це може бути корисно у випадку, коли клас, що викликає, вже має залежність від того класу, куди планується його перенести. Таким чином, зменшується зв'язаність між класами.
Порядок проведення
- Перевіряємо властивості, які використовував метод до початку рефакторингу. Якщо вони використовуються тільки самим методом, то потрібно перемістити і їх. Якщо ця властивість використовується ще якимось методами, то бажано перенести і ці методи. Адже налаштовувати зв’язок між цими методами у різних класах може бути проблематично.
- Перевірити наявність інших оголошень вихідного методу у базових і похідних класах. Якщо вони є, то потрібно або відмовитися від ідеї перенесення, або реалізувати в цільовому класі (клас, до якого переносимо метод) подібність поліморфізму для забезпечення різної функціональності методу.
- Оголосити метод, який переміщуємо в цільовому класі. За потреби змінити ім’я методу для кращої відповідності цільовиму класу.
- Копіюємо код вихідного методу в цільовий, після чого пристосовуємо скопійований код під нове місце.
- Якщо метод містить обробники виключних ситуацій, то слід визначити, в якому з класів - цільовому або вихідному - логічніше буде обробляти виключення.
- Визначити як буде виконуватися звернення до переміщеного методу.
- За наявності поля чи методу, які повертають об’єкт, не вносимо додаткових змін. За відсутності – потрібно написати новий метод або поле, в якому б зберігався об’єкт класу з переміщеним методом.
- Можливо зробити з вихідного методу делегуючий, який не буде містити код, а просто буде викликати цільовий метод. Можливо залишити метод як делегуючий у вихідному класі або видалити, попередньо замінивши всі звернення до нього зверненнями до створеного в іншому класі методу.
Приклад використання прийому
Виконано мовою C#:
public class BankAccount { public BankAccount(int accountAge, int creditScore, AccountInterest accountInterest) { AccountAge = accountAge; CreditScore = creditScore; AccountInterest = accountInterest; } public int AccountAge { get; private set; } public int CreditScore { get; private set; } public AccountInterest AccountInterest { get; private set; } public double CalculateInterestRate() { if (CreditScore > 800) return 0.02; if (AccountAge > 10) return 0.03; return 0.05; } }
public class AccountInterest { public BankAccount Account { get; private set; } public AccountInterest(BankAccount account) { Account = account; } public double InterestRate { get { return Account.CalculateInterestRate(); } } public bool IntroductoryRate { get { return Account.CalculateInterestRate() < 0.05; } } }
Увага в даному прикладі звертається на метод BankAccount.CalculateInterest, в якому як можна помітити, можливо дуже зручно перемістити метод. Після застосування прийому рефакторингу, отримуємо наступні зміни:
public class BankAccount { public BankAccount(int accountAge, int creditScore, AccountInterest accountInterest) { AccountAge = accountAge; CreditScore = creditScore; AccountInterest = accountInterest; } public int AccountAge { get; private set; } public int CreditScore { get; private set; } public AccountInterest AccountInterest { get; private set; } }
public class AccountInterest { public BankAccount Account { get; private set; } public AccountInterest(BankAccount account) { Account = account; } public double InterestRate { get { return CalculateInterestRate(); } } public bool IntroductoryRate { get { return CalculateInterestRate() < 0.05; } } public double CalculateInterestRate() { if (Account.CreditScore > 800) return 0.02; if (Account.AccountAge > 10) return 0.03; return 0.05; } }
Бореться з запахами
- Стрільба дробом
- Заздрісні функції
- Оператори switch
- Паралельні ієрархії наслідування
- Ланцюжок викликів
- Недоречна близькість
- Клас даних
Прийоми рефакторингу, яким допомагає переміщення методу
- Відокремлення класу
- Вбудовування класу
- Заміна параметрів об'єктом
Схожі рефакторинги
- Відокремлення методу
- Переміщення поля
Посилання
- Move Method(англ.) Сайт "Sourcemaking"
- Move Method(англ.) Сайт "Se Habla Code".
- Переміщення методу Сайт "Refactoring.guru"
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Peremi shennya me todu angl Move Method ce prijom refaktoringu yakij bazuyetsya na principi perenesennya metodu z odnogo klasu v inshij yakij bilshe jogo vikoristovuye ProblemaPevnij stvorenij metod pislya jogo stvorennya pochav vikoristovuvatisya inshim klasom bilshe nizh u vlasnim RishennyaPotribno stvoriti novij metod v klasi yakij vikoristovuye jogo bilshe za inshih v yakij perenestsya kod iz starogo metodu Pri comu kod originalnogo metodu potribno peretvoriti na zvernennya do novogo metodu v inshomu klasi abo pribrati jogo vzagali Prichini refaktoringuRishennya peremistiti metod do klasu de znahodyatsya dani z yakimi v osnovnomu i pracyuye cej metod Ce prizvodit do pidvishennya pov yazanosti vseredini klasiv Rishennya peremistiti metod shob pribrati abo zmenshiti zalezhnist klasu sho viklikaye cej metod vid klasu v yakomu vin znahodivsya Ce mozhe buti korisno u vipadku koli klas sho viklikaye vzhe maye zalezhnist vid togo klasu kudi planuyetsya jogo perenesti Takim chinom zmenshuyetsya zv yazanist mizh klasami Poryadok provedennyaPereviryayemo vlastivosti yaki vikoristovuvav metod do pochatku refaktoringu Yaksho voni vikoristovuyutsya tilki samim metodom to potribno peremistiti i yih Yaksho cya vlastivist vikoristovuyetsya she yakimos metodami to bazhano perenesti i ci metodi Adzhe nalashtovuvati zv yazok mizh cimi metodami u riznih klasah mozhe buti problematichno Pereviriti nayavnist inshih ogoloshen vihidnogo metodu u bazovih i pohidnih klasah Yaksho voni ye to potribno abo vidmovitisya vid ideyi perenesennya abo realizuvati v cilovomu klasi klas do yakogo perenosimo metod podibnist polimorfizmu dlya zabezpechennya riznoyi funkcionalnosti metodu Ogolositi metod yakij peremishuyemo v cilovomu klasi Za potrebi zminiti im ya metodu dlya krashoyi vidpovidnosti cilovimu klasu Kopiyuyemo kod vihidnogo metodu v cilovij pislya chogo pristosovuyemo skopijovanij kod pid nove misce Yaksho metod mistit obrobniki viklyuchnih situacij to slid viznachiti v yakomu z klasiv cilovomu abo vihidnomu logichnishe bude obroblyati viklyuchennya Viznachiti yak bude vikonuvatisya zvernennya do peremishenogo metodu Za nayavnosti polya chi metodu yaki povertayut ob yekt ne vnosimo dodatkovih zmin Za vidsutnosti potribno napisati novij metod abo pole v yakomu b zberigavsya ob yekt klasu z peremishenim metodom Mozhlivo zrobiti z vihidnogo metodu deleguyuchij yakij ne bude mistiti kod a prosto bude viklikati cilovij metod Mozhlivo zalishiti metod yak deleguyuchij u vihidnomu klasi abo vidaliti poperedno zaminivshi vsi zvernennya do nogo zvernennyami do stvorenogo v inshomu klasi metodu Priklad vikoristannya prijomuVikonano movoyu C public class BankAccount public BankAccount int accountAge int creditScore AccountInterest accountInterest AccountAge accountAge CreditScore creditScore AccountInterest accountInterest public int AccountAge get private set public int CreditScore get private set public AccountInterest AccountInterest get private set public double CalculateInterestRate if CreditScore gt 800 return 0 02 if AccountAge gt 10 return 0 03 return 0 05 public class AccountInterest public BankAccount Account get private set public AccountInterest BankAccount account Account account public double InterestRate get return Account CalculateInterestRate public bool IntroductoryRate get return Account CalculateInterestRate lt 0 05 Uvaga v danomu prikladi zvertayetsya na metod BankAccount CalculateInterest v yakomu yak mozhna pomititi mozhlivo duzhe zruchno peremistiti metod Pislya zastosuvannya prijomu refaktoringu otrimuyemo nastupni zmini public class BankAccount public BankAccount int accountAge int creditScore AccountInterest accountInterest AccountAge accountAge CreditScore creditScore AccountInterest accountInterest public int AccountAge get private set public int CreditScore get private set public AccountInterest AccountInterest get private set public class AccountInterest public BankAccount Account get private set public AccountInterest BankAccount account Account account public double InterestRate get return CalculateInterestRate public bool IntroductoryRate get return CalculateInterestRate lt 0 05 public double CalculateInterestRate if Account CreditScore gt 800 return 0 02 if Account AccountAge gt 10 return 0 03 return 0 05 Boretsya z zapahamiStrilba drobom Zazdrisni funkciyi Operatori switch Paralelni iyerarhiyi nasliduvannya Lancyuzhok viklikiv Nedorechna blizkist Klas danihPrijomi refaktoringu yakim dopomagaye peremishennya metoduVidokremlennya klasu Vbudovuvannya klasu Zamina parametriv ob yektomShozhi refaktoringiVidokremlennya metodu Peremishennya polyaPosilannyaMove Method angl Sajt Sourcemaking Move Method angl Sajt Se Habla Code Peremishennya metodu Sajt Refactoring guru