К основному содержанию
правило официальный · GitHub

oop-design-patterns — правило для GitHub Copilot: паттерны GoF и SOLID

Правило для GitHub Copilot, которое подталкивает его к паттернам GoF и принципам SOLID при генерации и рефакторинге ООП-кода.

Установить в GitHub Copilot · Вручную: положить файлы Все способы и платформы ↓
.github/instructions/oop-design-patterns.instructions.md
Открыть на GitHub

Что делает oop-design-patterns

Файл описывает, как Copilot должен выбирать паттерны проектирования. Внутри — четыре принципа архитектуры: программировать под интерфейс, а не под реализацию, предпочитать композицию наследованию, изолировать то, что меняется, и держать классы слабо связанными. Дальше идут три группы паттернов GoF с пояснением, когда каждый уместен: порождающие (Abstract Factory, Factory Method, Builder, Singleton, Prototype), структурные (Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy) и поведенческие (Strategy, Observer, Command, State, Template Method, Chain of Responsibility, Mediator, Iterator, Visitor, Memento).

Отдельный блок задаёт правила генерации кода. Copilot должен сначала писать интерфейс или абстрактный базовый класс, а уже потом реализации, помечать поля private по умолчанию и называть классы так, чтобы из имени читался паттерн — например, TaxCalculationStrategy или WidgetFactory. Singleton разрешён только там, где действительно нужен единственный экземпляр, и вместо него советуют внедрение зависимостей. Крупные классы правило велит разбивать на части и связывать их через Mediator или Strategy.

Правило подключается через applyTo и срабатывает на файлах **/*.py, **/*.java, **/*.ts, **/*.js, **/*.cs. Если ваш проект на другом языке, оно просто не подхватится — это повод проверить маску перед тем, как ждать изменений в подсказках. Текст инструкции обрезан на принципе подстановки Лисков, так что полного разбора SOLID в файле может не оказаться.

Какие задачи решает

  • выбрать паттерн под задачу создания объектов
  • убрать длинные цепочки if-else через Strategy
  • разбить разросшийся класс на несколько связанных
  • сделать поля закрытыми и добавить неизменяемость
  • отвязать отправителя запроса от получателя

Примеры запросов агенту

  • Подбери паттерн для расчёта налогов разными способами и объясни выбор в комментарии
  • Отрефактори этот класс: сначала интерфейс, потом реализации
  • Мне нужна отмена последнего действия — какой паттерн GoF тут подойдёт?

Как установить oop-design-patterns

Вручную: положить файлы

.github/instructions/oop-design-patterns.instructions.md

Поле applyTo задаёт, к каким файлам применять

По шагам, с командами для каждой платформы: AGENTS.md и CLAUDE.md: что это, кто читает и какой выбрать

Вопросы о oop-design-patterns

Как установить oop-design-patterns в GitHub Copilot?

Положите файл по пути .github/instructions/oop-design-patterns.instructions.md в репозитории — Copilot подхватит его как инструкцию.

Что делает oop-design-patterns?

Настраивает GitHub Copilot на паттерны GoF и принципы SOLID: подсказывает, какой паттерн применить, требует сначала интерфейс, а потом реализацию, и ограничивает использование Singleton.

На каких файлах работает это правило?

Маска applyTo покрывает **/*.py, **/*.java, **/*.ts, **/*.js и **/*.cs. Для файлов других расширений правило не сработает.

Исходный текст

oop-design-patterns.instructions.md · MIT
---
description: 'Best practices for applying Object-Oriented Programming (OOP) design patterns, including Gang of Four (GoF) patterns and SOLID principles, to ensure clean, maintainable, and scalable code.'
applyTo: '**/*.py, **/*.java, **/*.ts, **/*.js, **/*.cs'
---


# Design Patterns for Object-Oriented Programming for Clean Code

These instructions configure GitHub Copilot to prioritize Gang of Four (GoF) Design Patterns, SOLID principles, and clean Object-Oriented Programming (OOP) practices when generating or refactoring code.

## Core Architectural Philosophy

