← Назад к вопросам

Что такое Interface Agregation?

1.0 Junior🔥 191 комментариев
#TypeScript#Архитектура и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Interface Segregation Principle — один из пяти SOLID принципов

Interface Segregation Principle (ISP) — это принцип проектирования, который гласит: "Клиенты не должны зависеть от интерфейсов, которые они не используют". Иными словами, лучше иметь много специализированных интерфейсов, чем один большой универсальный интерфейс.

Проблема без ISP

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

// ПЛОХО - слишком большой интерфейс
interface User {
  name: string;
  email: string;
  // Методы для разных ролей
  approvePost(): void;      // Только модератор
  publishArticle(): void;    // Только автор
  manageBilling(): void;     // Только администратор
  editProfile(): void;       // Все пользователи
}

// Обычный пользователь не должен иметь методы для модерации
const regularUser: User = {
  name: "John",
  email: "john@example.com",
  approvePost: () => {}, // Не нужно!
  publishArticle: () => {}, // Не нужно!
  manageBilling: () => {}, // Не нужно!
  editProfile: () => {}
};

Решение с ISP

Разделите большой интерфейс на маленькие, специализированные интерфейсы:

// ХОРОШО - специализированные интерфейсы
interface User {
  name: string;
  email: string;
  editProfile(): void;
}

interface Moderator extends User {
  approvePost(): void;
  rejectPost(): void;
}

interface Author extends User {
  publishArticle(): void;
  editArticle(id: string): void;
}

interface Admin extends User {
  manageBilling(): void;
  manageUsers(): void;
  deleteContent(id: string): void;
}

// Теперь каждый класс реализует только необходимые интерфейсы
class RegularUser implements User {
  name: string = "John";
  email: string = "john@example.com";
  
  editProfile() {
    console.log("Editing profile");
  }
}

class BlogAuthor implements Author {
  name: string = "Jane";
  email: string = "jane@example.com";
  
  editProfile() {
    console.log("Editing profile");
  }
  
  publishArticle() {
    console.log("Publishing article");
  }
  
  editArticle(id: string) {
    console.log(`Editing article ${id}`);
  }
}

Пример в React

Interface Segregation часто встречается в React при работе с компонентами и их Props:

// ПЛОХО - один большой Props интерфейс
interface ButtonProps {
  label: string;
  onClick: () => void;
  disabled?: boolean;
  loading?: boolean;
  icon?: React.ReactNode;
  size?: 'sm' | 'md' | 'lg';
  variant?: 'primary' | 'secondary';
  onHover?: () => void;
  onBlur?: () => void;
  className?: string;
  tooltip?: string;
}

// ХОРОШО - специализированные интерфейсы
interface BaseButtonProps {
  label: string;
  onClick: () => void;
  disabled?: boolean;
}

interface StyledButtonProps extends BaseButtonProps {
  size?: 'sm' | 'md' | 'lg';
  variant?: 'primary' | 'secondary';
  className?: string;
}

interface EnhancedButtonProps extends StyledButtonProps {
  loading?: boolean;
  icon?: React.ReactNode;
  tooltip?: string;
}

function SimpleButton(props: BaseButtonProps) {
  return <button onClick={props.onClick}>{props.label}</button>;
}

function StyledButton(props: StyledButtonProps) {
  return (
    <button className={`btn btn-${props.size} btn-${props.variant}`}>
      {props.label}
    </button>
  );
}

Преимущества ISP

  • Гибкость: Компоненты зависят только от того, что им нужно
  • Переиспользуемость: Интерфейсы легче комбинировать
  • Тестируемость: Проще создавать моки для маленьких интерфейсов
  • Читаемость: Понятнее, что делает каждый интерфейс
  • Поддерживаемость: Изменения в одном интерфейсе не влияют на другие

Ключевой принцип

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