Как выбрать между статическими и нестатическими методами в C #? - PullRequest
14 голосов
/ 28 апреля 2009

[Изменить]

Мой оригинальный вопрос был «Почему нужно выбирать между статическим и нестатичным? Оба делают то же самое ...»

К сожалению, он был отредактирован до специфического для C # вопроса, чего я действительно хотел избежать.

Итак, позвольте мне сделать несколько дополнений:

Когда я говорю "интерфейс", я имею в виду не интерфейс C # -ключей, а то, что я понимаю, что-то вроде интерфейса С ++: набор четко определенных функций для работы с моим объектом. Говоря об ослаблении моего интерфейса, я имею в виду разные функции (статические / нестатические), которые выполняют одно и то же. Мой интерфейс больше не определен, когда есть разные функции для выполнения одной и той же вещи.

Итак, как написал Боб Джанитор, я могу реализовать функцию Validate () -

Document.Validate(myDocumentObject);    

но также

myConcreteDocumentObject.Validate();

Чтобы вернуться к моему Copy () - например, можно реализовать Copy () как

myConcreteDocument.Copy(toPath);

но также

Document.Copy(myConcreteDocumentObject, toPath)

или

Document.Copy(fromPath, toPath)

когда я думаю о папке, которая содержит все файлы, принадлежащие моему Документу (в этом случае я не зависим от конкретного экземпляра - но я зависим от других вещей:)).

В общем, я говорю о статических методах, а не о статических классах (извините, если я забыл упомянуть).

Но, как сказал Антон Гоголев, я думаю, что мой класс по Документам не является хорошим примером и не очень хорошо продуман, поэтому я думаю, что мне придется взглянуть на Принцип Единой Ответственности.

Я также мог бы реализовать какой-то класс ManagerClass, который работает с моим DocumentClass:

Например:

myDocumentManagerObject.Copy(myConcreteDocumentObject, toPath);

или

myDocumentManagerObject.Copy(myConcreteDocumentObject, toPath);

но если я обращаюсь к подходу 1), я склонен создавать объекты, которые выполняют свои задачи самостоятельно, а не другие объекты (DocumentManager), которые делают что-то с моим DocumentObject.

(Надеюсь, это не пойдет на сторону религиозной дискуссии об ООП;).)

[/ EDIT]


Старая версия:

Сначала кажется, что это очень простой вопрос, например, «когда использовать статические методы, а когда нет», но с этим я время от времени сталкиваюсь (и мне трудно описать, в чем заключается настоящая проблема; возможно, это просто чтобы получить причины, почему (не) использовать 1) или почему (не) использовать 2)).

(хотя я использую синтаксис C #, это не проблема C #)

В ООП существует два подхода (среди прочих) к работе с объектами:

1) Если я хочу, чтобы мой объект что-то сделал, я просто говорю ему сделать это:

myConcreteObject.DoSomething();

Это как разговаривать с объектом.

2) Или, если вы поклонник статических методов:

ObjectClass.JustDoIt();

В каком-то смысле я думаю, что статические функции просто "чувствуют" себя лучше. Поэтому я склонен использовать статические методы очень часто (быть независимым от конкретного экземпляра - независимость всегда полезна).

Итак, при разработке класса мне часто приходится решать, использовать ли мне подход 1) или подход 2):

Представьте, что у вас есть класс «Документ», который должен обозначать документ, который должен быть сохранен в базе данных:

Документ

  • состоит из одного или нескольких файлов изображений из файловой системы (они становятся страницами одного документа)
  • имеет что-то вроде библиографии - поля, в которые пользователь может добавлять информацию о документе, которая сохраняется в дополнительном файле
  • и должен иметь некоторые операции, такие как Copy (), AddPage (), RemovePage () и т. Д.

Теперь я сталкиваюсь с несколькими способами создания этого класса:

//----- 1) non static approach/talking to objects -----
Document newDocument = new Document();

// Copy document to x (another database, for example)
newDocument.Copy(toPath);

Мне нравится это: я приказываю документу скопировать себя в базу данных x, и объект делает это сам. Ницца.

//----- 2) static approach ----------------------------
Document.Copy(myDocumentObject, toPath);

Почему бы и нет? Также приятно, очень удобно ...

Так, что реализовать? И то и другое? Или поместить статический подход в своего рода вспомогательный класс? Или выбрать подход 1) и придерживаться его, чтобы не ослабить интерфейс моего Document-класса?

Размышляя об обоих подходах, я прихожу к выводу, что (теоретически) можно реализовать любую функцию как статическую функцию:

Class.Function(aConcreteClassObject, parameters);

но также нестатично:

aConcreteObject.DoSomething(parameters);

Чтобы привести пример из реальной жизни:

[EDIT (добавлен параметр из пути "Извините, я забыл")]

//----- 2) static approach ----------------------------
File.Copy(fromPath, toPath);    // .Net-Framework-like

[/ EDIT]

но также:

//----- 1) non static approach ------------------------
ExampeFileClass fileObject = new ExampleFileClass();
fileObject.Copy(toPath);

или даже (вид OOP-Overkill):

//----- 1) non static approach, too -------------------
fileObject.ToPath = @"C:\Test\file.txt";     // property of fileObject
fileObject.Copy();                           // copy to toPath

Итак, почему (не) использовать 1) или почему (не) использовать 2)?

(Я бы не стал слишком концентрироваться на примере класса Document, так как это более общий вопрос о хорошем дизайне класса.)

Ответы [ 11 ]

0 голосов
/ 28 апреля 2009

В целом, я бы сказал, что «копирование» себя в отношении объекта обычно означает клонирование данных в новый объект. Описанное здесь «копирование» - это то, что файловая система делает от вашего имени, а не объект. Поэтому я бы сделал это статическим методом, а не методом в экземпляре Document.

...