- **Program to an Interface, not an Implementation:** Always favor abstract classes or interfaces over concrete implementations. Use dependency injection to provide concrete instances.
- **Favor Object Composition over Class Inheritance:** Use composition to combine behaviors dynamically at runtime. Avoid deep inheritance trees. Use Delegation where appropriate to reuse behavior without breaking encapsulation.
- **Encapsulate What Varies:** Identify the aspects of the application that vary and separate them from what stays the same. Use patterns like Strategy, State, or Bridge to isolate these variations.
- **Loose Coupling:** Minimize direct dependencies between classes. Use Mediator, Observer, or abstract factories to keep components decoupled.

## Creational Patterns Guidelines

When generating code that involves object creation or instantiation, apply these patterns to decouple the system from how its objects are created:

- **Abstract Factory:** Use when a system must be configured with one of multiple families of related products (e.g., cross-platform UI widgets). Ensure clients only interact with the abstract factory and abstract product interfaces.
- **Factory Method:** Use when a class cannot anticipate the class of objects it must create. Defer instantiation to subclasses.
- **Builder:** Use when constructing a complex object requires a step-by-step process, especially when the same construction process can yield different representations.
- **Singleton:** Use *only* when absolutely necessary to guarantee a single instance of a class and provide a global access point (e.g., a central configuration manager or a hardware interface). Prefer Dependency Injection over strict Singletons where possible.
- **Prototype:** Use to avoid building a class hierarchy of factories or when creating an object from scratch is more expensive than cloning an existing one.

## Structural Patterns Guidelines

When generating code that defines how classes and objects are composed to form larger structures, apply these patterns:

- **Adapter:** Use to make incompatible interfaces work together. Prefer Object Adapters (using composition) over Class Adapters (using multiple inheritance) for greater flexibility.
- **Bridge:** Use to separate an abstraction from its implementation so the two can vary independently (e.g., separating a high-level `Window` concept from platform-specific `WindowImpl` logic).
- **Composite:** Use to represent part-whole hierarchies. Ensure clients can treat individual objects and compositions of objects uniformly via a common `Component` interface.
- **Decorator:** Use to attach additional responsibilities to an object dynamically. Prefer this over subclassing for extending functionality to prevent class explosion. Ensure the Decorator has the exact same interface as the component it decorates.
- **Facade:** Use to provide a simple, unified interface to a complex subsystem.
- **Flyweight:** Use to minimize memory usage or computational expenses by sharing as much as possible with similar objects.
- **Proxy:** Use to provide a surrogate or placeholder for another object to control access to it (e.g., lazy loading, access control, or remote communication).

## Behavioral Patterns Guidelines

When generating code involving algorithms, control flow, or communication between objects, apply these patterns:

- **Strategy:** Use to define a family of algorithms, encapsulate each one, and make them interchangeable. Eliminate complex conditional logic (`switch`/`if-else`) that selects behavior by delegating to a Strategy object.
- **Observer:** Use to define a one-to-many dependency where a change in one object (Subject) automatically notifies and updates others (Observers). Keep subjects and observers loosely coupled.
- **Command:** Use to encapsulate a request as an object. This is essential for implementing undo/redo functionality, queues, or logging requests.
- **State:** Use when an object's behavior depends heavily on its internal state, and it must change its behavior at runtime. Represent each state as a separate class.
- **Template Method:** Use to define the skeleton of an algorithm in a base class, deferring specific steps to subclasses without changing the algorithm's structure.
- **Chain of Responsibility:** Use to pass a request along a chain of potential handlers until one handles it, avoiding coupling the sender to a specific receiver.
- **Mediator:** Use to centralize complex communications and control logic between a set of objects, keeping them from referring to each other explicitly.
- **Iterator:** Use to provide a standard way to sequentially access elements of an aggregate object without exposing its underlying representation.
- **Visitor:** Use to define a new operation on an object structure without changing the classes of the elements on which it operates. This is highly effective for performing different analyses on stable composite structures (like Abstract Syntax Trees).
- **Memento:** Use to capture and externalize an object's internal state without violating encapsulation, allowing the object to be restored later (useful for complex Undo mechanisms).

