Re[7]: Присвоение свойств и вызов виртуального метода из кон
От: sharez  
Дата: 16.11.16 09:09
Оценка:
Здравствуйте, fddima, Вы писали:

F>Здравствуйте, sharez, Вы писали:


S>>В общем, всё это делается, да, но не кажется ли, что мы излишне усложнили архитектуру просто из-за надуманного ограничения на задание полей класса до вызова суперконструтора?

F> Не кажется.
F> Вне зависимости от возможности делать виртуальный вызов в конструкторе — контрол (кнопка) будет:
F> 1. Иметь состояние attached/detached (to DOM). Особенно в тех фреймворках кто может аттачится на уже существующий элемент и/или достраивать дом с плэйсхолдеров.
F> 2. Свойства на подобии title и color — они или бесполезные поля, или же имеют аксессоры и ими можно пользоваться как до так и после аттача с отражением изменений в DOM. Опционально — вычитка значений из DOM.
F> 3. События — аналогичны (2) — подписываемся/отписываемся в любое время, но в DOM они должны подписываться/отписываться железобетонно. Иначе ликать будет. (Хотя современные браузеры если ещё нет, то скоро и с этим справятся).
F> Я вообще не вижу зачем тут метод fill особенно в конструкторе.
F> Конструктор должен создавать объект в консистентном состоянии и только. Таким образом все параметры необходимые для конструкции объекта — необходимо передавать через параметры конструктора (парадокс?).
F> Для того что бы не вызывать тонну пропертей после конструкции объекта — можно соорудить ControlParams, ButtonParams или вообще безликий/динамический объект-холдер с настройками при инициализации. Заодно это могло бы упростить создание контрола фабрикой по уже готовому DOM с параметрами (или частью) которые лежат в атрибутах элемента.
F> Собственно нечто подобное я "изобретал" для себя, достаточно неплохо имхо организовано в google closure tools (library).

В таком случае все setTitle(), setColor() внутри помимо изменения DOM-дерева должны будут ещё и проверять, создано ли оно — тоже неплохое такое усложнение, особенно, если таких методов много (а их много).
Основная задумка была в том, что удобно создать this.el со всей внутренней структурой без аттача к DOM-дереву непосредственно документа, и добавлять его только при явном вызове, как-то так:

element.appendChild(button.getElement());


При этом нам ничего не помешает уже на этапе вызова конструктора задавать Title, Color в дереве, хранящемся во внутреннем поле this.el. Можно даже делать addEventListener/removeEventListener.

К сожалению, с Google Closure Tools я не знаком, но посмотрю на досуге.
Re[2]: Присвоение свойств и вызов виртуального метода из конструктора
От: sharez  
Дата: 16.11.16 09:23
Оценка:
Здравствуйте, ·, Вы писали:

Второй пример вышел слишком сложным (это он пока там кода нет кажется простым, но это оверинжинеринг на мой взгляд).
А вот первый имеет следующий недостаток: базовый класс AButton предполагается, что будет использован именно как базовый, и поставляться в виде SDK.
В нём уже заложен abstract getColor(), который помимо всего прочего може менять цвет (например в зависимости от проверки getParentToolbar() == null). Мы в базовом классе можем сделать constructor(color) только если уже знаем, что именно эта вещь нужна будущей реализации.
Можно вообще сделать в базовом классе передачу Map параметров, я уже об этом писал — это чуть лучше чем передавать лямбды, но тоже плохо: как минимум потому что всесто простого

this.prop = value;


мы вынуждены делать

super(new Map({"prop": "value"}));


Здесь в конструкторе будет использование Reflections (в случае Java, к примеру) со всемы вытекающими (опечатку/ошибку можно будет поймать только в run-time).

Можно ещё ввести конечно третий класс (уже третий!) ButtonParameters, но помимо того, что у нас уже и так три класса, мы добавим ещё около 50 строк (по одной на каждое свойство) в конструктор AButton (нужно же все эти значения присвоить). Соответственно введение нового изменяемого свойства потребует изменений в трёх местах, в трёх, Карл! Это вовсе не называется сокрытием реализации.
Re[3]: Присвоение свойств и вызов виртуального метода из констр
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 16.11.16 09:30
Оценка:
Здравствуйте, Carc, Вы писали:

C>Здравствуйте, netch80, Вы писали:


N>>Там, где можно вызвать конструктор в виде явного конструктора, можно вызвать и что-то вроде public static Button make(), которое само вызывает конструктор (возможно, объявленный private, чтобы не показывать незавершённое состояние), вызывает нужные методы и возвращает готовый результат. Такой себе конструктор, не выглядящий синтаксически как конструктор. (В родной библиотеке Java есть множество методов с неинтуитивным названием valueOf(), которые делают что-то похожее.) После этого специфика потрохов будет скрыта только внутри данного класса и его потомков, которые должны будут отразить специфику такого формирования у себя, но не у пользователей.

C>А по моему это называется Фабрика? Не?

Видимо, таки не:

In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created.


В том, что я описал, точно известно, объект какого класса будет создан.

Можно попробовать поспорить, но обычно бесполезно. Лучше попытаться подобрать похожее имя, но другое.
The God is real, unless declared integer.
Re[3]: Присвоение свойств и вызов виртуального метода из конструктора
От: · Великобритания  
Дата: 16.11.16 10:48
Оценка: +1
Здравствуйте, sharez, Вы писали:

S>Второй пример вышел слишком сложным (это он пока там кода нет кажется простым, но это оверинжинеринг на мой взгляд).

S>А вот первый имеет следующий недостаток: базовый класс AButton предполагается, что будет использован именно как базовый, и поставляться в виде SDK.
Тут противоречие. Судя по твоему описанию для конструирования AButton нужно знать цвет. Значит конструктор зависит от цвета, а значит его туда надо передать. А ты пытаешься огранизовать вычисление цвета в классах-потомках.

S>В нём уже заложен abstract getColor(), который помимо всего прочего може менять цвет (например в зависимости от проверки getParentToolbar() == null). Мы в базовом классе можем сделать constructor(color) только если уже знаем, что именно эта вещь нужна будущей реализации.

S>Можно вообще сделать в базовом классе передачу Map параметров, я уже об этом писал — это чуть лучше чем передавать лямбды, но тоже плохо: как минимум потому что всесто простого
Тебе нужно разорвать циклическую зависимость базового класса от класса потомка. Можно например убрать зависимость от цвета в базовом классе. А работу с цветом писать только в потомке:
class AButton {El getEl() {...}}
class ButtonWithColor : AButton
{
   public ButtonWithColor(color)
   {setColor(color);}

   public setColor(color)
   { getEl().addColorInfo(color);}
   
}

Циклическая зависимость ещё разрывается введением третьего класса, который инкапсулирует свойства, используемые обоими.

S>Здесь в конструкторе будет использование Reflections (в случае Java, к примеру) со всемы вытекающими (опечатку/ошибку можно будет поймать только в run-time).

Мапа очевидным образом заменяется на pojo-класс с геттерами/сеттерами, например.

S>Можно ещё ввести конечно третий класс (уже третий!) ButtonParameters, но помимо того, что у нас уже и так три класса, мы добавим ещё около 50 строк (по одной на каждое свойство) в конструктор AButton (нужно же все эти значения присвоить). Соответственно введение нового изменяемого свойства потребует изменений в трёх местах, в трёх, Карл! Это вовсе не называется сокрытием реализации.

Давай так. Начни с юнит-тестов. Накидай примерный код того, как ты хочешь использовать свои классы.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[8]: Присвоение свойств и вызов виртуального метода из кон
От: fddima  
Дата: 16.11.16 12:36
Оценка:
Здравствуйте, sharez, Вы писали:

S>В таком случае все setTitle(), setColor() внутри помимо изменения DOM-дерева должны будут ещё и проверять, создано ли оно — тоже неплохое такое усложнение, особенно, если таких методов много (а их много).

Сложность не такая уж и большая, и это скорее вопрос требований. Если хотим иметь такого рода свойства — в любом случае проверять. Можно конечно и не проверять и всегда менять/читать из DOM, но, имхо, возможность аттача выгоднее. (*)

S>Основная задумка была в том, что удобно создать this.el со всей внутренней структурой без аттача к DOM-дереву непосредственно документа, и добавлять его только при явном вызове, как-то так:

Не-не-не, связывание объекта и DOM элемента это уже и есть тот самый аттач. Только, с разницей что элемент строится безусловно самим контролом.

S>При этом нам ничего не помешает уже на этапе вызова конструктора задавать Title, Color в дереве, хранящемся во внутреннем поле this.el. Можно даже делать addEventListener/removeEventListener.

Помешает: как их задавать если условный createElement ещё не вызван? Возвращаемся к началу (*), и нам всё равно надо контроллировать создан он или нет в аксессорах. Если же речь о задании только значений по умолчанию в наследниках — то объект-шаблон/параметров поможет.
Опять же, установка новых значений по умолчанию в наследниках — имхо плохой вариант сам по себе: это местами может быть неожиданно (равно как и наоборот).
На самом деле куда интереснее, что делать если наследник хочет предоставить своё DOM tree, а базовый setTitle не виртуальный и пишет текст не туда.
А в финале — цепочка Control — Button сложна сама по себе. Я имею ввиду, что Control будет жутко перегружен в любом случае, а допиливаться будут все связанные классы сразу (и те которые не button тоже). Я делал себе Button и LinkButton, но LinkButton устанавливал только дефолтное базовое имя стиля (а точнее префикс). А вот в процессе пиляния такого фреймворка с 10-15 контролами — перетрушивал байду эту не раз, и в итоге пришел к тому, что напрямую я их в омновном все равно не создавал, а создавал на основе шаблона (dom tree), где спец элементы (скажем xcontrol) раскрывались в уже настоящий dom. А код уже обращался к ним по именам. Я к тому — что ну вот не вижу необходимости обсуждаемой возможности хоть убей. Или мы заранее знаем набор/значений свойств и свободно можем их передать в конструктор, или мы используем аксессоры после. Внутри конструктора аксессоры вполне могут быть использованы — ведь пока элемент не приатачен — ломаться нечему (разумеется, если свойства не виртуальные). Кроме того, не стоит и забывать, что DOM — это всегда интероп, поэтому подход: изменения только через контрол а не в DOM напрямую работает немножко лучше. (Ведь поверх этого надо ещё биндинг построить, так ведь?).

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

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

S>К сожалению, с Google Closure Tools я не знаком, но посмотрю на досуге.

Без фанатизма только, там много кода + длинная история. Примеры могут грузятся долго т.к. нескомпилированный js состоит из большого кол-ва модулей/файлов. Но они (модули) там хотя бы есть... а не профанация как в TS.
Я не со всем там согласен, но вдохновение в свое время почерпнул и не мало. Особенно система модулей и disposable (в дебаге) понравился. Кое что из идей перенес и себе.
Мне кажется это самый взрослый набор тулзов, но нетипизированность JS отталкивает, а его для их компилятора ещё и правильно писать надо. И реально нормальных редакторов нету, подпорки везде одни.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.