Як професійні програмісти висловлюють судження про те, чи варто йти на ООП чи ні? Це було б дуже корисно для мене.
Для мене є два моменти рішення. По-перше, іноді це буде очевидно на початку. Буде багато подібних типів, які мають загальні методи, що сильно відрізняються деталями їх реалізації. Наприклад, я будував систему робочого процесу, і мені потрібна була можливість реалізувати довільні завдання. Для виконання завдання я реалізував базовий клас, від якого успадковано кожне завдання, з Execute()абстрактним методом. Класи успадкування забезпечували реалізацію, але система робочого процесу могла розпочати виконання, нічого не знаючи про те, який тип завдання виконується.
Однак більшість проектів не настільки чіткі. Другий момент рішення - це коли підмножина проекту переросла у величезний клубок висловлювань "if-then" або "case-switch", і особливо, коли для цих тверджень потрібна велика кількість параметрів, щоб правильно запустити. Я відчуваю, що починаю втрачати логіку того, що намагаюся досягти, і код починає відчувати себе тендітним. У цей момент це, як правило, знак того, що настав час перефактурувати код на базові класи із конкретними реалізаціями.
Велика частина переходу на об'єктно-орієнтований стиль на відміну від функціонального стилю полягає в перетворенні операторів if-then в оператори "запустити цю дію". Замість величезного набору операторів if-then ви просто скажете коду виконати його дії. Яка дія насправді виконується, залежить від наданої вами реалізації.
Наприклад, ось функціональний стиль у псевдокоді C # -style:
if ( action == "email" ) {
callEmailFunction(userInfo);
}
else if ( action == "sms" ) {
callSmsFunction(userInfo);
}
else if ( action == "web" ) {
endpoint = "http://127.0.0.1/confirm";
confirmWeb(endpoint, userinfo);
}
...
Але, можливо, ви могли б переписати це на щось подібне:
interface IConfirmable {
void Confirm(UserInfo userinfo);
}
public class ConfirmEmail : IConfirmable {
public void Confirm(UserInfo userinfo) {
// do the appropriate thing to confirm via email
}
}
public class ConfirmSms : IConfirmable {
public void Confirm(UserInfo userinfo) {
// do the appropriate thing to confirm via email
}
}
public class ConfirmWeb : IConfirmable {
// this is a constructor
public ConfirmWeb(string endpoint) {
...
}
public void Confirm(UserInfo userinfo) {
// do the appropriate thing to confirm via web
}
}
А потім сам код:
// An implementation that decides which implementation of the base class to use
// This replaces the if-then statements in the functional programmming.
IConfirmable confirmer = ConfirmerFactory.GetConfirmer();
// get the userinfo however you get it,
// which would be the same way you get it in the functional example.
UserInfo userinfo = ...;
// perform the action.
confirmer.Confirm(userinfo);
Тепер, коли в if-then є дуже мало коду, це виглядає як багато роботи, щоб не отримати користі. І коли в if-then є дуже мало коду, це правильно: це дуже багато роботи для коду, який важче зрозуміти.
Але об’єктно-орієнтований стиль справді світить, коли у вас є більше ніж одна дія, ніж просто Confirm()метод, який потрібно виконати. Можливо, у вас є програма ініціалізації, три або більше методів дій, які можна запустити, і Cleanup()метод. Базовий алгоритм ідентичний, за винятком того, що він здійснює виклики у відповідні об'єкти, що реалізують загальний базовий клас. Тепер ви починаєте бачити реальну користь для об'єктно-орієнтованого стилю: базовий алгоритм читати набагато простіше, ніж якби він перевіряв твердження if-then на кожному кроці шляху.