## Code Generation Rules for Copilot

- **Pattern Recognition:** When prompted to solve a problem that maps to a GoF pattern (e.g., "I need a way to undo this action", "I have multiple ways to calculate taxes"), explicitly mention the pattern you are applying in comments.
- **Interface First:** Generate the interface or abstract base class *before* generating concrete implementations.
- **Immutability & Encapsulation:** Make fields `private` by default. Provide getters/setters only when necessary. Favor immutable objects.
- **Naming Conventions:** Use pattern names in class names where it aids understanding (e.g., `TaxCalculationStrategy`, `ButtonDecorator`, `WidgetFactory`), but keep names natural to the domain when appropriate.
- **Avoid God Classes:** Break large, complex classes into smaller, focused classes coordinating via a Mediator or composed of smaller Strategy objects.
- **Single Responsibility Principle:** Ensure each class has only one reason to change. If a class is doing too much, refactor it into multiple classes.
- **Open/Closed Principle:** Design classes to be open for extension but closed for modification. Use abstract classes or interfaces to allow new behavior without changing existing code.
- **Liskov Substitution Principle:** Ensure that subclasses can be substituted for their base classes without altering the correctness of the program. Avoid violating this principle by ensuring that derived classes do not strengthen preconditions or weaken postconditions.
- **Interface Segregation Principle:** Prefer many specific interfaces over a single general-purpose interface. Clients should not be forced to depend on interfaces they do not use.
- **Dependency Inversion Principle:** Depend on abstractions, not on concretions. High-level modules should not depend on low-level modules; both should depend on abstractions.
- **Use Design Patterns Judiciously:** Apply patterns when they solve a real problem in the codebase. Avoid over-engineering by applying patterns only when they provide clear benefits in terms of maintainability, flexibility, or readability.
- **Document Intent:** When using a design pattern, include comments that explain why the pattern was chosen and how it is being applied. This helps future maintainers understand the rationale behind the design decisions.
- **Testability:** Ensure that the generated code is testable. Use patterns that facilitate unit testing (e.g., Dependency Injection for easier mocking). Write tests that verify the behavior of the patterns in use.
- **Refactor Iteratively:** When refactoring existing code to apply design patterns, do so iteratively. Start with small, incremental changes that improve the design without introducing bugs. Use tests to verify that behavior remains correct throughout the refactoring process.
- **Performance Considerations:** Be mindful of the performance implications of design patterns. Some patterns may introduce additional layers of abstraction that can impact performance. Use profiling tools to identify bottlenecks and optimize as necessary without sacrificing maintainability.
- **Consistency:** Apply design patterns consistently across the codebase. If a particular pattern is used in one part of the code, consider using it in similar situations elsewhere to maintain a consistent design language.
- **Review and Iterate:** Regularly review the codebase for opportunities to apply design patterns or refactor existing code to better adhere to OOP principles. Encourage code reviews that focus on design quality and adherence to these guidelines.
- **Stay Updated:** Keep up with the latest developments in OOP design patterns and best practices. Continuously learn and adapt your coding style to incorporate new insights and techniques that can improve the quality of your codebase.
- **Balance Simplicity and Flexibility:** While design patterns can provide powerful solutions, they can also add complexity. Strive for a balance between simplicity and flexibility, ensuring that the code remains easy to understand and maintain while still being adaptable to future changes. Favor function definition over class definition when the problem can be solved with a simple function, and use classes and patterns when they provide clear organizational benefits.
- **Use Repositories and Typing definitions:** When generating code that involves complex data structures or interactions, consider using repositories to abstract data access and typing definitions to ensure type safety and clarity in the codebase. This can help maintain a clean separation of concerns and improve the overall maintainability of the code.

## Logging and Error Handling

