Абстрагирования метод это: метод абстрагирования | Перевод метод абстрагирования?

Примеры абстракций в технике и повседневности / Хабр

Поговорим про абстракциях. Что вообще это за слово такое абстракция?

Абстракция  (отвлечение) про­цесс от­вле­че­ния (абстрагирования) от тех или иных ха­рак­те­ри­стик объекта для их из­би­ра­тель­но­го анализа; при этом на­блю­дае­мый объ­ект за­ме­ща­ет­ся его идеализированным тео­ре­тическим об­ра­зом — аб­стракт­ным объектом. Абстракции являются уни­вер­саль­ным методом на­учного по­зна­ния, они необходимы для фор­ми­ро­ва­ния по­ня­тий, уз­на­ва­ния и клас­си­фи­ка­ции объ­ек­тов исследования на всех уров­нях фор­ми­ро­ва­ния зна­ний.

Синонимами можно считать такие слова как отвлеченный, умозрительный, теоретический. Абстракция это модель, теория.

Противоположное слово это конкретный, фактический.

Абстракция это когда берут какой-то сложный объект и убирают те детали, которые не имеют существенного значения для понимания какого бы то ни было свойства этого объекта.

Взять например карту метро. Карта метро — это хорошая полезная абстракция от реальной формы туннелей в метро. На карте нет тех изгибов тоннелей которые на самом деле есть. Вы же когда приезжаете в какой-то новый для себя город не рассматриваете на полу  разложенные аэрофотоснимки гектаров кварталов города чтобы понять где вам надо выйти в метро. Это было бы просто смешно. Вы просто подходите к схеме метрополитена смотрите и вам сразу всё становится понятно. Так и в остальном.

Абстракции в разработке программного обеспечения

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

Виртуальная память это абстракция от физических адресов. Виртуальная машина это абстрагирования от реальной физической машины (будь то телефон, DeskTop, Server). Любой язык программирования это способ отвлечения от безумно сложных и скучных машинных кодов. В каждой программе есть абстрактные структуры данных такие как бинарные деревья, очереди, стеки, циклические массивы, графы, косые деревья, хеш-таблицы. Файл как и файловые системы преобразуют нули и единицы в удобные текстовые файлики. Алгоритмы компрессии данных это способ отвлечения от реального размера файла. Операционная система это способ отвлечения от конкретного оборудования. POSIX (Portable Operating System Interface) это пример полезного абстрагирования от реализации функций операционных систем. Благодаря POSIX у разных операционных систем появилась совместимость на уровне исходного кода. Иконки на рабочем столе — тоже самое. Гипервизоры нужны чтобы не обращать внимания на то как меняются операционные системы. Байт-код это отвлечение от целевой платформы для которой собрана программа. Язык Python абстрагируется от типов данных. Модель OSI-7 это условное представление того через какие слои проходят данные в интернете. Физический, канальный, сетевой, транспортный, представления, сеансовый, прикладной. DNS адреса удобнее запоминать чем сырые IP адреса. Любое прикладное ПО с GUI это чистейшей воды абстракция. Прикладное ПО (например программа для трассировки печатных плат) это умозрительная концепция, коротая решает конкретную задачу реализованная на основе интерфейсов, которые предоставляет операционная система.

В общем абстракции очень полезны в программировании. Для разработки софтвера надо обязательно обладать развитым абстрактным мышлением.

Абстракции в аппаратном обеспечении

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

Вот например автоматическая коробка передач абстрагируется от реальной геометрии переключения положения шестерен очень полезная абстракция воплощенная в железе.  Или драйвер шагового двигателя это способ абстрагироваться от того как на самом деле осуществляется управления вращением вала шагового мотора. Затем появилась цифровая схемотехника, чтобы не вникать в реализацию логических элементов. Далее сформировался язык Verilog абстрагируется от схемотехники цифровых цепей и описывает цифровую схему просто как текст. Схемы конечный автоматов это пример отвлечения от физического расположения микросхем триггеров на электронной плате. Принстонская/Гарвардская архитектура микропроцессора это умозрительная модель понимания структуры всего компьютера.

Вот в схеме топологии печатной платы нет абсолютно никакой абстракции. Топология PCB она максимально конкретная. Поэтому и анализировать топологию всегда трудно. Многое отвлекает.

https://habr.com/ru/articles/655879/

Поэтому люди придумали схемы электрические принципиальные. Схемотехника это абстракция от топологии. Однако и схемотехника современных электронных устройств тоже достигла высокого уровня сложности. Схемотехника в 40…100 страниц это уже вообще сегодня норма жизни. Поэтому люди придумали блок-схемы электронных плат. Блок-схема это абстракция от схемотехники, которая работает на 2м уровне. Потом делают схемы топологии сети. Это уже, как минимум, 3тий уровень абстракции. 

https://habr.com/ru/articles/667030/

Проследите цепочку получившихся уровней:  Физика > Полупроводниковые приборы > аналоговые схемы > цифровые схемы > логические элементы > АЛУ > процессор > SoC > PCB > OS(системное ПО) > Прикладное ПО. Минимум 11 умозрительных уровней!

Абстракции это не выдумка программистов. Абстракции появились задолго до появления программирования и электроники вообще. Это более фундаментальная концепция. Скорее всего это пришло из искусства. Наскальная живопись, корявые рисунки животных первобытных людей. Всё это пошло откуда-то оттуда.

Вероятно абстракции появились как побочный эффект познания мироустройства в науке. Например закон всемирного тяготения это абстракция. Реальные силы значительно труднее в понимании и объяснении. Это доказывают опыты наблюдения смещения перигелия Меркурия. https://ru.wikipedia.org/wiki/Смещение_перигелия_Меркурия

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

В эпоху Великих Географический Открытий появилась ценность географических карт. Географическая карта это тоже абстракция от реальной формы земной поверхности и береговой линии. Там реки указывают плавной линией хотя на самом деле они извиваются как змеи и через каждые 100—200 метров поворот.

Абстракции мы всегда видим в повседневности. Деньги это вообще абстракция от вида трудовой деятельности. Будь то труд каменщика или труд пекаря.  Поэтому и говорят: «деньги не пахнут».

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

У каждой уважающей себя организации, компании есть логотип. Это условное обозначение которое впитывает в себя огромное количество аспектов. Чем занимается компания, какое у нее прошлое, где находится, какая у компании цель — всё это отражается в хорошем логотипе.

А оut source компании это пресловутый способ абстрагирования от найма как такового и социальных противоречий связанных с этим для продуктовых компаний.
https://habr.com/ru/articles/720464/

У абстракций есть недостатки?

Да, конечно. Уровни абстракции отбирают у системы некоторые ресурсы. Java код исполняется медленнее чем С код. Артефакты Java компилятора занимают больше места на диске, чем артефакты от C компилятора. Системные вызовы от приложений обрабатываются на уровне операционной системы и требуют времени. Это плата за упрощение понимания и переносимость программ. На каждом уровне абстракции время течет медленнее. То что в прикладном ПО одна строчка кода, то в коде на физическом уровне целая эпоха.

В чем достоинства абстракций?

1—Они помогают понять сложные вещи. Абстракции делают возможным применение формальных методов, и алгоритмов, т.е. в конечном счете логики. (модель атома Бора, абстрактные структуры данных в программировании, закон всемирного тяготения, математический маятник, идеальный газ, материальная точка)

2—Они уменьшают время понимания сложных вещей (схема метро, электрические принципиальные схемы)

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

4—Они помогают переносить объекты на другую систему координат (Языки программирования Java, гипервизоры, Doсker контейнеры)

5—Они заменяют сложное на простое (языки программирования, файловые системы, DNS адреса, иконки на рабочем столе, программы с GUI).

6—Они помогают уйти от ответственности (out source компании, модель OSI-7)

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

Способность к абстрагированию помогла им построить самую эффективную лаконичную нотацию для обозначения своего языка общения, чертежей, математических выражений, а потом и языков программирования. Как следствие они получили способность проектировать разрабатывать и производить сложные и эффективные технические средства: двигатели, корабли, самолеты, вооружение и компьютеры.

Как научиться абстрактному мышлению раз это так полезно? Как научиться придумывать полезные абстракции?

У меня нет четкого ответа на этот вопрос. Наверно надо пробовать. Далее эксперименты покажут какие абстракции жизнеспособны, а какие нет. Это как в физике. Была модель атома Томсона и модель атома Бора. В результате экспериментов выяснилось, что модель атома Бора оказалась более пригодной к реальности. Многие языки программирования тоже канули в лету. Где сейчас Паскаль, Fortran или Бэйсик? Тут как с языками программирования. Некоторые абстракции будут существовать до поры до времени пока их не заменят более эффективные простые абстракции. И это нормально.

Вывод

У природы же видимо нет абстракций. В природе всё максимально конкретно. Абстрагирование это чисто человеческое свойство. Это люди придумывают абстракции и уровни абстракций для себе подобных. Это и понятно. Смысл абстракции это уменьшение сложности, увеличения скорости понимания, объяснение сути чего-либо, будь-то карта материка или электронная плата.  

Создавайте свои абстракции, господа. В этом нет ничего предосудительного.

Известные мне примеры умозрительных понятий я перечислил тут https://docs.google.com/spreadsheets/d/1JxEuo7bxo2A7J5qksBxekWf3FJVuDCJbXaZKx9IvDnU/edit#gid=0

