Общие ООП
Я придерживаюсь мнения, что геттеры и сеттеры в значительной степени бессмысленны и глупы, независимо от того, на каком языке вы пишете код.
По большей части, открытые свойства должны быть редкими, поскольку любое свойство объекта обычно должно находиться в домене объекта, поэтому только объект должен фактически изменять свои собственные внутренние компоненты в качестве побочного эффекта других действий, а не потому, что какой-то другой объект напрямую сказал ему что-то поменять. Я уверен, что есть исключения (они всегда есть), но я не могу вспомнить, когда в последний раз мне нужно было их делать.
Кроме того, когда свойства открываются, единственная причина для раскрытия с помощью метода заключается в том, что вы либо не можете просто раскрыть свойство из-за языковых ограничений (Java), либо потому, что при изменении этого свойства должна произойти некоторая проверка или уведомление. Простое использование методов в стиле Java-bean, которые не делают ничего, кроме фактического изменения или возврата свойств, ничего не делает для сохранения инкапсуляции. Вы могли бы просто сделать собственность общедоступной, если можете.
Но настоящая проблема с желанием получить / установить все волей-неволей из любого места в том, что вы в основном просто написали связанный процедурный код и назвали его ООП. У вас все еще есть длинный извилистый ряд вещей, о которых можно рассуждать только в терминах того, что одно происходит за другим. Идея ООП состоит в том, чтобы избежать этой длинной извилистой цепочки спагетти, чтобы вы могли больше рассматривать свою архитектуру с точки зрения более крупных конструкций, которым принадлежат определенные домены, взаимодействующие друг с другом в ключевых точках. Без этого вы, возможно, уменьшите количество спагетти, по крайней мере, классифицируя свои функции по пространствам имен, чтобы было легче знать, где искать материал, но вы на самом деле не используете ключевые преимущества, которые ООП может предоставить вашей архитектуре.
Реальное значение переменных private или, в случае JS, local constructor / factory-closur - это сигнал о намерении. Если он обнажен, значит, что-то внешнее действительно должно его изменить. Если это не так, значит, вы дали понять, что var - это только бизнес объекта.
JS OOP
Мой совет - забыть об эмуляции классов в JS. Это совершенно не нужно. Прототипы изящны и просты, если вы их поймете. Думайте о свойстве прототипа конструктора как о некоем резервном объекте. Если вы вызываете метод для экземпляра, которого у него нет, следующим шагом будет проверка свойства объекта прототипа конструктора экземпляра. Если у этого объекта его нет, то проверяется объект-прототип его конструктора и так далее, пока вы, наконец, не дойдете до прототипа основного конструктора Object.
Это из-за этого процесса поиска, что вы можете добавлять новые методы в конструктор на лету и все экземпляры «наследовать» его после того, как они были построены, но на самом деле это не столько наследование, сколько резервный процесс.
Наследование в JS - это просто глупо. Это не значит, что вы должны делать много этого. Длинные цепочки каскадного наследования считаются антипаттерном на любом языке по уважительной причине, и из-за того, как работает процесс обратного вызова, он также может действительно убить производительность, если вы забиваете объект вызова через 18 уровней прототипов для каждая мелочь в JS. Я бы предпочел составные объекты наследованию, и когда наследование кажется более разумным вариантом, проверяйте себя каждый раз, когда у вас возникает соблазн наследовать через более чем 2-3 звеньев прототипа в цепочке.
О, и еще одна хитрость JS, на которую нужно обратить внимание на локальные переменные экземпляра в конструкторах как на частные свойства: на самом деле это просто правила закрытия JS в контексте области действия функции в действии. Методы, объявленные в прототипе или вне функции конструктора, не могут получить доступ к этим внутренним переменным. Функции-конструкторы, вызываемые с помощью ключевого слова new, изменяют правила доступа this, и они оставляют экземпляр позади, но в остальном выполняются JS-функциями другими способами.
Другие разновидности сумасшедшего, но также безумно мощного, стоящего понимания в JS OOP, - это методы apply, call и now bind. Я склонен рассматривать их скорее как вещи, которые вы хотели бы видеть на фабрике, но они очень эффективны.
После того, как вы освоите JS OOP, начните понимать JS с функциональной точки зрения, и вы обнаружите, что в нем действительно мощная комбинация 1-2 удара. Мы можем делать что угодно очень легко и с минимумом кода на JS. Компромисс дизайна - это производительность (с которой современные JIT-компиляторы справляются на удивление хорошо) и то, что это дает вам достаточно веревки, на которой можно повеситься. Я предпочитаю веревку. Сам линчевание - это не весело, но это часть процесса обучения / развития лучших инстинктов, который в результате происходит намного быстрее и в долгосрочной перспективе приводит к более удобному в сопровождении коду. В то время как Java в основном заставляет внедрять ООП, но из-за чрезмерного протекционизма по отношению к разработчикам, которые делают себе глупые вещи, приводит к широкому принятию сообществом практик, которые полностью противоречат сути ООП.
Краткая версия:
- Перестаньте получать / настраивать много, если вы это сделаете, независимо от языка. Это в первую очередь резко снижает выигрыш от внедрения ООП.
- Прототипы действительно просты, элегантны и мощны. Повозитесь с ними. Узнай их. Но будьте осторожны. Классы могут начать казаться архаичными, неуклюжими и перегруженными по сравнению (хотя, честно говоря, совершенно необходимо для неинтерпретируемых языков).
- Чтобы JS работал на вас, изучите дерьмо самостоятельно, с каким бы его аспектом вы ни столкнулись. Награды в виде чистой элегантной языковой силы более чем оправдывают потраченное время. JS ближе к Scheme, чем языки, которые вы перечислили, поскольку они знакомы, так что это странно, но это не странно произвольно или без учета принципов дизайна, и доминирующий успех JS в веб-интерфейсе не случаен, независимо от того, что люди говорят всем, что мы "застряли" с этим "вы бы поверили.
- Полное раскрытие: я не люблю Java.
Обновлять:
Ключевое слово es6 class практически ничего не меняет в ООП в JS. Это 100% синтаксический сахар. ИМО, использование слова «класс» не приносит новичкам никакой пользы, но есть преимущества / недостатки для всех трех стилей конструктора / создания объекта и создания экземпляра объекта в JS, и все они заслуживают того, чтобы их знать / понимать. Эти три подхода - это функции как конструкторы, Object.create, а теперь и ключевое слово class.
person
Erik Reppen
schedule
05.12.2012