2010-10-23 3 views
21

Я читаю Programming Scala. В начале главы 4 автор комментирует, что Java поддерживает статические методы, которые являются «не столь чистыми понятиями OO». Почему это так?Почему статические методы не считаются хорошей практикой OO?

+6

Я не уверен, что «не так чисто» должно быть немедленно связано с плохой практикой. – mellowsoon

+0

Неплохая практика. По словам автора, просто не очень хорошая практика. – Mike

+1

Не дает ли автор никаких аргументов? – 2010-10-25 01:37:06

ответ

17

Одна из причин того, что статические методы не очень OO, о которых до сих пор не упоминалось, заключается в том, что интерфейсы и абстрактные классы определяют нестатические методы. Таким образом, статические методы не очень хорошо вписываются в наследование.

Обратите также внимание на то, что статические методы не имеют доступа к «super», что означает, что статические методы не могут быть переопределены в каком-либо реальном смысле. На самом деле они не могут быть переопределены вообще, только скрыты. Попробуйте следующее:

public class Test { 
    public static int returnValue() { 
     return 0; 
    } 

    public static void main(String[] arg) { 
     System.out.println(Test.returnValue()); 
     System.out.println(Test2.returnValue()); 
     Test x = new Test2(); 
     System.out.println(x.returnValue()); 
    } 
} 


public class Test2 extends Test { 
    public static int returnValue() { 
     return 1; 
    } 
} 

Когда вы запустите это, вы не получите то, что ожидаете. Test.returnValue() дает то, что вы ожидаете. Test2.returnValue()скрывает метод с тем же именем в суперклассе (он не переопределяет его), и он дает то, что вы ожидаете.

Можно было бы наивно ожидать, что «нестатически» вызывает статический метод использования полиморфизма. Это не так. Независимо от того, какой класс объявляется как переменная, используется тот, который использовался для поиска метода. Это плохая форма, потому что кто-то может ожидать, что код сделает что-то отличное от того, что он на самом деле делает.

Это не означает: «Не используйте статические методы!«Это означает, что вы должны зарезервировать использование статических методов для тех случаев, когда вы действительно хотите, чтобы объект класса владел этим методом, а не просто как ленивый способ создания синглета.

+0

Этот ответ, вероятно, имеет наибольший смысл из того, что я видел до сих пор. Разрыв одной из концепций Троицы, безусловно, идет вразрез с зерном. – Mike

+0

Не то, чтобы я оспариваю это, но пример, который вы показываете, применим только к Java правильно? IIRC, Java - единственный язык OO (с которым я столкнулся), который позволяет вызывать статические функции через экземпляр класса. –

+0

@Jeff: VB.NET также допускает это бессмысленное поведение. –

1

Статические методы не являются настолько чистыми концепциями ОО, потому что они могут быть вызваны без связанного с ними объекта. Вы используете сам класс. Вы вызываете их так: Classname.method(...);

+0

Что делать, если я использую что-то вроде Ruby, которое поддерживает классы-объекты и статические вызовы? Фактически объект будет связан со статическим вызовом. – Mike

+0

Ну, я не уверен, насколько он ассоциировался с Java, когда он сказал, что он сделал, но дело в том, что даже в Java есть объекты, которые создаются и управляются самими представлениями самих классов, так что это все обсуждается , в некоторой степени. Тем не менее, простая идея о том, что у вас есть статический основной метод и статические методы, которые вы можете вызывать без каких-либо объектов, делает это немного против парадигмы ООП. –

0

Концепция OO говорит о контроле/доступе к данным от объекта, но статические методы не нужно вызывать с использованием объекта, и они принадлежат классу, а не объекту.

--Cheers

24

Не путайте «не столь чистые понятия ОО» с «плохой практикой». Быть «чистым ОО» - это не какая-то панацея, которую вы должны пытаться достичь. Просто потому, что статические методы не принимают переменную экземпляра в качестве параметра, это не значит, что они не являются полезными. Некоторые вещи просто не поддаются объектам, и их нельзя вводить в эту форму только ради «чистоты».

Некоторые люди считают, что вещи должны быть «чистыми», и, следовательно, все, что «нечисто», является плохой практикой. В действительности, плохая практика - это просто вещи, которые запутывают, трудно поддерживать, трудны в использовании и т. Д. Создание статических методов, которые принимают экземпляр , - это плохая практика, потому что любой метод, который принимает экземпляр, вероятно, должен быть методом экземпляра. С другой стороны, такие вещи, как служебные и заводские функции, как правило, не принимают экземпляр, поэтому они должны быть статическими. должен быть.

Если вам интересно, почему они не являются «чистым ОО», это потому, что они не являются методами экземпляра. «Чистый» язык OO имел бы все, что является объектом, а все функции - экземплярами. Конечно, это не очень полезно все время. Например, рассмотрим метод Math.atan2. Он принимает два номера и не требует никакого состояния. Какой объект вы могли бы сделать его способом от? В «чистом» языке OO Math может сам быть объектом (возможно, одним), а atan2 будет методом экземпляра, но поскольку функция фактически не использует какое-либо состояние в объекте Math, это также не концепция «чистого ОО».

+0

Имейте в виду, что я никогда не говорил, что это плохая практика, поэтому на мой вопрос не ответил. ;) – Mike

+2

Правда. С другой стороны, я видел слишком много кода, где все одноэлемент, и все статично. Этот тип кода, как правило, сложнее модифицировать, сложнее расширить, сложнее переделать, чтобы сделать то, чего изначально не предназначалось. Тем не менее, слишком много людей слишком догматично об этом. – Eddie

+0

Фактически, функция «atan2» измеряет радиан угла a * одной точки * на положительную ось x. Другими словами, он не должен принимать два аргумента числа, в первую очередь, он должен принимать одноточечный аргумент. Который в терминах ОО мог быть смоделирован как метод на точечном объекте. –

40

Объектная ориентация - это три вещи :

  • сообщений,
  • местного сохранение и защита и скрытие государственного процесса и
  • крайность позднего связывания всех вещей

из них три. , наиболее важным является обмен сообщениями.

Статические методы нарушают, по меньшей мере, обмен сообщениями и позднюю привязку.

Идея обмен сообщениями означает, что в OO вычисление выполняется сетями автономных объектов, которые отправляют сообщения друг другу. Отправка сообщения только способ связи/вычисления.

Статические методы этого не делают. Они не связаны ни с каким объектом. Они действительно не методы на всех, в соответствии с обычным определением. Они действительно просто процедуры. Практически нет никакой разницы между статическим методом Java Foo.bar и подпрограммой BASIC FOO_BAR.

Что касается позднего связывания: более современное название для этого - динамическая отправка. Статические методы также нарушают это, на самом деле, это даже само название: static методов.

Статические методы ломают некоторые очень приятные свойства объектной ориентации. Например, объектно-ориентированные системы автоматически могут быть безопасными с объектами, действующими как возможности. Статические методы (или действительно any статика, будь то статическое состояние или статические методы) нарушают это свойство.

Вы также можете выполнять каждый объект параллельно в своем собственном процессе, поскольку они обмениваются сообщениями только через обмен сообщениями, тем самым обеспечивая некоторый тривиальный параллелизм. (Как Актеры, в основном, что не должно быть слишком удивительным, поскольку Карл Хьюитт создал модель актера на основе Smalltalk-71, а Алан Кей создал Smalltalk-71 частично на основе PLANNER, который, в свою очередь, был создан Карлом Хьюиттом. Тесная взаимосвязь между субъектами и объектами далека от случайных, по сути, они по существу одно и то же.) Опять же, статика (как статические методы, так и , особенно статическое состояние) ломает это приятное свойство.

+0

Это также отличный ответ. Хотел бы я принять более одного. Спасибо. – Mike

1

Статические методы вызывают жесткую связь, что является нарушением хорошей объектно-ориентированной конструкции. Тесную связь вызывающего кода и кода внутри статического метода нельзя избежать посредством инверсии зависимостей, потому что статические методы по своей сути не поддерживают объектно-ориентированные методы проектирования, такие как Наследование и Полиморфизм.

Кроме того, статические методы трудно проверить из-за этих тесно связанных зависимостей, которые часто приводят к сторонней инфраструктуре, от которой зависит код - как база данных, и это очень затрудняет изменение поведения без фактического перехода и изменение кода.

0

Статические методы не считается хорошей практикой ОО из-за следующих причин:

1) предотвращает от повторного использования:

Статические методы не могут быть переопределены. Он не может использоваться в интерфейсе.

2) Время жизни объекта очень длинный:

Статические методы остаются в памяти в течение времени, журнала и его сбора мусора занимает много времени. Разработчики не имеют контроля над уничтожением или созданием статических переменных. Чрезмерное использование статических переменных может привести к переполнению памяти.

3) Кроме того, некоторые другие моменты:

Он не уважает инкапсуляцию, потому что объект does't остаются в полном контроле ее состояния. Он не следует таким концепциям, как инверсия управления, свободная связь, инъекция зависимостей и т. Д.