Если Вам известны ещё примеры красивых абстракций в технике или в повседневной жизни, то напишете про это, пожалуйста, в комментариях.

https://habr.com/ru/companies/tiktokcoach/articles/206994/

https://habr.com/ru/companies/skillfactory/articles/508716/

Абстрагирование в психологии — Психолог Татьяна Хохлова

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

В психологии это понятие связано с изменением взгляда на привычные вещи, отвлечение от объекта (человека, деятельности, цели, ситуации) с целью его более беспристрастной оценки.

Цели абстрагирования

Сознание человека устроено таким образом, что он чаще воспринимает объект в целом, не разделяя его на отдельные составляющие. Абстрагирование же – это возможность отделить одну характеристику от другой и увидеть объект по-новому.

Поскольку с латинского языка слово «абстрагирование» переводится как отвлечение, часто этим термином называют уход от неприятной ситуации. Это не совсем верно, ведь абстрагирование позволяет:

  • взглянуть на ситуацию под новым углом, чтобы адекватно ее оценить и принять решение;
  • отвлечься от собственных чувств в отношении ситуации или объекта, что приведет к формированию нового взгляда на вещи.

Отождествление

Эта цель абстрагирования предполагает удержание фокуса внимания на признаках, которые объединяют один объект с другим. Например, испытывая страх перед исходом определенного события, человек может вспомнить схожие ситуации, исход которых был удачен. И понять, что его страх иррационален и практически не обоснован.

Систематизация и разделение

Эта цель, напротив, направлена на удержание фокуса внимания на тех признаках, которые отличают объекты. Например, если однажды исход события был неудачным, это не значит, что схожая ситуация будет складываться так же.

Обобщение

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

Четкость и конкретика

Эта цель позволяет определить границы понятия или объекта (ситуации). Она дает возможность повысить эффективность коммуникации, ведь часто люди склонны додумывать за собеседника. А ведь в процессе общения он мог иметь ввиду совершенно не то, что могло показаться.

Создание образца

Образец – это отправная точка. Ее может не существовать в реальном мире, однако она служит идеальной моделью, ориентиром, к которому можно двигаться. Создание образца очень эффективно для постановки целей.

Умение абстрагироваться – это важное качество личности, которое дисциплинирует и позволяет оградить себя от излишних переживаний, а также способствует успеху в различных сферах жизни.

Типы абстракций

Абстракции – это преобразованные представления об объекте или явлении объективного мира.

  1. Изолирующая абстракция. Соответствует вычленению и фиксации определенных черт объекта или явления.
  2. Обращающая абстракция.
    Соответствует общей характеристике объекта или явления (учитывая все черты в совокупности).
  3. Идеализация. Соответствует замещению реальной цели на некий идеализированный образ. Используется для наиболее эффективного применения всех доступных инструментов достижения обозначенного результата.

Методы абстрагирования

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

  1. Создание шаблона. Любое свойство, характеристика объекта или явления можно использовать в качестве образца, который станет начальной точкой. С помощью него можно увидеть другие свойства объекта, рассмотреть его под другим углом.
  2. Самоконтроль. Умение контролировать свои действия и эмоции – важнейшее качество личности, которое позволяет сконцентрироваться на своих переживаниях и отвлечься от внешнего раздражителя. Или, напротив, в случае сильных эмоциональных встрясок «переключиться» на восприятие внешнего мира.
  3. Адекватная оценка ситуации/явления/объекта. Этот метод позволяет трезво оценить тот или иной объект/ситуацию/человека, не поддаваясь своим эмоциям. Сюда же можно включить и адекватную самооценку, поскольку, оценивая себя честно, можно увидеть вовремя недостатки и исправить их, при этом удерживая внимание на достоинствах.
  4. Воображение. Техники визуализации помогают справиться с негативными переживаниями и сместить акцент внимания с негативных сторон ситуации/явления/объекта на его позитивные стороны. Иногда человеку нужно время, чтобы воспринимать происходящее адекватно. А визуализация позволяет вовремя остановиться, чтобы не совершить глупость. Этот метод помогает тогда, когда контроль эмоций и поведения кажется невозможным.
  5. Развитие навыка концентрации. Концентрация на положительных сторонах – это навык, который очень полезен в жизни. Концентрация на негативных сторонах же, напротив, может приводить к депрессии. Чтобы развить в себе этот навык, необходимо периодически переосмысливать происходящее и отслеживать свои реакции.

Умение абстрагироваться тесно связано с позитивным мышлением, которое предполагает поиск плюсов в даже сложных ситуациях. Любая сложность – это задача, которая предполагает получение новых навыков и нового опыта.

