Как стать автором
Обновить
-2
0

Пользователь

Отправить сообщение

Ок, они уже ушли, полгода как, если не больше, где там всё это не работающее? Как человек с почти 25-летним опытом в индустрии, и как основной либо даже единственный автор некоего количества "костылей", которое продолжает работать у нескольких тысяч пользователей (в мед. учреждениях), правда не считаю себя senior, и увидев уход не одного десятка людей, отвечавших за создание и развитие/поддержку крупных подсистем в огромном монолите на протяжении этих 25 лет, у меня сложилось собственное мнение насчёт важности senior-ов в поддержании жизнеспособности и дальнейшем развитии крупных систем. Более того, буквально пару дней назад обсуждал некоторые вещи с человеком, про которого я первый раз услышал, который продолжает поддерживать и развивать в том числе и ПО написанное мной у заказчика, с которым мы перестали работать в конце 2000-х гг., ан нет, продолжало всё работать и без нашего участия эти 14 лет или около того.

Глядя на костыли, которые понатыканы сплошь и рядом во всех крупных проектах, задаёшься вопросом, а точно ли будет хуже без "сеньёров", которые, очевидно, имеют прямое отношению к их появлению в проектах.

Абсолютно не реалистичная затея. Даже не говоря о том, что экономически они не в состоянии конкурировать с основными мощностями TSCM, но вдобавок к этому TSMC несколько лет назад признавалось, что работает с порядка 20 тысячами компаний, которые им поставляют компоненты, используемые в производстве, оказывают различные услуги (включая транспорт) и т.п. Точный список они, естественно, не давали, но можно предположить, что подавляющее количество этих компаний из материкового Китая. Плюс в мире нет большого количества свободных инженеров, а образование в самим штатах из-за повесточки деградировало не год и не два назад, Китай переманил на материк значительное количество опытного народу, имеющего опыт в этой сфере.

Построить здания и завезти и настроить там оборудование это от силы пара процентов того, что нужно сделать, чтобы начать реальное серийное производство, но даже если чисто гипотетически представить, что они таки справятся и найдут себе всех поставщиков, начнут производить очистку редкоземельных металлов на своей территории, к примеру, вместо тотальной зависимости от Китая, найдут достаточно опытных инженеров на эти заводы, но экономически они всё равно не способны выйти на прибыль в обозримом будущем, если только они не убьют уже существующие мощности TSMC, Samsung и прочих в других странах, и не нагнут свои собственные компании и Европу на то, чтобы они ни в коем случае не покупали процессоры и память у Китая. Современные США способны только в услуги, а не в сложное производство.

Вы можете использовать березовые ветки и листья для создания стен

Когда на улице -20 и снега по колено, на берёзах прямо полно листьев.

В общем, этот "ИИ" и здравый смысл понятия совершенно не совместимые. Интеллекта ноль.

Лично моё понимание такое - платежи по новой схеме ещё по сути не начались, так как пока ещё качают газ в счёт предыдущей оплаты, сделанной ещё до введения новой схемы, в середине или конце апреля подойдёт время новой оплаты, тогда и посмотрим.

И суть не в том, сколько именно валюты будет Газпром продавать на внутреннем рынке, 80% или 100%, и даже не в обменном курсе, а в том, что он будет продавать эту валюту Российским компаниям на Московской бирже. Компания предлагает, мы готовы купить у Газпрома 100 миллионов долларов в обмен на рубли. Вот наш счёт открытый в долларах, причём не важно, открыт ли этот счёт в Российском банке (у которого, соответственно, корреспондентский счёт в Американском банке), либо напрямую долларовый счёт в зарубежном банке, переводите доллары на него, а после того, как мы убедимся, что доллары поступили, тогда мы переведём нужную сумму со своего рублёвого счёта на рублёвый счёт Европейской компании в Газпромбанке.

Европейская компания не может перевести свои доллары на указанный покупателем долларов долларовый счёт, так как это будет нарушением санкций (из-за чего её США накажут так, что можно сразу объявлять себя банкротом), либо даже если попытается это сделать, то уже Американский банк скажет, что этот Российский банк под санкциями, мы не будем переводить ваши деньги на их счёт.

