Принцип разделения интерфейса || Interface Segregation Principle

Поділитися
Вставка
  • Опубліковано 14 гру 2024

КОМЕНТАРІ • 42

  • @vaniysha1992
    @vaniysha1992 2 роки тому

    -Кто мы?
    - К кому ты обращаешься?
    - Я один здесь на..!
    Всегда вспоминаю Зелёного Слоника после просмотра практически любого видео))
    За сам материал спасибо, довольно доходчиво!

  • @aleksandrzelenskiy4000
    @aleksandrzelenskiy4000 3 роки тому +3

    Интересно и понятно, спасибо! Когда новые выпуски?

    • @it-sin9k
      @it-sin9k  3 роки тому +1

      Спасибо :)
      вот сейчас напишу анонс текстовый, что во вторник будет новый выпуск)

  • @mykhailostepanishchev6472
    @mykhailostepanishchev6472 3 роки тому +3

    Очень интересно,спасибо !

  • @antiquis_philosophia
    @antiquis_philosophia Рік тому

    Спасибо😊

  • @dinaltGoth
    @dinaltGoth 3 роки тому +3

    Очень хорошая подача 👍

    • @it-sin9k
      @it-sin9k  3 роки тому +1

      спасибо!)
      все во имя сообщества)

  • @hihoho1578
    @hihoho1578 4 роки тому +1

    Благодарю за работу)

    • @it-sin9k
      @it-sin9k  4 роки тому

      Спасибо :) рады стараться!

  • @-X-Ray-
    @-X-Ray- 4 роки тому +1

    Спасибо, как раз начинаю работать с TS :)

    • @it-sin9k
      @it-sin9k  4 роки тому

      Мы как раз следующее видео готовили связанное плотно с TS)

    • @-X-Ray-
      @-X-Ray- 4 роки тому

      @@it-sin9k с нетерпением жду)

  • @БатырбекАйгалиев
    @БатырбекАйгалиев 4 роки тому +9

    Спасибо за видео! Не знаю, связано это или нет, но после этого видео разработчики moment.js заявили о прекращении разработки новых фич и советуют использовать другие похожие пакеты)

    • @it-sin9k
      @it-sin9k  4 роки тому +4

      ахах) не думаю, что это связано) но moment.js действительно лучше не использовать)

  • @Quentinrei
    @Quentinrei Рік тому

    👏👏👏👏👏👏

  • @sergey_llal6897
    @sergey_llal6897 2 роки тому

    Лайк + коммент )

  • @dm.hol.3624
    @dm.hol.3624 3 роки тому +1

    спасибо посоны

  • @dimitro.cardellini
    @dimitro.cardellini 2 роки тому

    Привет.
    Как всегда, отличная подача материала.
    Но! Но вот по ISP ... все не так. Ключевая проблема в видео -- это подмена "зависит" на "реализует". Зависит -- это значит использует (вызывает, читает и т.п.). Реализует -- это значит предоставляет то, что может быть использовано.
    Если посмотреть на определение ISP, то там ничего про реализацию нет, там -- про зависимость.
    И объяснить это лучше не на примере User, Landlord и Admin (Где разделение -- это классический пример SRP.), а скорее на примере Readable, Writable.
    Допустим, у нас есть необходимость писать и читать в стор. Объявим два интерфейса:
    export interface ReadableStore {
    read(): Promise;
    }
    export interface WritableStore {
    write(value: T): Promise;
    }
    при этом у нас есть IndexDB, где мы хотим хранить наши данные.
    для реализации мы делаем один класс, который имплементирует оба интерфейса:
    export class IndexDBStore implements ReadableStore, WritableStore {
    ...
    }
    Далее, допустим, что у нас есть задача, в которой нам надо прочитать некую строку из стора и отправить ее по апи на сервер:
    const readAndSend = async (store, api) => api.sendString(await store.read());
    Так вот ISP о том, какой тип должен быть у store. У нас есть три варианта:
    - IndexedDBStore
    - ReadableStore & WritableStore
    - ReadableStore
    Согласно ISP первые два варианта его нарушают, а вот третий "Readable" -- самое оно.
    При этом мы все так же можем вызвать readAndSend, передавая экземпляр IndexDBStore.
    Для чего это надо?
    Самое реальное и наглядное применение -- это unit-тесты.
    const store = {
    read: jest.fn();
    }
    const api = {
    sendString: jest.fn();
    }
    expect.assertions(3);
    store.read.mockResolvedValue('a stirng');
    api.sendString.mockResolvedValue(true);
    expect(await readAndSend(store)).toBe(true);
    expect(api.sendString).toHaveBeenCalledTimes(1);
    expect(api.sendString).toHaveBeenCalledWith('a string');
    Мы получили корректный с точки зрения TS код теста, и при этом не делали лишнего. В случае с Readable & Writable пришлось бы store в тесте объявить как:
    const store = {
    read: jest.fn(),
    write: jest.fn()
    };
    А в случае с IndexDBStore пришлось бы еще кучу всего добавлять (включая TS-приватные поля класса IndexDBStore).
    Вторая, более важная, но менее очевидная причина -- это изменения логики.
    В примере выше, мы видим только один метод api sendString, но вполне вероятно еще есть и sendNumber, sendDate и т.д:
    export interface Api {
    sendString(value: string): Promise;
    sendNumber(value: number): Promise;
    sendDate(value: Date): Promise;
    }
    И вот в один прекрасный момент выясняется, что теперь нам надо не просто отправлять все на сервер, а еще и выводить в консоль.
    Конечно, мы можем пойти в имплементацию api и там это поменять. Но если апи-клиент у нас был уже вынесен в отдельный пакет (библиотеку), и другие приложения, которые используют тот же api-клиент теперь тоже начнут спамить в консоль, чего бы никому не хотелось.
    Выход есть -- это декоратор или наследование. Но в обоих этих случаях для того, чтобы вызвать readAndSend, который принимает api: Api, нам надо реализовать все методы в нашей программе. А вот, если readAndSend в качестве api: Pick, то нам достаточно реализовать только один метод.
    Следующая причина -- это рефакторинг.
    Допустим однажды выясняется, что мы прекращаем поддержку функционала, который требовал отправку дат на сервер. Т.е. метод sendDate можно убрать. И казалось бы, все просто -- идем в реализацию и правим: и интерфейс, и реализацию.
    Но, здесь оказывается, что у нас есть код, который содержит дубликат интерфейса Api со всеми полями (когда-то кто-то вынес кусок бизнес-логики в пакет, и чтобы избавиться от зависимости от пакета api-клиентом определил интерфейс Api в этом новом пакете, просто скопировав его из api-клиента). В итоге, код с дубликатом Api теперь не работает, т.к. ему передают объект без метода sendDate (но который этому коду все равно не нужен).
    Здесь важно, что перенести определение интерфейса в новый пакет -- это было правильное решение (интерфейс принадлежит клиенту -- см. DIP), а вот сделать код, который будет требовать объект, реализующий весь интерфейс -- это как раз и было нарушением ISP.
    Понятное дело, что можно "кастануть к any", обманув Typescript, и все равно пробросить новый объект в старый код, но здесь мы стреляем себе в ногу, т.к. сразу отключаем кучу других проверок, которые делает TS.
    Sandbox с примером: codesandbox.io/s/naughty-feistel-kbptzf?file=/src/index.ts
    И да, все вышесказанное касается TypeScript. С JS такой проблемы не возникнет, т.к. остутствует статическая проверка типов, а зависимость проявляется только в рантайме и только от того, что так или иначе действительно используется. Для JS может быть более актуальным похожий (но отнюдь не тождественный) Закон Деметры (en.wikipedia.org/wiki/Law_of_Demeter).
    В нашем примере с Api и Store, было бы правильно сделать вот так:
    const readAndSend = async (read, sendString) => sendString(await read());

  • @rinat9685
    @rinat9685 4 роки тому +4

    Спасибо, очень полезно 😀

    • @it-sin9k
      @it-sin9k  4 роки тому

      Нас очень радуют такие комментарии)

  • @gerasim_vol
    @gerasim_vol 3 роки тому +2

    лол, голос на скорости х1.25 звучит более естественно, чем оригинал

    • @it-sin9k
      @it-sin9k  3 роки тому +2

      запись аудио дорожки это особый стресс для меня)
      очень тяжело мне дается)

  • @КириллИор
    @КириллИор 3 роки тому

    🙃

  • @denskorpi
    @denskorpi 4 роки тому +1

    Спасибо за видос! По стилю подачи материала вдохновлялся каналом MyGap? )

    • @it-sin9k
      @it-sin9k  4 роки тому +3

      Прям на 100% в точку) когда обсуждали формат канала, MyGap взяли за основу и на базе этого уже рисовали что-то свое) Но сразу мы нарисовали просто мужика с бородой, а потом обсуждали, что скучно будет и придумали абстрактного персонажа)

    • @it-sin9k
      @it-sin9k  3 роки тому

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

    • @it-sin9k
      @it-sin9k  3 роки тому

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

  • @mnik0128
    @mnik0128 3 роки тому

    03:32 на скрине слева ошибка. Нужно было указать что тип Array а не так как указано на видео. На видео показывается что массив юзеров имеет тип либо админ либо квартирант etc

    • @it-sin9k
      @it-sin9k  3 роки тому +1

      ты абсолютно прав) я набросал это не тестируя, а потом увидел косяк, только после публикации видео) лайк за внимательность)

    • @srjoyme2525
      @srjoyme2525 2 роки тому

      @@it-sin9k а то что объединение интерфейсов идёт, а не типов никого не смутило?))

  • @AndriiKuftachov
    @AndriiKuftachov 3 роки тому

    В Go этот принцип доведён до совершенства!

  • @МаксимНырков-у6г

    О, ты из Минска?)

    • @it-sin9k
      @it-sin9k  Рік тому

      Да :)

    • @МаксимНырков-у6г
      @МаксимНырков-у6г Рік тому

      @@it-sin9k кайф, я тоже! не эмигрировал еще?)
      тут так пустовато чутка стало без айтишечки

    • @it-sin9k
      @it-sin9k  Рік тому

      В данный момент тоже уехал :)

  • @qutbiddinmakhmudov4088
    @qutbiddinmakhmudov4088 3 роки тому

    Надо коммент написать

    • @it-sin9k
      @it-sin9k  3 роки тому

      Это правильно!) комментарий надо всегда писать)

  • @koryunsirunyan3096
    @koryunsirunyan3096 2 роки тому

    У вас есть патреон?

    • @it-sin9k
      @it-sin9k  2 роки тому

      Поддержать нас финансово можно по следующим ссылка:
      UA-cam: ua-cam.com/channels/lgj-KWiNaOo9H1rz1ISO6Q.htmljoin
      boosty: boosty.to/sin9k
      Patreon: www.patreon.com/ITSin9k

  • @ТвойМаршрут
    @ТвойМаршрут 3 роки тому

    CRP instead of CPR

  • @iamgoingbetter6044
    @iamgoingbetter6044 2 роки тому

    Формат ~8-ми хвилин досить комфортний.

    • @it-sin9k
      @it-sin9k  2 роки тому +1

      Так и задумывалось!) длинные видео тяжело решиться смотреть)