Поэтому внутреннее спокойствие, развитие концентрации, а также взгляд под другим углом – это лучшие способы справиться с проблемой.

Абстрагирование – это способ, который позволяет достигнуть поставленной цели и поддерживать позитивный настрой.

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

Абстрагирование положительно влияет на психическое здоровье человека, ведь этот прием направлен на бережное отношение к своему внутреннему миру.

 

Как переопределить абстрактные методы в интерфейсах

Учитесь на знаниях сообщества. Эксперты добавляют свои идеи в эту совместную статью на основе ИИ, и вы тоже можете.

Это новый тип статьи, которую мы начали с помощью ИИ, и эксперты продвигают ее вперед, делясь своими мыслями непосредственно в каждом разделе.

Если вы хотите внести свой вклад, запросите приглашение, поставив лайк или ответив на эту статью. Узнать больше

— Команда LinkedIn

Последнее обновление: 27 апреля 2023 г.

Как обеспечить совместимость и согласованность при переопределении абстрактных методов в интерфейсах? Интерфейсы — это мощная функция Java, которая позволяет вам определять общее поведение для разных классов без указания деталей их реализации. Однако иногда вам может потребоваться настроить или изменить поведение метода интерфейса для определенного класса. Вот где пригодится переопределение абстрактных методов. В этой статье вы узнаете, как переопределять абстрактные методы в интерфейсах и какие правила нужно соблюдать, чтобы избежать ошибок и обеспечить совместимость.

    Что такое абстрактный метод?

    Абстрактный метод — это метод, который не имеет тела и имеет только сигнатуру. Он объявляется с помощью ключевого слова abstract и заканчивается точкой с запятой. Абстрактный метод представляет собой общее действие, которое может выполняться разными классами, но у каждого класса может быть свой собственный способ его выполнения. Например, абстрактный метод run() может быть определен в интерфейсе Animal, но каждый подкласс Animal (например, Dog, Cat или Bird) может иметь свою реализацию run().

    Что такое интерфейс?

    Интерфейс — это набор абстрактных методов и констант, которые определяют общее поведение или контракт для группы классов. Интерфейс объявляется с помощью ключевого слова interface и его имени. Интерфейс может иметь несколько методов, но все они должны быть абстрактными. Интерфейс также может иметь константы, которые объявляются с помощью ключевых слов public, static и final. Интерфейс не может иметь конструкторов, переменных экземпляра или неабстрактных методов. Например, интерфейс Vehicle может иметь абстрактные методы, такие как start(), stop() и Acceleration(), и константы, такие как MAX_SPEED и MIN_SPEED.

    Как реализовать интерфейс?

    Реализовать интерфейс означает предоставить тело или код для каждого абстрактного метода в интерфейсе. Класс может реализовать один или несколько интерфейсов, используя ключевое слово «реализует» и перечисляя имена интерфейсов после имени класса. Класс, реализующий интерфейс, должен обеспечивать реализацию всех абстрактных методов интерфейса, иначе он должен быть объявлен как абстрактный. Например, класс с именем Car может реализовать интерфейс Vehicle, предоставив код для методов start(), stop() и ускорение().

      Как переопределить абстрактный метод?

      Переопределить абстрактный метод означает предоставить другую или более конкретную реализацию абстрактного метода, унаследованного от интерфейса или суперкласса. Класс может переопределить абстрактный метод, используя ту же сигнатуру, что и исходный метод, но с другим телом или кодом. Ключевое слово @Override можно использовать в качестве аннотации, чтобы указать, что метод переопределяет другой метод. Например, класс ElectricCar может переопределить метод start() из интерфейса Vehicle, используя другую логику для запуска двигателя.

        Зачем переопределять абстрактный метод?

        Переопределение абстрактного метода может быть полезным по нескольким причинам. Одна из причин заключается в обеспечении большей функциональности или гибкости для определенного класса. Например, ElectricCar может переопределить метод start() для проверки уровня заряда батареи перед запуском двигателя или для отображения сообщения на приборной панели. Другая причина заключается в обеспечении совместимости или согласованности с интерфейсом или суперклассом. Например, интерфейс Animal может иметь абстрактный метод с именем eat(), но у каждого подкласса Animal могут быть разные диетические требования или предпочтения. Переопределяя метод eat(), каждый подкласс может гарантировать, что он следует контракту интерфейса и ведет себя так, как ожидалось.

          Каковы правила переопределения абстрактного метода?

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

            Оцените эту статью

            Мы создали эту статью с помощью ИИ. Что вы думаете об этом?

            Это здорово Это не так здорово

            Спасибо за ваш отзыв

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

            Ваши методы должны быть «Single Level of Abstraction» Long

            Большинство разработчиков программного обеспечения признают, что методы в их коде не должны занимать сотни строк кода (не говоря уже о тысячах). Это один из немногих принципов кодирования, по поводу которого мы, разработчики, пришли к единому мнению. Однако, когда дело доходит до указания длины методов, этот хрупкий консенсус рушится: некоторые говорят, что методы должны помещаться на одном экране; другие ограничивают количество строк определенным числом; разработчики, ориентированные на познание, предполагают, что методы должны быть достаточно короткими, чтобы уместиться в вашей голове; и подходов больше.

            Я редко задумываюсь о длине своих методов. Вместо этого я подчиняюсь другому, более важному принципу, который имеет приятный побочный эффект естественного создания более коротких методов. Этот принцип называется принципом единого уровня абстракции (SLAP).

            Как следует из названия, принцип единого уровня абстракции гласит, что каждый метод в кодовой базе должен иметь дело с концепциями, относящимися только к одному уровню абстракции. Без смешивания. Звучит просто, но на практике применить этот принцип в реальном коде может быть сложно, потому что он… ну, абстрактный. Поэтому в этом посте я объясню, что означает принцип единого уровня абстракции, и покажу несколько примеров его применения в коде.

            Абстракция

            Абстракция — это то, что скрывает ненужную информацию. Это определение может показаться совершенно непрактичным, поэтому позвольте мне продемонстрировать, что делают абстракции, на простой аналогии.

            При взаимодействии с компьютером вы используете экран, клавиатуру, мышь и другие периферийные устройства. Вам плевать на пластик, стекло, печатные платы, конденсаторы, чипы, вентиляторы и т. д. И уж точно плевать на транзисторы. Все эти низкоуровневые детали, какими бы важными они ни были для работающего компьютера, не имеют значения, когда вы работаете или играете в игры. В этом примере внешние устройства ввода-вывода вашего компьютера, а также его внешнее физическое тело являются абстракциями. Они скрывают от вас большую часть низкоуровневых сведений и предоставляют минимальный объем информации и функций, которые позволяют вам использовать компьютер.

            Подумайте вот о чем: если бы нам нужно было понять хотя бы 1% сложности наших компьютеров, прежде чем мы сможем их использовать, большинство людей не смогли бы написать и одной строки текста. Следовательно, абстракции не являются необязательными или второсортными конструкциями. Это обязательные инструменты. Фактически, для большинства пользователей абстракции более высокого уровня (например, веб-сайт) гораздо более реальны, чем любые детали более низкого уровня (например, передача данных).

            Исходный код также использует мощь абстракций. Например, класс скрывает большую часть своей сложности от внешнего мира и предоставляет простой набор функций (надеюсь) в форме своего общедоступного API. Итак, класс — это абстракция. Но методы также являются абстракциями, поскольку они также скрывают большую часть своей сложности. А исходный код сам по себе является абстракцией, потому что он позволяет вам использовать такие операторы, как 9.0087, если , или , если , не имея дело с инструкциями, программными счетчиками, регистрами и т. д.

            В общем, везде мы видим абстракции «поверх» других абстракций. Эта прогрессия «уровней абстракции» продолжается и продолжается, и продолжается. Даже транзисторы, которые мы часто рассматриваем как самые фундаментальные компоненты компьютерной инженерии, являются абстракциями более низкого уровня концепций EE и физики твердого тела.

            Принцип единого уровня абстракции (SLAP)

            Вернемся к SLAP, который выступает за то, чтобы каждый метод в вашей кодовой базе имел дело только с одним уровнем абстракции.

            Это определение может показаться странным, потому что в предыдущем разделе я сказал, что метод сам по себе является абстракцией. Итак, разве метод не имеет дело с тем уровнем абстракции, который связан с тем, что он является методом? Ну в общем то верно. Однако, как и экран, который может одновременно отображать информацию и вводить данные, один объект может представлять разные абстракции, если смотреть с разных точек зрения. Таким образом, метод действительно является абстракцией сам по себе. Это верно со «структурной» точки зрения, если рассматривать его как одну из языковых конструкций. Однако SLAP рассматривает метод как контейнер для кода, который манипулирует другими концептуальными абстракциями, связанными с функциями приложения.

            Согласно SLAP, исходный код внутри каждого метода должен относиться к концепциям и механизмам, относящимся только к одному уровню «оперативной сложности» вашего приложения. Например, если метод создает и выполняет HTTP-запросы, он также не должен обрабатывать полученный JSON. Это разные уровни абстракции: один касается связи по HTTP, а другой — определенного формата данных и макета.

            В следующих разделах я покажу несколько примеров кода, которые прояснят для вас SLAP.

            Рефакторинг для SLAP — пример 1

            Рассмотрим этот метод из официального приложения Google IO Scheduler:

             override fun toggleFilter(filter: Filter, enabled: Boolean) {
                    если (фильтр !in _filters) {
                        throw IllegalArgumentException("Неподдерживаемый фильтр: $filter")
                    }
                    значение изменено = если (включено) {
                        _selectedFiltersList. add(фильтр)
                    } еще {
                        _selectedFiltersList.remove(фильтр)
                    }
                    если (изменено) {
                        _selectedFilterChipsList =
                            _selectedFiltersList.mapTo(mutableListOf()) { it.asChip(true)}
                        val index = _filterChipsList.indexOfFirst { it.filter == filter }
                        _filterChipsList[index] = filter.asChip(включено)
                        опубликовать (правда)
                    }
                } 

            Имя toggleFilter , так что мы уже можем понять, что он делает. Первый оператор if проверяет недопустимый аргумент. Второй оператор if либо добавляет, либо удаляет фильтр, поэтому он связан с фильтрами. Однако реализация этого оператора показывает нам, что фильтры хранятся в каком-то списке. Не критично, но, строго говоря, что-то «переключить» и что-то «добавить» — это не совсем один уровень абстракции. И, наконец, если вторые , если приводит к изменению, код переходит в третье условие , если . Этот последний блок кода содержит некоторые низкоуровневые манипуляции, которые не читаются естественно для нетренированного глаза. Поэтому сразу не понять, что такое полный высокоуровневый поток «переключения».

            Этот код нарушает SLAP, так что давайте это исправим. Вот с чем я пришел:

             override fun toggleFilter(filter: Filter, enabled: Boolean) {
                    если (фильтр !in _filters) {
                        throw IllegalArgumentException("Неподдерживаемый фильтр: $filter")
                    }
                    если (включено) {
                        добавить фильтр (фильтр)
                    } еще {
                        удалить фильтр (фильтр)
                    }
                }
                частное развлечение addFilter(filter: Filter) {
                    если (_selectedFiltersList.add (фильтр)) {
                        updateFilterChips (фильтр, правда)
                    }
                }
                частная забава removeFilter (фильтр: фильтр) {
                    если (_selectedFiltersList. remove (фильтр)) {
                        updateFilterChips (фильтр, ложь)
                    }
                }
                приватное удовольствие updateFilterChips(filter: Filter, isSelected: Boolean) {
                    _selectedFilterChipsList =
                        _selectedFiltersList.mapTo(mutableListOf()) { it.asChip(true)}
                    val index = _filterChipsList.indexOfFirst { it.filter == filter }
                    _filterChipsList[index] = filter.asChip(isSelected)
                    опубликовать (правда)
                } 

            Теперь у нас есть явное «переключение», «добавление» и «удаление» функций. Кроме того, читая исходный код, я понял, что существует абстракция под названием «чипы фильтра», которая отличается от «фильтра». Я не знаю, что это значит (и мне все равно), но, согласно SLAP, манипуляции над этой абстракцией также должны быть извлечены в отдельный метод. Так я и сделал.

            Я нахожу версию, следующую за SLAP, более чистой и более читабельной. Теперь, читая этот код, я знаю, когда я перехожу от уровня абстракции «фильтр» к уровню «чипов фильтра», поэтому я могу просто остановиться, если мне не интересно пересекать эту границу.

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

            Пожалуйста, обратите внимание, что первоначальная версия не была чрезмерно длинной, поэтому я, вероятно, счел бы нормальным, если бы я оценивал свои методы только по количеству строк кода. Это показывает, насколько мощнее SLAP по сравнению с подсчетом строк.

            Для протокола: я тоже не думаю, что рефакторинговый код идеален. Это, конечно, намного лучше оригинала, но все равно довольно грязно. Самая большая оставшаяся проблема — злоупотребление булевыми аргументами метода, но эта проблема выходит за рамки нашего обсуждения здесь.

            Рефакторинг для SLAP — пример 2

            Второй пример — это еще один метод из того же приложения Google IO:

             private fun showFeedItems(recyclerView: RecyclerView, list: List?) {
                    если (адаптер == ноль) {
                        val sectionHeaderViewBinder = FeedSectionHeaderViewBinder()
                        val countdownViewBinder = CountdownViewBinder()
                        val momentViewBinder = MomentViewBinder(
                            прослушиватель событий = модель,
                            информация о пользователе = модель. Информация о пользователе,
                            тема = модель.тема
                        )
                        val sessionViewBinder = FeedSessionsViewBinder(модель)
                        val feedAnnouncementsHeaderViewBinder =
                            ОбъявленияHeaderViewBinder(это, модель)
                        val обьявлениеViewBinder = AnnouncementViewBinder(model.timeZoneId, это)
                        val аннонсемптивиевбиндер = аннонсментсэмптивиевбиндер()
                        val-announcementsLoadingViewBinder = AnnouncementsLoadingViewBinder()
                        val feedSustainabilitySectionViewBinder = FeedSustainabilitySectionViewBinder()
                        val feedSocialChannelsSectionViewBinder = FeedSocialChannelsSectionViewBinder()
                        @Suppress("НЕПРОВЕРЕННЫЙ_КАСТ")
                        val viewBinders = ImmutableMap.builder()
                            .помещать(
                                sectionHeaderViewBinder.modelClass,
                                sectionHeaderViewBinder как FeedItemBinder
                            )
                            .помещать(
                                обратный отсчетViewBinder. modelClass,
                                countdownViewBinder как FeedItemBinder
                            )
                            .помещать(
                                моментViewBinder.modelClass,
                                momentViewBinder как FeedItemBinder
                            )
                            .помещать(
                                сеансыViewBinder.modelClass,
                                sessionViewBinder как FeedItemBinder
                            )
                            .помещать(
                                каналобъявленийHeaderViewBinder.modelClass,
                                feedAnnouncementsHeaderViewBinder как FeedItemBinder
                            )
                            .помещать(
                                объявлениеViewBinder.modelClass,
                                объявлениеViewBinder как FeedItemBinder
                            )
                            .помещать(
                                объявленияEmptyViewBinder.modelClass,
                                объявленияEmptyViewBinder как FeedItemBinder
                            )
                            .помещать(
                                объявленияLoadingViewBinder.modelClass,
                                объявленияLoadingViewBinder как FeedItemBinder
                            )
                            . помещать(
                                feedSustainabilitySectionViewBinder.modelClass,
                                feedSustainabilitySectionViewBinder как FeedItemBinder
                            )
                            .помещать(
                                feedSocialChannelsSectionViewBinder.modelClass,
                                feedSocialChannelsSectionViewBinder как FeedItemBinder
                            )
                            .строить()
                        адаптер = FeedAdapter (viewBinders)
                    }
                    если (recyclerView.adapter == ноль) {
                        recyclerView.adapter = адаптер
                    }
                    (recyclerView.adapter как FeedAdapter).submitList(list ?: emptyList())
                    // После отправки списка в адаптер представление переработчика начинает измерение и рисование
                    // поэтому давайте подождем, пока макет будет отрисован, прежде чем сообщать о полной отрисовке.
                    привязка.recyclerView.doOnLayout {
                        // reportFullyDrawn() печатает `I/ActivityTaskManager: Полностью нарисовано {активность} {время}`
                        // в логкэт.  Платформа гарантирует, что оператор печатается только один раз за
                        // активности, поэтому нет необходимости добавлять в приложение логику дедупликации.
                        активность?.reportFullyDrawn()
                    }
                } 

            Теперь, даже если бы разработчики никогда не слышали о SLAP, этот метод все равно нарушил бы любой разумный предел максимальной длины. В некоторых случаях длинные методы неизбежны (например, длинный блок switch с десятками или даже сотнями случаев), но это не один из них. Это просто грязный код, так что давайте позаботимся об этом.

            Большая часть кода этого метода находится внутри начальной проверки if , которая завершается записью в переменную адаптера . Другими словами, большинство из showFeedItems Тело метода не имеет дело ни с лентой, ни с элементами, а с более низкоуровневыми деталями инициализации адаптера. Затем у нас есть еще одно условие if, которое очень озадачивает, потому что оно кажется ненужным и, опять же, имеет дело с адаптером. Затем у нас есть одна строка кода, которая (наконец) связана с абстракцией элементов фида и использует список, переданный в метод, за которым следует какой-то сильно закомментированный и малопонятный код более низкого уровня. Всего внутри этого метода всего одна строчка кода, напрямую связанная с уровнем абстракции, указанным в его названии. Грязный.

            Вот что у меня получилось после рефакторинга по SLAP:

             private fun showFeedItems(list: List?) {
                    обеспечитьFeedUiInitialized()
                    bindFeedItemsToAdapter (список ?: пустой список ())
                    отчетFullyDrawnAfterFeedItemsDrawn()
                }
                приватное развлечение
                    если (адаптер == ноль) {
                        val viewBinders = инициализироватьViewBinders()
                        адаптер = FeedAdapter (viewBinders)
                    }
                    если (recyclerView. adapter == ноль) {
                        recyclerView.adapter = адаптер
                    }
                }
                частная забава initializeViewBinders () {
                    val sectionHeaderViewBinder = FeedSectionHeaderViewBinder()
                    val countdownViewBinder = CountdownViewBinder()
                    val momentViewBinder = MomentViewBinder(
                        прослушиватель событий = модель,
                        информация о пользователе = модель.Информация о пользователе,
                        тема = модель.тема
                    )
                    val sessionViewBinder = FeedSessionsViewBinder(модель)
                    val feedAnnouncementsHeaderViewBinder =
                        ОбъявленияHeaderViewBinder(это, модель)
                    val обьявлениеViewBinder = AnnouncementViewBinder(model.timeZoneId, это)
                    val аннонсемптивиевбиндер = аннонсментсэмптивиевбиндер()
                    val-announcementsLoadingViewBinder = AnnouncementsLoadingViewBinder()
                    val feedSustainabilitySectionViewBinder = FeedSustainabilitySectionViewBinder()
                    val feedSocialChannelsSectionViewBinder = FeedSocialChannelsSectionViewBinder()
                    @Suppress("НЕПРОВЕРЕННЫЙ_КАСТ")
                    val viewBinders = ImmutableMap. builder()
                        .помещать(
                            sectionHeaderViewBinder.modelClass,
                            sectionHeaderViewBinder как FeedItemBinder
                        )
                        .помещать(
                            обратный отсчетViewBinder.modelClass,
                            countdownViewBinder как FeedItemBinder
                        )
                        .помещать(
                            моментViewBinder.modelClass,
                            momentViewBinder как FeedItemBinder
                        )
                        .помещать(
                            сеансыViewBinder.modelClass,
                            sessionViewBinder как FeedItemBinder
                        )
                        .помещать(
                            каналобъявленийHeaderViewBinder.modelClass,
                            feedAnnouncementsHeaderViewBinder как FeedItemBinder
                        )
                        .помещать(
                            объявлениеViewBinder.modelClass,
                            объявлениеViewBinder как FeedItemBinder
                        )
                        .помещать(
                            объявленияEmptyViewBinder.modelClass,
                            объявленияEmptyViewBinder как FeedItemBinder
                        )
                        . помещать(
                            объявленияLoadingViewBinder.modelClass,
                            объявленияLoadingViewBinder как FeedItemBinder
                        )
                        .помещать(
                            feedSustainabilitySectionViewBinder.modelClass,
                            feedSustainabilitySectionViewBinder как FeedItemBinder
                        )
                        .помещать(
                            feedSocialChannelsSectionViewBinder.modelClass,
                            feedSocialChannelsSectionViewBinder как FeedItemBinder
                        )
                        .строить()
                    вернуть viewBinders
                }
                частное развлечение bindFeedItemsToAdapter(feedItems: List) {
                    (binding.recyclerView.adapter as FeedAdapter).submitList(feedItems)
                }
                частный отчет о развлеченияхFullyDrawnAfterFeedItemsDrawn() {
                    // После отправки списка в адаптер представление переработчика начинает измерение и рисование
                    // поэтому давайте подождем, пока макет будет отрисован, прежде чем сообщать о полной отрисовке.
                    привязка.recyclerView.doOnLayout {
                        // reportFullyDrawn() печатает `I/ActivityTaskManager: Полностью нарисовано {активность} {время}`
                        // в логкэт.  Платформа гарантирует, что оператор печатается только один раз за
                        // активности, поэтому нет необходимости добавлять в приложение логику дедупликации.
                        активность?.reportFullyDrawn()
                    }
                } 

            После этого рефакторинга становится очень ясно, что происходит, когда мы хотим показать элементы ленты. Большая часть кода теперь находится внутри метода, в котором четко указано, что он имеет дело с абстракцией «привязки представлений», поэтому вы можете пропустить его при чтении кода, если вас не интересует такой уровень детализации. Обратите внимание, что этот метод initializeViewBinders по-прежнему относительно длинный, но это совершенно нормально, поскольку он имеет дело только с одним уровнем абстракции. Разделение этого метода на самом деле не имело бы смысла, потому что это привело бы к фрагментации композиции 9.0087 Сопоставить структуру данных без усиления. Следовательно, следование SLAP в этом случае автоматически создает оптимальный код.

            Как и прежде, для протокола скажу, что код после рефакторинга все еще не чист. Опытные разработчики Android заметят, что то, как они работают с адаптером, бессмысленно, и в коде есть ненужные типы, допускающие значение NULL, но ничего из этого не связано с SLAP.

            Заключение

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

            Преимущества SLAP становятся еще более очевидными при рефакторинге унаследованного кода, поскольку SLAP помогает вам выполнять множество небольших поэтапных рефакторингов, которые вы можете легко реализовать. Эти небольшие шаги со временем приведут к сложному проценту и могут превратиться в серьезные архитектурные улучшения.

            Поскольку «абстракции» в вашем коде не определены точно, SLAP не является точной наукой.

            About the Author

            Добавить комментарий

            Ваш адрес email не будет опубликован. Обязательные поля помечены *

            Related Posts