Перевода денег с долларового счёта Европейского покупателя газа не происходит, значит сделка по обмену долларов на рубли не происходит, а значит нет рублей - нет газа.

palesz.wordpress.com/2011/12/03/howto-maven-lombok-and-aspectj-together
1. javac compiles your .java files to .class files with lombok (generating methods, etc.)
2. aspectj regenerates your classes from the .java files without lombok
Но, к сожалению, предложенный по ссылке вариант у меня не сработал. И не только у меня, насколько можно понять из issue того же lombok — github.com/rzwitserloot/lombok/issues/995
Беда начинается, когда требуется в одном проекте использовать и Lombok и AspectJ, они не очень дружат.
LinkedList может быть полезен в качестве источника «сырых» данных (например, запроса из таблицы, который заранее условиями WHERE разбивать на части не удобно или не эффективно), которые приходится в цикле обрабатывать несколько раз, разделяя данные на части по какому-то условию. При каждом проходе из списка удаляются записи, соответствующими критерию из данного цикла, так что в следующем цикле приходится обходить гораздо меньше записей (null оставляет количество записей первоначальным, создание новой копии списка на каждом проходе снижает эффективность).
Перечитал оригинал, мы оба не правы. Там совсем про другое написано, условно про три уровня:

class MyApp {
void doSomething(A a) {
a.someMethod();
}
}

interface A {
someMethod();
}

class AImpl implements A {
someMethod() {}
}

На том, как именно будет создан объект 'a', который будет передан в метод doSomething класса MyApp, в статье внимание не заостряется.
1) Нигде в оригинале не говорится о размере или количестве методов. Если у класса есть 10000 свойств (полей) и getter-ы/setter-ы либо вычисления для всех этих 10000 свойств, и больше никаких других методов (скажем, вывод этих свойств в файл или показ на экране), то принцип SR не нарушен.

2) Добавление новых методов не нарушает OC. В оригинале, помимо прочего, говорится:
«It should be clear that no significant program can be 100% closed.… Since closure cannot be complete, it must be strategic. That is, the designer must choose the kinds of changes against which to close his design.»
В статье про L упоминается «The primary mechanisms behind the Open-Closed principle are abstraction and polymorphism», в случае если у меня класс implements SomeInterface, добавление в него новых методов или изменение старых методов, которые не перечислены в SomeInterface, не нарушает OC.

Рефакторинг существующего кода — возможно является нарушением де-юре, однако если этот рефакторинг никоим образом не меняет логику/поведение (на чём я заострил внимание), то де-факто он не привносит проблем, с которыми борется OC («When a single change to a program results in a cascade of changes to dependent modules»).

3) Оригинал: «What is wanted here is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all
programs P defined in terms of T, the behavior of P is unchanged when o1 is
substituted for o2 then S is a subtype of T.»
Если логика/поведение одних и тех же методов в двух классах будет разной, это изменит поведение программы, а значит нарушит L.

4) Соответствие одновременно нескольким интерфейсам — допустимая вещь для Interface Segregation, главное, чтобы эти интерфейсы «правильно» группировали методы по логике/применению. Признаю, я неточно выразился, не упомянув интерфейсы (или «abstract base classes» как в оригинале).

Как раз class A implements Foo, Bar, Baz {} это будет нормальный IS, при условии, что части программы, которые используют класс A об этом не знают (DI), а обращаются к нему как к реализации либо интерфейса Foo, либо интерфейса Bar, либо интерфейса Baz.

5) Ну, пускай это несколько разные вещи. Как я написал в одном из ответов: «Как именно сделано DI это менее важная вещь, чем то, что в поле или в параметр у нас могут попадать interface либо «родительский» class, у которого могут быть несколько «детей», имеющих «докрученную», более специализированную логику. „
DI-контейнер это типичный подход к реализации принципа, однако нигде не говорится, что injection реализуется исключительно DI-контейнером. Любой внешний код, создающий экземпляр объекта и передающий его в другой объект (через конструктор, setter или присваиванием значения полю) является injector-ом, то есть реализует dependency injection.
Весь вопрос — насколько часто понадобятся эти сложности и понадобятся ли вообще. Обычно программистам советуют придерживаться принципа YAGNI
Разделение программного interface на части это нечто совсем иное, чем декомпозиция визуального интерфейса на компоненты.

Как именно сделано DI это менее важная вещь, чем то, что в поле или в параметр у нас могут попадать interface либо «родительский» class, у которого могут быть несколько «детей», имеющих «докрученную», более специализированную логику. Возвращаясь к примеру, у меня будет тип ModalDialogWindow с методом show(), а уж какое конкретное окно будет создано, InputField или TreeDirectory это будет разрулено в runtime контейнером DI.

Я не могу сказать, насколько DI важно или реализуемо в front-end разработке, так как больше специализируюсь на back-end и БД. Всё, что я хотел сказать — то, что описано в статье — не содержит DI.
Сложно объяснить это на примере javascript. Условно, в Java у меня вместо относительно (пример искусственный, на самом деле методов может быть не 4, а, скажем, 100) переусложнённого варианта

interface ModalDialogWindow {
void setupInputFieldVersion();
void showInputFieldVersion();
void setupTreeDirectoryVersion();
void showTreeDirectoryVersion();
}

был бы
interface ModalDialogWindow {
void show();
}
interface InputFieldModalDialogWindow extends ModalDialogWindow {
void setupInputField();
void show();
}
interface TreeDirectoryModalDialogWindow extends ModalDialogWindow {
void setupTreeDirectory();
void show();
}
то есть я разделил бы общий случай на более специализированные.

Про DI также сложно объяснять пишущим на javascript. На Java у меня будет, допустим,

interface A {}
class B implements A {}
class C implements A {}

В коде у меня будет заведено поле типа A (экземпляр interface или abstract class создать невозможно, можно создавать только экземпляры не-абстрактных class-ов), и мне кто-то (DI-контейнер) подставит в это поле экземпляр либо типа B либо типа C, он сам по какой-то (известной, не случайной) логике решит, какой именно, B или C подставлять, не я в коде прямо впишу создание экземпляра конкретного класса

A a = new B();

или по какому-то условию буду создавать экземпляр

A a;
if(someVar == 'B') { a = new B(); }
else if(someVar == 'C') {a = new C(); }

а DI-контейнер за меня это сделает.
Затем я, допустим, добавлю

class D implements A {}

мне ну нужно будет переписывать код, добавляя в него ещё одно условие

else if(someVar == 'D') { a = new D(); }

а неким иным способом смогу присваивать переменной 'a' экземпляр типа 'D', без изменения кода.
Прошу прощения, <ModalDialogContent>Some content</ModalDialogContent> заменилось на просто Some content.
Изменение вёрстки — это изменение поведения, я изначально сказал, что рефакторинг его не должен менять.

Слишком общее решение может быть не удобно для использования и может увеличивать количество ошибок. Легче один раз написать и отладить helper (в общепринятой терминологии facade), чем помнить как, с какими параметрами и в какой последовательности нужно выполнить 5-10 простых, казалось бы, операций. То есть супер-гибкий метод может быть доступен, но, скорее всего, в 90% случаев будет достаточно пяти вариантов диалогового окна, и лучше иметь эти 5 вариантов в виде пяти простых и отлаженных методов.

Я не стал бы переводить interface segregation как разделение интерфейса, это скорее изоляция вариантов использования интерфейса, разделение его на несколько частей с более узкой специализацией. Условно, вот есть у Вас это гибко-настраиваемое диалоговое окно. И есть в приложении 10 вызовов этого окна, где нужен лишь заголовок, input-поле и кнопка «ок». А также один единственный вызов этого диалогового окна, где, допустим, будет заголовок, под ним строка для поиска с кнопкой «искать», внизу слева древовидный справочник для выбора значения, справа при click-е на значении в дереве будет показываться какой-то текст, и внизу кнопка «ок». Принцип interface segregation советует разделить эти два варианта на разные классы/компоненты, так как по отдельности ими будет легче пользоваться.

Дело не в «из каких компонентов он собирает окно», а в том, что DI-код сборки, условно, встретив Some content, может динамически (то есть в runtime) выбрать один из нескольких вариантов отрисовки этого компонента, причём он сам решает исходя из каких-то параметров или контекста, какой именно вариант выбрать. А может быть и только один вариант такого компонента, или вообще не одного, мало ли при сборке проекта что-то потерялось.
Я повторюсь, что single responsibility несёт в себе несколько иной смысл, чем просто размер компонента. Пусть у нас будет даже маленький компонент, даже крохотный, у которого будет только одно свойство, допустим строка value, и пара методов — get/set. То, как оно будет визуализироваться в html — это уже должен быть другой компонент. Нельзя будет добавить в первый компонент метод showAsHtml, не нарушив при этом принцип S.

Принцип open/closed, условно, пусть у меня будет в коде цикл for(i=0; i <= myArray.length — 1; i++), почему я не могу поменять его на for(i=0; i < myArray.length; i++)? Что это нарушит в логике/поведении программы? Ничего. Если быть осторожным (и правильно покрыть код unit-тестами), то рефакторинг вполне допустим и не нарушает принцип O.

Принципы L и D я в предложенном решении не вижу.

Принцип interface segregation, возможно, соблюдён для мелких «деталек LEGO», но в самом решении конструирования диалогового окна из кубиков принцип I вообще не соблюдается. Это несоблюдение, само по себе. не хорошо и не плохо, даже самые полезные принципы и паттерны могут не подходить для решения каких-то конкретных, специфичных проблем, и в этом нет ничего зазорного.

Как я уже писал выше, конструирование диалогового окна из деталек я бы вынес в отдельный factory-класс, в котором был бы набор facade-методов вроде dialogWithTextAndOkButton(text, okButtonCallback), dialogWithTextAndOkButtonAndXClose(text, okButtonCallback, closeCallback) или что-то подобное.
Если из SOLID выбросить 2 или 3 принципа (за «ненужностью» или из-за того, что в языке javascript чего-то нет), это будет уже не SOLID. Зачем тогда вообще упоминать эти 5 принципов?

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

S — компоненты (классы) не обязательно должны быть маленькими и простыми, но должны иметь узкую специализацию. Условно, если есть класс «персона» (или как правильнее перевести то, что в английском вкладывается в слово person), у него может быть хоть 10000 методов и миллион строк кода, но если они связаны исключительно со свойствами абстрактной персоны, то принцип single responsibility де-юре не нарушается.

O — позволяет делать рефакторинг старых методов, если это никак не влияет на логику, то есть никоим образом не нарушает совместимость ранее написанного кода, вызывающего эти методы. При этом могут добавляться новые методы с новой логикой, но как только где-то в другом компоненте/классе появился его вызов, всё, снова логику поведения менять нельзя, если хочешь что-то поменять в логике, добавляй ещё один новый метод.

L — компонент может быть заменён не просто на другой, а на такой, который реализует те же самые методы с той же самой логикой/поведением (но помимо этого может реализовывать ещё какие-то новые методы, которых не было в старом компоненте).

I — если компонент может, в зависимости от входных параметров, быть слишком разным (будь то внешний вид или поведение), то предпочтительнее выделить эти «разные» версии в виде отдельных классов, с более мелкими компонентами легче работать, чем помнить все варианты зависимости поведения «жирного» компонента от входных параметров.

D — не являюсь специалистом по javascript и front-end-у, но dependency injection в javascript якобы возможно, например, об этом писалось в habrahabr.ru/post/232851
Эта статья во многом вдохновлена докладом Павла Силина на РИТ 2017

Бегло глянув на доклад, часть претензий по непониманию принципов SOLID и вообще ООП можно предъявить его автору. Основной посыл докладчика — в javascript интерфейсов нет, наследование есть, однако использовать его он не рекомендует (дословно цитируя — «моя практика показала, что использование наследования в React-компонентах это приводит к больше проблемам, чем к каким-то профитам»), но про SOLID он читал, и поэтому будет пытаться как-то связать прочитанное с темой доклада. Ведущий front-end разработчик…
1

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность