Pull to refresh
2
0
Send message

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

Это навряд ли

А вообще мой посыл в том, что не надо лепить интерфейсы и абстракции просто потому, что в умных книжках так написано.
Абстракции должны изолировать потенциальные точки отказа приложения и обобщать взаимодействие с множеством реализаций. Кстати про умные книжки, давече читал "Эволюционная архитектура" и там как раз было про соотношение абстракций к реализациям - у авторов мнение (там есть какая-то формула для подсчета этого добра), что ок это примерно 1:3-1:4 соответственно, с чем я вообщем-то согласен.
А пилить интерфесы вроде IUserService и IUserRepository ну максимально бессмысленно - других реализаций для них (почти 100%) не будет, поэтому смысла скрывать реализацию нет; смене контракта интерфейс не помешает; это даже не абстракция, просто интерфейс ради интерфейса

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

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

С вашим стеком не работал, но расскажу как решали некоторые подобные проблемы у себя:

  1. Отображение диаграмм: мы рендерили диаграммы в png в GitHub actions.

  2. Ссылки: вообще документы должны ссылаться на соответствующий документ в репо, а не на воображаемый в Hugo. На нашем стеке ссылки автоматически преобразовывались плагином в пайплайне при переливке в базу знаний.

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

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

  5. Про gitea ничего не знаю, но гитхаб и ide нормально отображают документы в md и asciidoc, поэтому чаще всего никакие Hugo в целом не нужны были, только для смежников (у нас была интеграция в confluence увы ныне почившая).

  6. Поломки сборки: при создании ПРа должна проводиться автоматическая упрощенная версия сборки в ci/cd. Если не собралось - ПР блокируется.

я большой сторонник doc as a code, при нормальном ci/cd и адекватных разработчиках и аналитиках документация получается супер, хотя конечно не панацея и испортить можно все что угодно.

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

// list.tsx
export const List = ({ className, children }): JSX.Element => (
  <ul className={ className }>
    { children }
  </ul>
);

// list-item.tsx
export const ListItem = ({ user }): JSX.Element => (
  <li className={ className }>
    { children }
  </li>
);

// fullname.tsx
export const FullName = ({ surname, name, patronymic }): JSX.Element => {
  const fullName = `
    {name} 
    {patronymic ?? ''} 
    {surname}
  `.toLowerCase();
  
  return (
    <span>
      { fullName }
    </span>
  );
};

// date.tsx
export const Date = ({ date }): JSX.Element | null => {
  if (!date) {
    return null;
  }
  
  return (
    <span>
      { moment(date) }
    </span>
  );
};

// status.tsx
import styles from './status.modules';

enum ColorByStatus = {
  'В сети': styles.statusOnline, 
  'Не в сети': styles.statusOffline,
};

export const Status = ({ description }): JSX.Element | null => (
  <span className={ ColorByStatus[description] ?? styles.statusDefault }>
    { description }
  </span>
);

// user-list.tsx
export const UserList = (users): JSX.Elemet => {
  return (
    <List className="user-list">
      {
        users.map(({ surname, name, patronymic, regestrationDate, status }) => (
          <FullName
            surname={ surname }
            name={ name }
            patronymic={ patronymic }
          />
          <Date date={ regestrationDate } />
          <Status description={ status.description } />
        )) 
      }
    </List>
  );  
};







rxjs помогает добавить реактивность в обычные ts-классы, сервисы, репозитории и тп...можно конечно событийные шины лепить на колбэках, свою реализацию observable написать на проксе - дело вкуса, но ИМХО оно того не стоит. Хотя у rxjs есть свои проблемы.

Вы сделали пол-шага к Clean Architecture. Я бы добавил inversifyjs для менеджмента зависимостей и заменил vuex на rxjs.

По всей видимости таким образом разгоняет читателей до сверхсветовой без применения экзотической физики ) только старый добрый реактив)

Сомневаюсь, что много реакт-разработчиков хорошо понимаю как работают те же хуки, проброс контекста и прочий подобный функционал прикрытый сахаром и магией. Тоже касается vue и composition api.

Information

Rating
Does not participate
Registered
Activity