All streams
Search
Write a publication
Pull to refresh
0
0
Send message
Я пробовал подебажить одну библиотеку собранную вебпаком. Скажу это то еще приключение. Когда модуль бывает состоит из одной строчки кода, а внутри вызывает другой модуль в итоге мы получаем незабываемое путешествие по измерениям. И там такой мэппинг, что Алисе даже и не снилось в ее стране чудес. А когда находим нужное место, от которого якобы что-то зависит, оказывается, что это не то место и путешествие начинается заново. Через час другой такой отладки, отпадает всякое желание работать с таким кодом.
И ситуация становится еще хуже. Теперь, вместо того, чтобы просто лазить по простыне if-elseов в одном месте, я буду лазить по 8-ми кускам кода, к которым отсылает новый god-component.
Честно говоря, мне кажется, что я уже использую SOLID подход, но мы как-то не то обсуждаем. Например chekbox() в checkMode или input() в inputMode это такие же компоненты, как и droplist(), он их использует внутри себя по своему усмотрению. И в этом есть смысл: повторное использование, дочерний элемент ничего не знает о родителе, ну и так далее. Но в статье это как-то на столько извращено и перековеркано, что рациональное зерно утеряно. Остались только радостные возгласы о том, как стало легче жить и светлое будущее не за горами.
«это некий «God Component»,» Прямо в точку. Это именно то, что и предполагалось сделать. Эдакое параметрическое программирование: вводишь конфигурацию — получаешь нужный компонент.
Повторюсь у меня нет проблем с отладкой, тестированием (тесты отсутствуют), развитием и поддержкой. Меня смущают макароны из if-else конструкций, которые выглядят не эстетично. Хотелось что-то более феншуйское.
Все принципы SOLID похожи на библейские заповеди, как хочешь так и трактуй. В итоге начинаются холивары, вроде, как надо: element.render() или render(element)?
То есть с появлением нового режима, мне нужно городить droplist2(opts)? Лишь бы не трогать старый? Какой-то оверкилл. И почему сейчас «Можно сделать droplist(opts)», а раньше (в статье) это было нельзя?
Но проблема то никуда не денется. Ну будет у нас вместо одного droplist(opts), восемь конфигураций типа droplistCheck(), droplistMS(), droplistInput() и так далее, всего 8 компонентов.
Пусть инпут будет droplist, multiSelect — множественный выбор с отображением выбранного свреху над дроплистом, checkMode — чекбокс напротив каждого пункта дроплиста, inputMode — в поле дроплиста можно вводить своей значение, а из пунктов находится наиболее подходящий. Пусть кейсов даже будет немного меньше. Все равно легче не становится.
Хорошо, вот пример моей проблемы:
Конструктор
Input({
 inputMode:true,
 checkMode:true,
 multiSelect:true
})

Внутренняя реализация:
function Input (opts) {
 if(inputMode){
  if(checkMode){
   if(multiSelect) {/*case 1*/}else{/*case 2*/}
  } else {
   if(multiSelect) {/*case 3*/}else{/*case 4*/}
  }
 } else {
  if(checkMode){
   if(multiSelect) {/*case 5*/}else{/*case 6*/}
  } else {
   if(multiSelect) {/*case 7*/}else{/*case 8*/}
  }
 }
}

Можно ли кадринально изменить этот код с помощью SOLID?
Может, я не так все понимаю. Начинает разработчик делать форму. Сначала у него что-то вроде
<container>
 <form>
  <inputs></inputs>
  <controls></controls>
 </form>
</container>
.
Дальше у него возникает необходимость убрать оверлей:

var formHTML =  '\
 <form>\
  <inputs></inputs>\
  <controls></controls>\
 </form>';
var  fullHTML = overlay ?
 '<container>' + formHTML + '</container>' :
 formHTML;

И так далее. То есть изначально у разработчика есть один большой блок, затем он дробится по мере разработки, когда возникает необходимость добавить новых фич. То есть влезание в код часто используемого компонента — это неизбежность. А как его иначе улучшить? Или как его разбить на меньшие компоненты?
Тем более ветвление никуда не девается. Ну было оно раньше внутри компонента, а стало межкомпонентное. И что мы выиграли?

На самом деле у меня действительно есть проблема, когда в форму вваливатеся куча параметров и их все нужно обработать, при чем каждый влияет на остальные особым образом. И от этого if-else ада я пока не нашел способа избавиться. Думал SOLID поможет, но он как-то не об этом.
Я использую пункт 3. Но тогда рушится вся концепция SOLID. Ведь форма начинает знать о свойствах и методах инпутов.
И раз уж в этом подходе «одна из самых сложных тем», где я проблемы даже не встретил, то я просто создал отдельный базовый класс Input, от которого отнаследовал остальные инпуты, откастомизировав их, а сама Form использовала их прототипные методы вроде getValue(), getHTML(), blink() и т.д. Хочешь добавить свой метод, например, onBlur(), не вопрос, передавай его в параметр инпута, типа new Form([{droplist:{onBlur: blurHandler}}], handler, opts). Я считаю в этом как раз наоборот вся красота и простота подхода, а не его недостаток. Да и собственно в статье эти недостатки описаны как-то пространно, вроде «это „попахивает“», «грозит появлением регрессий». Я даже не понимаю о чем речь. Как будто меня пугают привидениями.
Допустим. Но пока выгоды не вижу. Раз форма о них ничего не знает, что делать в ситуации, когда при сабмите инпуты проходят валидацию и надо мигнуть, если поле пустое.
Погодите меня штрафовать за нарушения. Я пока в целом не понял, чем я так провинился и чем ваш подход лучше. В итоге, так и не ясно от куда взялось this.state.showCloseButton. Кто и через что этот state туда засунул? В этом же ключевой момент. И для чистоты эксперимента давайте может чистый js и html использовать (не считая jquery). А то я может какой-то ключевой момент упускаю.
Так об обертках то и речь. Именно их Вы забраковали, а не внутреннюю реализацию. Моя внутренняя реализация выглядит практически так же.
var formHTML = showControls ? 
 '<form><controls></controls></form>' :
 '<form></form>' 
$('#form').html(formHTML);

То есть в моем случае я просто добавляю кейс на уровне if или switch. Вы же городите новый модуль. При чем он городится точно так же по мере возникновения необходимости, а не заранее, ведь изначально неизвестно нужно ли будет его скрывать или нет.
В итоге мы имеем:
function Form(inputs, handler, options){
 var inputsHTML = getInputsHTML(inputs);
 var formHTML = showControls ? 
  '<Form onSend={this.onSend)} isOpen={this.state.open}>
   <FormHeader>My form</FormHeader>
   <FormCloseButton onClick={this.onClose()} />
       {inputsHTML }
   <StandardFormButtonPanel />
  </Form>' :
  '<Form onSend={this.onSend)} isOpen={this.state.open}>
   <FormHeader>My form</FormHeader>
       {inputsHTML  }
   <StandardFormButtonPanel />
  </Form>'  
  $(body).html(formHTML);
}

new Form(inputs, handler, {showControls:false})
«Это описано в секции статьи „Как делать не надо“». Но я так сделал. накатал 3к строк кода и ничего, по необходимости навешиваю всё новые свойства, когда надо. Поэтому я и не понял, почему рабочий метод забраковался и вместо него предлагается некая сомнительная конструкция. Давайте просто сравним подходы в контексте приложения. Надо решить упомянутую проблему с кнопками.
До:
new Form(inputs, function(results){
 send(results);
});

После:
new Form(inputs, function(results){
 send(results);
}, {showControls: false});

Напишите свой пример До и После.
Например, понадобилось, чтобы форма была встраиваемая в основной контент. Просто в конструктор передаешь третьим параметром: {parent: selector}, то есть родительскую ноду, в которую надо встроить форму и затем рендеришь в нее, а не в popup. Как-то так. Если нужно убрать кнопки, оставив крестик добавляешь что-то типа {parent: selector, controls: false}. Если нужна какая-то особая кнопка то используешь инпут типа html — просто контейнер для гипертекста и в него вставляешь нужные кнопки, размещая их как надо при помощи стилей. Если нужна кастомная стилизация, то добавляешь {parent: selector, controls: false, class: 'myCustomClass'}, затем добавляешь этот класс к форме $form.addClass(class). Думаю смысл понятен.
Сам недавно писал такое окно на js. Пол года где-то писал. Реализовал все возможные инпуты и поведения формы. Как-то никаких проблем не заметил. есть конструктор Form, задаются параметры, где Form([массив инпутов], функция-обработчик, {объект — свойства формы}). Всё! Придумывай сколько угодно инпутов по единому базовому шаблону с неограниченной возможностью кастомизации параметров и вешай сколько угодно свойств и методов на саму форму. При чем вся моя философия повторного использования кода сводилась к следующему: видишь кусок кода повторяющийся больше двух раз — выноси в функцию. Я не пытаюсь что-то опровергнуть, но я не вижу большой пользы от всей этой конструкции под названием SOLID. По крайней мере статья этого не раскрывает.
2

Information

Rating
Does not participate
Registered
Activity