З точки зору принципів SOLID, відповідь jgauffin має сенс. Однак ви не повинні забувати про загальні принципи дизайну, наприклад приховування інформації .
Я бачу кілька проблем із даним підходом:
- Як ви самі зазначали, люди не очікують використання "нового" ключового слова при створенні об'єкта не керує жодним станом . Ваш дизайн відображає його намір. Люди, які використовують ваш клас, можуть заплутатися в тому, який стан він управляє, і чи можуть наступні виклики методу спричинити різну поведінку.
- З точки зору людини, яка використовує клас, внутрішній стан добре прихований, але, бажаючи внести зміни в клас або просто зрозуміти його, ви робите речі більш складними. Я вже багато писав про проблеми, які я бачу з методами розщеплення, щоб зменшити їх менше , особливо при переході стану до області класу. Ви змінюєте спосіб використання вашого API саме для того, щоб мати менші функції! Це, на мій погляд, безумовно, забирає це занадто далеко.
Деякі пов'язані посилання
Можливо, головний аргумент полягає в тому, наскільки далеко слід розтягнути Принцип єдиної відповідальності . "Якщо ви сприймете це до крайніх і будуєте класи, які мають одну причину існування, ви можете закінчити лише один метод на клас. Це призведе до великого розповсюдження класів навіть для найпростіших процесів, внаслідок чого система буде важко зрозуміти і важко змінити ».
Ще одна відповідна посилання, що стосується цієї теми: "Розділіть свої програми на методи, що виконують одне ідентифіковане завдання. Зберігайте всі операції методу на одному рівні абстракції ." - Кент Бек Клю тут "той самий рівень абстракції". Це не означає "одне", як це часто трактують. Цей рівень абстракції повністю відповідає контексту, для якого ви проектуєте.
То який правильний підхід?
Не знаючи вашого конкретного випадку використання, важко сказати. Існує сценарій, в якому я іноді (не часто) використовую подібний підхід. Коли я хочу обробити набір даних, не бажаючи робити цю функціональність доступною для всього діапазону класу. Я писав про це в блозі, як лямбдаси можуть ще більше покращити інкапсуляцію . Я також почав запитання на цю тему про програмістів . Далі - останній приклад того, де я використовував цю техніку.
new TupleList<Key, int>
{
{ Key.NumPad1, 1 },
...
{ Key.NumPad3, 16 },
{ Key.NumPad4, 17 },
}
.ForEach( t =>
{
var trigger = new IC.Trigger.EventTrigger(
new KeyInputCondition( t.Item1, KeyInputCondition.KeyState.Down ) );
trigger.ConditionsMet += () => AddMarker( t.Item2 );
_inputController.AddTrigger( trigger );
} );
Оскільки той самий "локальний" код в ForEach
не використовується більше ніде, я можу просто зберігати його в тому місці, де він є актуальним. Викладення коду таким чином, що код, який спирається один на одного, сильно згрупований між собою, робить його більш зрозумілим на мою думку.
Можливі альтернативи
- У C # ви можете використовувати методи розширення. Тож працюйте над аргументом безпосередньо ви переходите до цього методу «одне».
- Подивіться, чи справді ця функція не належить до іншого класу.
- Зробіть це статичною функцією в статичному класі . Це, швидше за все, є найбільш підходящим підходом, що також відображається в загальних API, на які ви посилалися.
bool arrayContainsSomestring = new List<string>(stringArray).Contains("somestring");
коли мені було все байдуже - це конкретна інформація, а методи розширення LINQ недоступні. Добре працює і вписується всерединуif()
умови, не потрібно стрибати через обручі. Звичайно, ви хочете зібраний сміттям мову, якщо ви пишете такий код.