- When applying design patterns, ensure that logging and error handling are integrated appropriately.
- Fail safe, loud, clear and early.
- Avoid silent failures and ensure that errors are logged with sufficient context to facilitate debugging and maintenance.
- Use custom exceptions where appropriate to provide more meaningful error messages and to allow for more granular error handling in client code.
- Use exception blocks judiciously, ensuring that they are used to handle expected error conditions rather than to control normal program flow.
- Use logging frameworks to manage log levels and outputs, allowing for better control over the logging behavior in different environments (e.g., development vs. production).
- Use info, debug, warning, error and critical log levels appropriately in every class and function to provide clear insights into the application's behavior and potential issues. Consider implementing a centralized error handling mechanism (e.g., a global exception handler) to ensure consistent error responses and logging across the application.

## Documentation

- When applying design patterns, ensure that the code is well-documented.
- Use docstrings written in English to explain the purpose of classes and methods, and include comments that clarify complex logic or design decisions. Use the numpy pattern for documenting the parameters and returns in the docstring unless another pattern is used in the existing code. Ask the developer at the first usage of this instruction which kind of docstring parameter and return he prefers, override the numpy docstring definition here and use this kind of docstring for all later programming tasks. This helps other developers understand the intent behind the code and how to use it effectively.
- Consider using tools like Sphinx or JSDoc to generate documentation from your codebase, making it easier for developers to navigate and understand the available classes, methods, and their intended usage.
- Additionally, maintain a high-level architectural overview in a README or dedicated documentation file that explains how different components and patterns fit together within the overall system architecture.
- Divide your documentation into user documentation (how to use the code) and developer documentation (how the code works and how to maintain it). Ensure that both types of documentation are kept up-to-date as the code evolves.
- Use diagrams (e.g., UML) where appropriate to visually represent the relationships between classes and patterns, aiding in comprehension for developers who may be new to OOP design patterns.
- Encourage a culture of documentation within the development team, emphasizing its importance for maintaining a clean and maintainable codebase.
- Never explode in documentation by creating constantly new documentation files which contain the same content.
- Scan existing doc files to extend them or to build new required doc sheets in the same style as existing ones. Keep it concise, clear and focused on the most important aspects of the code and its design patterns.
- Avoid redundant or overly verbose documentation that can overwhelm developers and obscure the key information they need to understand the codebase effectively.

© github · MIT · github/awesome-copilot

Похожие правила IDE

Всё по теме «Код-ревью и рефакторинг» →

Из того же набора732

Весь набор →
pcf-tooling Правило подсказывает Copilot, что для сборки, отладки и деплоя код-компонентов нужен Microsoft Power Platform CLI. ★ 40 418звёзд репо pcf-manifest-schema Правило подсказывает Copilot структуру ControlManifest.Input.xml: какие элементы и атрибуты бывают и что они делают. Пригодится, когда правишь манифест PCF-компонента. ★ 40 418звёзд репо pcf-events Правило подсказывает Copilot, как объявлять и обрабатывать кастомные события в компонентах Power Apps Component Framework. ★ 40 418звёзд репо pcf-code-components Правило объясняет Copilot, как устроены code components в Power Apps component framework: манифест, реализация, ресурсы. Пригодится, когда правите ControlManifest.Input.xml или index.ts. ★ 40 418звёзд репо no-heredoc Правило запрещает агенту писать файлы через heredoc и перенаправления в терминале, потому что в VS Code такие команды портят содержимое. ★ 40 418звёзд репо nestjs Правило подключает к GitHub Copilot набор стандартов NestJS: модули, DI, DTO и валидация. Пригодится, когда агент пишет серверный код на TypeScript. ★ 40 418звёзд репо moodle Правило задаёт Copilot стандарты Moodle: Frankenstyle-неймспейсы, Mustache-шаблоны, обязательные функции безопасности. Пригодится, если пишете плагины и темы. ★ 40 418звёзд репо langchain-python Правило для GitHub Copilot, которое подсказывает агенту паттерны LangChain: Runnable, LCEL, чат-модели, ретриверы и векторные хранилища. Пригодится, если вы пишете на Python с LangChain. ★ 40 418звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой