После 4K телевизора мне стали не понятны все эти танцы с мониторами. То "очень широкие для геймеров", то "очень высокие для дизайнеров", то 10 битные, то очень яркие. И радуются всегда, что нет рамок. Открою секрет - у телевизора рамок нет. Размещаете две программы 1920x1080 друг над другом, и ещё остаётся по половине места слева и справа для всяких виджетов, дебагеров или блокнотов. У телика матрица отличная, и нет лага (на LG для этого нужно включить режим компьютера у hdmi-входа, и убрать всякие улучшалки в настройках). Полноценный 4K 60fps 10bit IPS HDR, размером с целый стол. Только для дизайнеров может не зайти - всякие фотошопы или планшетные дрова вроде бы не умеют ограничивать прямоугольник движений курсора, и выходит огромный ход. Но свобода не сравнится двойными, широкими или высокими мониторами. И фильмы можно "бесшовно" смотреть - не нужно ничего для этого делать, только развернуть на весь экран. А майкрософтовская программа PowerToys умеет делить экран на любые области, куда удобно примагничиваются окна в нужных размерах.
Методы по умолчанию должны быть у предка, а не у интерфейса. Например у предка, реализующего интерфейс. Но C# не поддерживает множественное наследование, что для игр недостаток, так как например ружьё со штыком - это одновременно и ружьё и штык. Одной оси наследования мало, а агрегирование спасает не полностью, оно менее удобно чем наследование и заставляет делать прокси-свойства. В c++ множественное наследование есть. Почему в C# его не сделали, а теперь возвращают в интерфейсах и делают из них класс, не понятно. Ну что есть то есть, вы от этого довольны, а я бурчу вот, у меня идеалы другие - множественное наследование и интерфейсы-не-классы.
Обобщённое программирование рассматривается как методология программирования, основанная на разделении структур данных и алгоритмов через использование абстрактных описаний требований[3]. Абстрактные описания требований являются расширением понятия абстрактного типа данных. Вместо описания отдельного типа в обобщённом программировании применяется описание семейства типов, имеющих общий интерфейс и семантическое поведение (англ.semantic behavior). Набор требований, описывающий интерфейс и семантическое поведение, называется концепцией (англ.concept). Таким образом, написанный в обобщённом стиле алгоритм может применяться для любых типов, удовлетворяющих его своими концепциями. Такая возможность называется полиморфизмом.
Дженерики как частный случай там есть, но ими не ограничивается. Вот например в той же статье на английском (в русском вырезано):
Similarly, dynamically typed languages, especially interpreted ones, usually offer genericity by default as both passing values to functions and value assignment are type-indifferent
Тут говорится про то, что например JS имеет "обобщённость" просто потому, что не проверяет типы.
Полиморфизм - это концепция из ООП.
Ну если вы имеете в виду изначально только ООП, тогда да. А так вот из Википедии опять:
Интерфейс создан для сокрытия реализации. Уменьшает связность модулей. И в какой-то степени является заменой множественного наследования.
Для сокрытия создано сокрытие (private). Интерфейс нужен для обобщённого программирования. Поясню ещё раз. Я например ожидаю, что аргумент функции будет иметь метод work. Мне без разницы на наследование, на то открыта реализация или нет, есть дженерики в языке или нет, мне нужен только метод work. Почему это обобщённое программирование? Потому что я написал код функции один раз, никогда его не меняю, а он работает с разными типами входящих данных. Почему это полиморфизм? Потому что разные объекты подходят в одно место использования.
В чем накладность интерфейса?
В том что его нужно писать. Если у вас функция только вызывает метод work у объекта, то вы пишете параметр типа IWorkable . Тогда таких интерфейсов очень много. Вот я и говорю, если не нужно обобщённое программирование, то есть если метод и так всегда работает с одним классом или с одним предком, а не с любыми объектами, то интерфейс тут не нужен, а нужен класс-предок. Это экономит силы программиста.
Нужно 10 раз подумать, прежде чем вносить изменения в контракт.
Мы говорим о разных граничных случаях, чтобы доказать точку зрения. Вот статья для мидлов на юнити. Мне кажется, что там и будет монолит :) . Но будут бояться менять интерфейсы, просто потому что так написано в интернете. И будут городить многоэтажные дополнения-потомки или новые интерфейсы вместо правки существующего кода.
Также const в интерфейсе не может быть
Ну насчёт этого я перегнул. Смысл моего выпада был в том, что интерфейс это контракт. А его используют уже как склад всего подряд. Отсюда новичёк подумает, что private в интерфейсе - это так и надо. Только потом узнает, что это совсем не тот private (не контракт). Хотя в нынешние времена, насколько я понял, новичок даже не задумается, потому что для него интерфейс - это просто штука из конкретного языка, а не воплощение контракта.
Подумал подумал, минус заслуженный :) погорячился.
в грамотном подходе к архитектуре проекта для большой команды, в начале создаются интерфейсы
Из моего опыта так не работает. Потому что не возможно всё учесть на этапе планирования. Интерфейсы будут создаваться по ходу разработки, потому что не возможно распланировать проект настолько глубоко и подробно. А дальше будет тупик - запретили себе изменять интерфейсы, и можете реализовывать только то, что запланировали в самом начале. Если же вы говорите не про самое начало, а просто про какой-то очередной этап разработки, то вопросов нет, интерфейсы тогда могут помочь.
Это один из принципов солида - "не изменяй то, что уже работает - добавляй новое"
Этот принцип не работает в полной мере. Если только наращивать и никогда не править, то такой код очень быстро станет перегруженным и не понятным. Просто в каждом месте придётся пробираться через нагромождения. Сегодня рады что не трогали код соседа, а завтра вместе с соседом придётся рефакторить нагромождения.
Начиная с C# 8.0, член интерфейса может объявлять тело
Я теперь понял ваш посыл - перечислить в картинке всё что может C#. Да, в нём захотели использовать интерфейс как склад, как неймспейс или класс. Я придрался потому, что это всё - противоположность назначения интерфейсов. Если я вижу private или static в интерфейсе, то прежде всего думаю, что автор кода не понимает зачем нужны интерфейсы, или что он столкнулся с какими-то проблемами и ему пришлось это написать. Интерфейс нужен по месту требования, например для параметра функции. Нельзя требовать на входе функции чтобы входящий объект имел приватное поле или чтобы его класс имел статичный метод.
Товарищи, вижу минус, поясните что не понравилось, чтобы я хотя-бы понимал, нужно такие полотна впредь писать или нет. Может вам не понравилось "много буков", или вы и вправду уверовали в те статьи, где интерфейсы для большой команды, или любите private в интерфейсах, или что-то ещё не так? Кнопки удаления нет, так хоть узнаю может.
Думаю неверно расставлены акценты, объясню по-своему, может будет полезно.
Инкапсуляция: Имеет много определений - в широких смыслах и в узких. ООП начинается, когда объединили данные с методами их обработки. Уже это можно называть инкапсуляцией. Как следствие данного объединения появляется возможность скрыть данные и методы. Потому что лежащие независимо данные и методы не могут быть скрыты, иначе их нельзя будет использовать. Разве что могут быть помещены друг в друга или использовать какие-то правила именования для имитации сокрытия.
Сокрытие: У вас C#, но в целом может достигаться и без модификаторов типа private. Например это могут быть подчёркивания __такие, или локальный скоуп, откуда переменные не выходят наружу. Например в JS модификатора private до сих пор нет, но сокрытие всегда в нём было и будет. Сейчас для этого выдумали решётку #такую.
Наследование: Для переиспользования кода при ООП. Переиспользование может достигаться и без наследования, например через вызов обычной внешней функции, или через делегирование, или через "воровство" методов других объектов с подменой this, и много ещё как. Наследник может не иметь доступа к родительским данным и методам. Переиспользование тогда выходит только в вызове конструктора предка или в прочих неявных механизмах языка. Наследуются экземпляры, а не классы. Классы остаются отдельными, в частности статичные поля у каждого класса свои. Наследник не "берёт у родителя", а является родителем. "Берёт" при делегировании.
Полиморфизм: Для обобщённого программирования, то есть чтобы один код работал с разными типами данных. Достигается как угодно, лишь бы один код работал с разными типами данных. В языках со слабой динамической типизацией полиморфно всё, потому что переменные и функции не знают, какой тип в них попадёт. Так происходит в JS например, где различные объекты подходят в одни и те же места просто потому, что нет проверки типов. В языках со строгой статической типизацией есть специальные механизмы для обобщённого программирования, например интерфейсы или пропуск потомка там, где требуется предок, то есть полиморфизм потомков.
Интерфейсы: Для обобщённого программирования (полиморфизма) в языках со статической типизацией. Чтобы можно было засунуть различные объекты, не имеющие одинакового предка, в одно место использования. Например если требуется где-то объект с методом work, тогда делаем интерфейс с таким методом. И тогда без разницы какой будет класс.
Интерфейсы не являются фундаментальными кирпичами архитектуры проекта, как вы пишете. И они создаются не в начале проекта, а когда потребовались. Не для удобства обращения к объектам и не для большой команды, а для обобщённого программирования. Если такового нет или не требуется - не нужно делать интерфейсы. Также зачастую можно обойтись классами, так как создавать интерфейс под каждое место использования может быть накладно.
То, что интерфейсы нельзя изменять, - не правда. Никакой негативной практики, как вы пишете, в этом нет. Это абсолютно обычное дело. В IDE даже есть рефакторинг интерфейсов - во всём проекте всё синхронно меняется и ничего не ломается. Также компилятор проверяет все места использования интерфейса и все ошибки после изменений легко найти. Смена методов интерфейса и смена методов предка никак не отличаются по негативности. Но бывает мнение, что код можно только наращивать, но никогда не менять, в таком случае можно со мной не согласиться.
В вашем примере IMovable есть поля private, protected и static в интерфейсе. На мой взгляд это глупость, потому что интерфейс может быть только публичным, иначе не имеет смысла. И служит для экземпляров, а не для классов, поэтому static там быть не может. Также const в интерфейсе не может быть, потому что константы не принадлежат экземплярам, и интерфейс не может требовать константу от экземпляра. Разве что это какие-то заморочки конкретного языка, например в C# у интерфейсов есть реализация, что противоречит даже вашим словам "отделить описание от реализации".
Возможно я не тот аспект затрагиваю или под другим акцентом.
Я имел в виду не только правки от клиента, но и "первичную" сдачу работы. Текст "обучение персонала" на кнопке карточки вряд ли был оговорен заранее. То есть получили вёрстку или дизайн, проверяете, а там два слова не влезло. Вот такие моменты возникают потом.
Опытные исполнители подстилают себе солому без раздумий, это скорее чутьё и по-умолчанию-резиновый подход. Но не идеально, и далеко не везде. Что не влезло и отвалилось - доделывается спокойно потом.
Есть начинающие верстальщики и дизайнеры, которые всё прибивают гвоздями, им такие статьи полезны. А есть опытные, которые просто не делают всё заранее, потому что это долго и не всегда оказывается востребовано при реальном использовании.
Думаю, что веб-дизайнеров должны учить верстальщики, после их дизайнерского образования или сразу. А верстальщиков - программисты. Поначалу там не то что одна статья, им месяцами нужно показывать кучу таких вещей.
Ошибки и недопонимание здесь возникают из-за того, что в будущее смотреть никто не умеет.
Мнение "работа сдельная, я уже всё отдал, меня уже не касается" позволяет расслабиться после сдачи работы, выпить пивка, или знать что можешь взять следующую работу.
Я бы вместо этого посоветовал нормально относиться к последующей доработке, с обоих сторон. То есть убрать фактор "неизвестного будущего" - причину проблем.
Когда делаешь весь проект самостоятельно, то становится очевидно, что всё меняется на всех этапах, и всегда по-разному, поперёк и наискось. Никакие списки требований и подсказок не помогут.
смысл у нее появится только в зависимости от того как мы ее будем использовать, то есть откуда будем на нее ссылаться
Не обязательно. У целого числа 2 может быть потомок Width. Тогда он будет отличаться от Height. В любых объектах, которые их используют. Это можно делать наследованием или каким-нибудь брендированием для передачи смысла "2 как ширина". А у Color может быть наследник SkyColor или color.type = sky. То есть цвет не имеет смысла, и используется там, где смысл не важен, а цвет неба используется там, где важно его отличать от цвета кожи.
Сделайте обобщённый класс Sense<T,S>, и сможете для полей писать смысл, и он будет единый для всего проекта. Например поле "ширина_кабины" : Sense<int,кабины> = 5.
В области ИИ я ничего не понимаю, и наверное вы придумали что-то полезное, но замечу:
Два, одинаково называемых поля в разных объектах это два совершенно разных системных объекта
может быть один экземпляр свойства между многими объектами
... и не имеющих ничего общего с точки зрения системы
у них один тип или класс или интерфейс или структура или экземпляр
Человек воспринимает свойство самостоятельной сущностью и говоря, например, о цвете машины и о цвете волос, мы понимаем, что речь идет об одном свойстве – цвете
да, это тип
Следовательно, для реализации алгоритмов, моделирующих мыслительные процессы человека, свойство и объект должны быть представлены в виде самостоятельных и равноправных структур
они так и представлены, как объект и как тип свойства
Так как описание объекта максимально абстрактно («Нечто»), а новые свойства легко определяются и добавляются, то функциональность может быть расширена без необходимости внесения изменений в уже реализованные действия
Это объект JS или словарь. А потом понадобится ответить на вопрос "как работать с этим объектом, когда я забыл где и что добавлял, и есть ли оно в данный момент", и вы изобретёте контракт и класс. JS -> TS. А функциональность при наследовании и так расширяется без изменений, или меняется где это нужно через override. Или допустим на строго типизированном языке можно сделать класс, у которого все свойства и методы будут в словаре, и вызывать методы Get Set Call, что и происходит в JS. Только это будет в одном случае, а всё остальное строго. И будет это дженерик, у которого для свойств указывается один и тот же тип, или any/object для любого типа. И через этот тип свойства в разных объектах связаны по смыслу. А когда нужно связать их ещё и по поведению в рантайме, то они просто станут ссылками на объект свойства где-нибудь в куче.
В условиях острого недостатка новых идей
Сильно сказано. Может они просто не проходят отбор.
В частности, на многие десятилетия считающееся само собой разумеющимся представление о том, что объект первичен, а свойство привязано к объекту.
Потому что по определению, объект - это данные и методы их обработки. Если данные сами по себе - то никакого объекта нет. Там где данные не привязаны к объекту, есть например функциональное или процедурное программирование. И у вас о свойствах представление как о примитивах типа целого числа, но они могут быть объектами, их смысловая связь прямо прописана в виде класса.
Можно во всех ситуациях использовать div, кроме тех, где очевидно ломается что-то, или иногда ломается. Например, если у вас админка, в которой слепой человек не сможет работать, даже если всё будет доступным, то делать такую админку доступной - не имеет смысла. Или если в любом случае всё будет делаться мышкой, то перемещение табом можно вообще выкинуть. Если вы на таком проекте работаете, то доступностью вы просто потратите время и деньги, и будете зря что-то доказывать коллегам. Просто подумайте в каждом случае что вам нужно, а что нет, а не слушайте советы идеального мира.
Если бы была возможно писать теги вообще без указания их тег-имени, было бы ещё лучше. Потому что это был бы контейнер. А прочие особенности и назначения можно задавать в атрибутах. Плюс в том, что это опционально, и дробится на сколько угодно нюансов. Так когда-то поступили со style, так же можно поступить и с именем тега. Сейчас теги имеют как минимум 3 назначения, то есть являются контейнером, семантикой и имеют разный принцип работы. А как же разделение ответственности? Свалили всё в одну кучу, поэтому приходится писать статьи, чтобы как-то договориться как с этой кучей работать.
Основная идея информационных батарей (IB) проста: когда возобновляемая энергия доступна в избытке, она используется для спекулятивных вычислений в больших энергоёмких центрах обработки данных. По данным Управления по энергоэффективности и возобновляемым источникам энергии, эти центры обработки данных — от Google и Facebook до студий рендеринга голливудских фильмов
Не слабо так, спекулятивно отрендерить голливудский фильм. Просыпается потом монтажер, доделывает кадры, а рендер в помойку.
Полностью векторный GUI, то есть идеальное качество изображения на дисплеях высокого разрешения. Продвинутый векторный рендеринг с поддержкой анимации.
Векторный GUI - это преимущество?
Преимущество векторной графики - масштабирование. Ресайзим однопиксельную рамку в полтора раза, и она мутная или округляется в какую-то некрасивую сторону.
Отрисовка пиксельного квадрата везде векторное, не из картинки его берут. Браузеры могут рисовать SVG и анимации, CSS сплошь и рядом векторный. Шрифты давно векторные. Получается все ОС, особенно браузерные, - векторные. Ну у окон не торчат векторные вензеля и короны, и слава богу.
У векторных иконок нет хинтинга, их детали не попадают в пиксели. А на винде иконки "в исходнике" большие - аналог векторных, при даунскейле. А маки имеют высокий ppi, что нивелирует отсутствие хинтинга или мутность иконок. И проблем нет, всё хорошо на "дисплеях высокого разрешения".
Вы правы, действительно есть относительно дешёвые. У меня мнение на основе моих предпочтений просто оказалось, по которым самое минимальное 500$ выходит.
Не понятно кто кого обвиняет в заголовке. Мне вот всё равно на чём кому-то нравится смотреть. Я только знаю, что впечатления и погружение от телика будут не сравнимы с мобильником. И в большинстве люди не смотрят на телике просто потому, что телика нет, ибо он дорогой, и не является первостепенной вещью для многих. Телик просто купил и смотришь, ничего там сложного нет. А уже если не нравится чёрный или настройки, то это уже второстепенная задача. И мне например ни в каких ОС на телеках не хватает настроек, они либо какие-то примитивные, либо наоборот излишние. И все настройки расположены не в тех местах, марсианская логика как-будто, но это на мой взгляд. Думаю что у производителей нет обратной связи с пользователями, или они их просто игнорируют.
Так же, алгоритмы обфускации активно используются не только для затруднения анализа кода, но и для уменьшения размера программного кода, что, в свою очередь, активно используется при разработке различных веб-сервисов и баз данных.
Если вы определяете обфускацию как запутывание и затруднение понимания, то в таком случае она не используется для уменьшения размера кода. Размер уменьшается различными приёмами, и код потом уже может выглядеть как обфусцированный, но может при этом оставаться понятным.
Если насчёт веба имелся в виду фронтенд, то скажу что нет смысла обфусцировать JavaScript. Потому что самому же будет сложнее разрабатывать, а злой дядя всегда может легко превратить код в нормальный или понять без превращений, особенно когда ему заплатили хорошо.
Жилеты там по паре штук этих квадратов содержат и греют точечно только почки и верх спины, иногда ещё шею. Когда в некоторых местах жарко, а в других холодно, контраст не приятный. Так что в жилеты с али нужно ещё самому дошивать хотябы один набор квадратов (штуки 4 от ещё одного входа USB), и носить с павербанком, который поддерживает полную мощность двух портов.
Наберите на али «USB Electric Heating Pad», появится много чёрных квадратов, работающих от USB. Те связки, где слишком много штук от одного входа, брать не нужно, мощность низкая будет. Ну и лучше несколько разных заказать, чтобы проверить какие лучше по теплоотдаче. И потом уже вшивать в куртку. Насчёт нагревающего кабеля ничего сказать не могу. Но там в квадратах этих — что-то вроде нагревающейся нитки, всего пара зигзагов. Возможно даже тонкая хромовая нить в оплётке. Можно наверное и самому такое сделать, но там есть ещё переключатель электронный на три режима, он рассчитан на мощность своих квадратов.
Спасибо, посмотрел под другими углами на вопрос, раньше не видел эти нюансы. Понял про какое сокрытие вы говорите.
После 4K телевизора мне стали не понятны все эти танцы с мониторами. То "очень широкие для геймеров", то "очень высокие для дизайнеров", то 10 битные, то очень яркие. И радуются всегда, что нет рамок. Открою секрет - у телевизора рамок нет. Размещаете две программы 1920x1080 друг над другом, и ещё остаётся по половине места слева и справа для всяких виджетов, дебагеров или блокнотов. У телика матрица отличная, и нет лага (на LG для этого нужно включить режим компьютера у hdmi-входа, и убрать всякие улучшалки в настройках). Полноценный 4K 60fps 10bit IPS HDR, размером с целый стол. Только для дизайнеров может не зайти - всякие фотошопы или планшетные дрова вроде бы не умеют ограничивать прямоугольник движений курсора, и выходит огромный ход. Но свобода не сравнится двойными, широкими или высокими мониторами. И фильмы можно "бесшовно" смотреть - не нужно ничего для этого делать, только развернуть на весь экран. А майкрософтовская программа PowerToys умеет делить экран на любые области, куда удобно примагничиваются окна в нужных размерах.
Методы по умолчанию должны быть у предка, а не у интерфейса. Например у предка, реализующего интерфейс. Но C# не поддерживает множественное наследование, что для игр недостаток, так как например ружьё со штыком - это одновременно и ружьё и штык. Одной оси наследования мало, а агрегирование спасает не полностью, оно менее удобно чем наследование и заставляет делать прокси-свойства. В c++ множественное наследование есть. Почему в C# его не сделали, а теперь возвращают в интерфейсах и делают из них класс, не понятно. Ну что есть то есть, вы от этого довольны, а я бурчу вот, у меня идеалы другие - множественное наследование и интерфейсы-не-классы.
Вот второй абзац в Википедии про обобщённое программирование:
Дженерики как частный случай там есть, но ими не ограничивается. Вот например в той же статье на английском (в русском вырезано):
Тут говорится про то, что например JS имеет "обобщённость" просто потому, что не проверяет типы.
Ну если вы имеете в виду изначально только ООП, тогда да. А так вот из Википедии опять:
------
Для сокрытия создано сокрытие (private). Интерфейс нужен для обобщённого программирования. Поясню ещё раз. Я например ожидаю, что аргумент функции будет иметь метод work. Мне без разницы на наследование, на то открыта реализация или нет, есть дженерики в языке или нет, мне нужен только метод work. Почему это обобщённое программирование? Потому что я написал код функции один раз, никогда его не меняю, а он работает с разными типами входящих данных. Почему это полиморфизм? Потому что разные объекты подходят в одно место использования.
В том что его нужно писать. Если у вас функция только вызывает метод work у объекта, то вы пишете параметр типа IWorkable . Тогда таких интерфейсов очень много. Вот я и говорю, если не нужно обобщённое программирование, то есть если метод и так всегда работает с одним классом или с одним предком, а не с любыми объектами, то интерфейс тут не нужен, а нужен класс-предок. Это экономит силы программиста.
Мы говорим о разных граничных случаях, чтобы доказать точку зрения. Вот статья для мидлов на юнити. Мне кажется, что там и будет монолит :) . Но будут бояться менять интерфейсы, просто потому что так написано в интернете. И будут городить многоэтажные дополнения-потомки или новые интерфейсы вместо правки существующего кода.
Ну насчёт этого я перегнул. Смысл моего выпада был в том, что интерфейс это контракт. А его используют уже как склад всего подряд. Отсюда новичёк подумает, что private в интерфейсе - это так и надо. Только потом узнает, что это совсем не тот private (не контракт). Хотя в нынешние времена, насколько я понял, новичок даже не задумается, потому что для него интерфейс - это просто штука из конкретного языка, а не воплощение контракта.
Подумал подумал, минус заслуженный :) погорячился.
Из моего опыта так не работает. Потому что не возможно всё учесть на этапе планирования. Интерфейсы будут создаваться по ходу разработки, потому что не возможно распланировать проект настолько глубоко и подробно. А дальше будет тупик - запретили себе изменять интерфейсы, и можете реализовывать только то, что запланировали в самом начале. Если же вы говорите не про самое начало, а просто про какой-то очередной этап разработки, то вопросов нет, интерфейсы тогда могут помочь.
Этот принцип не работает в полной мере. Если только наращивать и никогда не править, то такой код очень быстро станет перегруженным и не понятным. Просто в каждом месте придётся пробираться через нагромождения. Сегодня рады что не трогали код соседа, а завтра вместе с соседом придётся рефакторить нагромождения.
Я теперь понял ваш посыл - перечислить в картинке всё что может C#. Да, в нём захотели использовать интерфейс как склад, как неймспейс или класс. Я придрался потому, что это всё - противоположность назначения интерфейсов. Если я вижу private или static в интерфейсе, то прежде всего думаю, что автор кода не понимает зачем нужны интерфейсы, или что он столкнулся с какими-то проблемами и ему пришлось это написать. Интерфейс нужен по месту требования, например для параметра функции. Нельзя требовать на входе функции чтобы входящий объект имел приватное поле или чтобы его класс имел статичный метод.
Товарищи, вижу минус, поясните что не понравилось, чтобы я хотя-бы понимал, нужно такие полотна впредь писать или нет. Может вам не понравилось "много буков", или вы и вправду уверовали в те статьи, где интерфейсы для большой команды, или любите private в интерфейсах, или что-то ещё не так? Кнопки удаления нет, так хоть узнаю может.
Думаю неверно расставлены акценты, объясню по-своему, может будет полезно.
Инкапсуляция:
Имеет много определений - в широких смыслах и в узких. ООП начинается, когда объединили данные с методами их обработки. Уже это можно называть инкапсуляцией. Как следствие данного объединения появляется возможность скрыть данные и методы. Потому что лежащие независимо данные и методы не могут быть скрыты, иначе их нельзя будет использовать. Разве что могут быть помещены друг в друга или использовать какие-то правила именования для имитации сокрытия.
Сокрытие:
У вас C#, но в целом может достигаться и без модификаторов типа private. Например это могут быть подчёркивания __такие, или локальный скоуп, откуда переменные не выходят наружу. Например в JS модификатора private до сих пор нет, но сокрытие всегда в нём было и будет. Сейчас для этого выдумали решётку #такую.
Наследование:
Для переиспользования кода при ООП. Переиспользование может достигаться и без наследования, например через вызов обычной внешней функции, или через делегирование, или через "воровство" методов других объектов с подменой this, и много ещё как.
Наследник может не иметь доступа к родительским данным и методам. Переиспользование тогда выходит только в вызове конструктора предка или в прочих неявных механизмах языка.
Наследуются экземпляры, а не классы. Классы остаются отдельными, в частности статичные поля у каждого класса свои.
Наследник не "берёт у родителя", а является родителем. "Берёт" при делегировании.
Полиморфизм:
Для обобщённого программирования, то есть чтобы один код работал с разными типами данных. Достигается как угодно, лишь бы один код работал с разными типами данных. В языках со слабой динамической типизацией полиморфно всё, потому что переменные и функции не знают, какой тип в них попадёт. Так происходит в JS например, где различные объекты подходят в одни и те же места просто потому, что нет проверки типов. В языках со строгой статической типизацией есть специальные механизмы для обобщённого программирования, например интерфейсы или пропуск потомка там, где требуется предок, то есть полиморфизм потомков.
Интерфейсы:
Для обобщённого программирования (полиморфизма) в языках со статической типизацией. Чтобы можно было засунуть различные объекты, не имеющие одинакового предка, в одно место использования. Например если требуется где-то объект с методом work, тогда делаем интерфейс с таким методом. И тогда без разницы какой будет класс.
Интерфейсы не являются фундаментальными кирпичами архитектуры проекта, как вы пишете. И они создаются не в начале проекта, а когда потребовались. Не для удобства обращения к объектам и не для большой команды, а для обобщённого программирования. Если такового нет или не требуется - не нужно делать интерфейсы. Также зачастую можно обойтись классами, так как создавать интерфейс под каждое место использования может быть накладно.
То, что интерфейсы нельзя изменять, - не правда. Никакой негативной практики, как вы пишете, в этом нет. Это абсолютно обычное дело. В IDE даже есть рефакторинг интерфейсов - во всём проекте всё синхронно меняется и ничего не ломается. Также компилятор проверяет все места использования интерфейса и все ошибки после изменений легко найти. Смена методов интерфейса и смена методов предка никак не отличаются по негативности. Но бывает мнение, что код можно только наращивать, но никогда не менять, в таком случае можно со мной не согласиться.
В вашем примере IMovable есть поля private, protected и static в интерфейсе. На мой взгляд это глупость, потому что интерфейс может быть только публичным, иначе не имеет смысла. И служит для экземпляров, а не для классов, поэтому static там быть не может. Также const в интерфейсе не может быть, потому что константы не принадлежат экземплярам, и интерфейс не может требовать константу от экземпляра. Разве что это какие-то заморочки конкретного языка, например в C# у интерфейсов есть реализация, что противоречит даже вашим словам "отделить описание от реализации".
Возможно я не тот аспект затрагиваю или под другим акцентом.
Я имел в виду не только правки от клиента, но и "первичную" сдачу работы. Текст "обучение персонала" на кнопке карточки вряд ли был оговорен заранее. То есть получили вёрстку или дизайн, проверяете, а там два слова не влезло. Вот такие моменты возникают потом.
Опытные исполнители подстилают себе солому без раздумий, это скорее чутьё и по-умолчанию-резиновый подход. Но не идеально, и далеко не везде. Что не влезло и отвалилось - доделывается спокойно потом.
Есть начинающие верстальщики и дизайнеры, которые всё прибивают гвоздями, им такие статьи полезны. А есть опытные, которые просто не делают всё заранее, потому что это долго и не всегда оказывается востребовано при реальном использовании.
Думаю, что веб-дизайнеров должны учить верстальщики, после их дизайнерского образования или сразу. А верстальщиков - программисты. Поначалу там не то что одна статья, им месяцами нужно показывать кучу таких вещей.
Ошибки и недопонимание здесь возникают из-за того, что в будущее смотреть никто не умеет.
Мнение "работа сдельная, я уже всё отдал, меня уже не касается" позволяет расслабиться после сдачи работы, выпить пивка, или знать что можешь взять следующую работу.
Я бы вместо этого посоветовал нормально относиться к последующей доработке, с обоих сторон. То есть убрать фактор "неизвестного будущего" - причину проблем.
Когда делаешь весь проект самостоятельно, то становится очевидно, что всё меняется на всех этапах, и всегда по-разному, поперёк и наискось. Никакие списки требований и подсказок не помогут.
смысл у нее появится только в зависимости от того как мы ее будем использовать, то есть откуда будем на нее ссылаться
Не обязательно. У целого числа 2 может быть потомок Width. Тогда он будет отличаться от Height. В любых объектах, которые их используют. Это можно делать наследованием или каким-нибудь брендированием для передачи смысла "2 как ширина". А у Color может быть наследник SkyColor или color.type = sky. То есть цвет не имеет смысла, и используется там, где смысл не важен, а цвет неба используется там, где важно его отличать от цвета кожи.
Сделайте обобщённый класс Sense<T,S>, и сможете для полей писать смысл, и он будет единый для всего проекта. Например поле "ширина_кабины" : Sense<int,кабины> = 5.
В области ИИ я ничего не понимаю, и наверное вы придумали что-то полезное, но замечу:
Два, одинаково называемых поля в
разных объектах это два совершенно разных системных объекта
может быть один экземпляр свойства между многими объектами
... и не имеющих ничего общего с точки зрения системы
у них один тип или класс или интерфейс или структура или экземпляр
Человек воспринимает свойство самостоятельной сущностью и говоря, например, о цвете машины и о цвете волос, мы понимаем, что речь идет об одном свойстве – цвете
да, это тип
Следовательно, для реализации алгоритмов, моделирующих мыслительные процессы человека, свойство и объект должны быть представлены в виде самостоятельных и равноправных структур
они так и представлены, как объект и как тип свойства
Так как описание объекта максимально абстрактно («Нечто»), а новые свойства легко определяются и добавляются, то функциональность может быть расширена без необходимости внесения изменений в уже реализованные действия
Это объект JS или словарь. А потом понадобится ответить на вопрос "как работать с этим объектом, когда я забыл где и что добавлял, и есть ли оно в данный момент", и вы изобретёте контракт и класс. JS -> TS. А функциональность при наследовании и так расширяется без изменений, или меняется где это нужно через override. Или допустим на строго типизированном языке можно сделать класс, у которого все свойства и методы будут в словаре, и вызывать методы Get Set Call, что и происходит в JS. Только это будет в одном случае, а всё остальное строго. И будет это дженерик, у которого для свойств указывается один и тот же тип, или any/object для любого типа. И через этот тип свойства в разных объектах связаны по смыслу. А когда нужно связать их ещё и по поведению в рантайме, то они просто станут ссылками на объект свойства где-нибудь в куче.
В условиях острого недостатка новых идей
Сильно сказано. Может они просто не проходят отбор.
В частности, на многие десятилетия считающееся само собой разумеющимся представление о том, что объект первичен, а свойство привязано к объекту.
Потому что по определению, объект - это данные и методы их обработки. Если данные сами по себе - то никакого объекта нет. Там где данные не привязаны к объекту, есть например функциональное или процедурное программирование. И у вас о свойствах представление как о примитивах типа целого числа, но они могут быть объектами, их смысловая связь прямо прописана в виде класса.
Можно во всех ситуациях использовать div, кроме тех, где очевидно ломается что-то, или иногда ломается. Например, если у вас админка, в которой слепой человек не сможет работать, даже если всё будет доступным, то делать такую админку доступной - не имеет смысла. Или если в любом случае всё будет делаться мышкой, то перемещение табом можно вообще выкинуть. Если вы на таком проекте работаете, то доступностью вы просто потратите время и деньги, и будете зря что-то доказывать коллегам. Просто подумайте в каждом случае что вам нужно, а что нет, а не слушайте советы идеального мира.
Если бы была возможно писать теги вообще без указания их тег-имени, было бы ещё лучше. Потому что это был бы контейнер. А прочие особенности и назначения можно задавать в атрибутах. Плюс в том, что это опционально, и дробится на сколько угодно нюансов. Так когда-то поступили со style, так же можно поступить и с именем тега. Сейчас теги имеют как минимум 3 назначения, то есть являются контейнером, семантикой и имеют разный принцип работы. А как же разделение ответственности? Свалили всё в одну кучу, поэтому приходится писать статьи, чтобы как-то договориться как с этой кучей работать.
Не слабо так, спекулятивно отрендерить голливудский фильм. Просыпается потом монтажер, доделывает кадры, а рендер в помойку.
Векторный GUI - это преимущество?
Преимущество векторной графики - масштабирование. Ресайзим однопиксельную рамку в полтора раза, и она мутная или округляется в какую-то некрасивую сторону.
Отрисовка пиксельного квадрата везде векторное, не из картинки его берут. Браузеры могут рисовать SVG и анимации, CSS сплошь и рядом векторный. Шрифты давно векторные. Получается все ОС, особенно браузерные, - векторные. Ну у окон не торчат векторные вензеля и короны, и слава богу.
У векторных иконок нет хинтинга, их детали не попадают в пиксели. А на винде иконки "в исходнике" большие - аналог векторных, при даунскейле. А маки имеют высокий ppi, что нивелирует отсутствие хинтинга или мутность иконок. И проблем нет, всё хорошо на "дисплеях высокого разрешения".
Если насчёт веба имелся в виду фронтенд, то скажу что нет смысла обфусцировать JavaScript. Потому что самому же будет сложнее разрабатывать, а злой дядя всегда может легко превратить код в нормальный или понять без превращений, особенно когда ему заплатили хорошо.