Skip to main content

awesome-software-design-patterns

Curated guide for implementing design patterns, architecture decisions, and verified design rules in software projects

Ir a la instalación

Datos de origen

Repositorio
reason-machines/design-skills
Última actividad en el origen
17 de mayo de 2026 a las 12:49
Idioma detectado de SKILL.md
inglés
Estrellas
4
Forks
0

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
awesome-software-design-patterns
description
Curated guide for implementing design patterns, architecture decisions, and verified design rules in software projects
triggers
["show me design patterns for this problem","how do I document architecture decisions","what are the best practices for API design","help me implement clean architecture","show me examples of architecture verification","how do I create architecture diagrams as code","what design pattern should I use here","help me set up ADR documentation"]
# Awesome Software Design Patterns > Skill by [ara.so](https://ara.so) — Design Skills collection. A comprehensive resource for organizing and structuring software through proven design patterns, architecture decision records (ADRs), and automated verification rules. This skill helps you apply battle-tested design principles, document architectural decisions, and enforce design constraints through CI/CD. ## What This Resource Provides This curated collection covers: - **Implementation Patterns & Reference Code** - Production-ready examples of DDD, CQRS, Clean Architecture, Event Sourcing - **Design Patterns** - All 23 GoF patterns plus enterprise and architectural patterns - **API & Interface Design** - Industry-standard guidelines from Google, Microsoft - **Decision Records (ADR/RFC)** - Templates and real-world examples for documenting architecture decisions - **Documentation as Code** - C4 Model, Mermaid, PlantUML, and other diagram-as-code tools - **Architecture Verification** - CI-integrated tools for enforcing architecture rules (ArchUnit, Arkitect, etc.) - **Operational Case Studies** - Real-world architecture examples from Figma, Discord, Shopify, Stripe ## Key Design Patterns Reference ### Creational Patterns **Singleton Pattern** - Ensures a class has only one instance with global access: ```php // PHP Example class Database { private static ?Database $instance = null; private PDO $connection; private function __construct() { $this->connection = new PDO( $_ENV['DB_DSN'], $_ENV['DB_USER'], $_ENV['DB_PASS'] ); } public static function getInstance(): Database { if (self::$instance === null) { self::$instance = new Database(); } return self::$instance; } public function getConnection(): PDO { return $this->connection; } } // Usage $db = Database::getInstance(); ``` **Factory Pattern** - Creates objects without specifying exact classes: ```go // Go Example package notification type Notification interface { Send(message string) error } type EmailNotification struct { recipient string } func (e *EmailNotification) Send(message string) error { // Send email implementation return nil } type SMSNotification struct { phoneNumber string } func (s *SMSNotification) Send(message string) error { // Send SMS implementation return nil } type NotificationFactory struct{} func (f *NotificationFactory) Create(notifType, target string) Notification { switch notifType { case "email": return &EmailNotification{recipient: target} case "sms": return &SMSNotification{phoneNumber: target} default: return nil } } // Usage factory := &NotificationFactory{} notif := factory.Create("email", "user@example.com") notif.Send("Hello World") ``` **Builder Pattern** - Constructs complex objects step by step: ```go // Go Example package query type SQLQuery struct { table string columns []string where string orderBy string limit int } type QueryBuilder struct { query SQLQuery } func NewQueryBuilder(table string) *QueryBuilder { return &QueryBuilder{ query: SQLQuery{table: table, columns: []string{"*"}}, } } func (b *QueryBuilder) Select(columns ...string) *QueryBuilder { b.query.columns = columns return b } func (b *QueryBuilder) Where(condition string) *QueryBuilder { b.query.where = condition return b } func (b *QueryBuilder) OrderBy(field string) *QueryBuilder { b.query.orderBy = field return b } func (b *QueryBuilder) Limit(limit int) *QueryBuilder { b.query.limit = limit return b } func (b *QueryBuilder) Build() string { sql := "SELECT " + strings.Join(b.query.columns, ", ") + " FROM " + b.query.table if b.query.where != "" { sql += " WHERE " + b.query.where } if b.query.orderBy != "" { sql += " ORDER BY " + b.query.orderBy } if b.query.limit > 0 { sql += fmt.Sprintf(" LIMIT %d", b.query.limit) } return sql } // Usage query := NewQueryBuilder("users"). Select("id", "name", "email"). Where("age > 18"). OrderBy("created_at DESC"). Limit(10). Build() ``` ### Structural Patterns **Adapter Pattern** - Makes incompatible interfaces work together: ```php // PHP Example - Adapting legacy payment gateway to new interface interface PaymentGateway { public function processPayment(float $amount, string $currency): bool; } class LegacyPaymentService { public function pay(int $amountInCents, string $currencyCode): array { // Legacy payment logic return ['status' => 'success', 'transaction_id' => 'TXN123']; } } class PaymentAdapter implements PaymentGateway { private LegacyPaymentService $legacyService; public function __construct(LegacyPaymentService $legacyService) { $this->legacyService = $legacyService; } public function processPayment(float $amount, string $currency): bool { $amountInCents = (int)($amount * 100); $result = $this->legacyService->pay($amountInCents, $currency); return $result['status'] === 'success'; } } // Usage $legacy = new LegacyPaymentService(); $adapter = new PaymentAdapter($legacy); $success = $adapter->processPayment(99.99, 'USD'); ``` **Decorator Pattern** - Adds behavior to objects dynamically: ```go // Go Example package middleware type Handler interface { Handle(request string) string } type BaseHandler struct{} func (h *BaseHandler) Handle(request string) string { return "Handling: " + request } type LoggingDecorator struct { handler Handler } func (d *LoggingDecorator) Handle(request string) string { log.Printf("Before handling: %s", request) result := d.handler.Handle(request) log.Printf("After handling: %s", result) return result } type AuthDecorator struct { handler Handler } func (d *AuthDecorator) Handle(request string) string { if !isAuthenticated(request) { return "Unauthorized" } return d.handler.Handle(request) } // Usage - Stack decorators handler := &BaseHandler{} handler = &LoggingDecorator{handler: handler} handler = &AuthDecorator{handler: handler} result := handler.Handle("user-request") ``` ### Behavioral Patterns **Strategy Pattern** - Defines a family of algorithms and makes them interchangeable: ```php // PHP Example - Different pricing strategies interface PricingStrategy { public function calculate(float $basePrice): float; } class RegularPricing implements PricingStrategy { public function calculate(float $basePrice): float { return $basePrice; } } class SeasonalDiscount implements PricingStrategy { private float $discountPercent; public function __construct(float $discountPercent) { $this->discountPercent = $discountPercent; } public function calculate(float $basePrice): float { return $basePrice * (1 - $this->discountPercent / 100); } } class VIPPricing implements PricingStrategy { public function calculate(float $basePrice): float { return $basePrice * 0.80; // 20% off } } class Product { private float $basePrice; private PricingStrategy $pricingStrategy; public function __construct(float $basePrice, PricingStrategy $strategy) { $this->basePrice = $basePrice; $this->pricingStrategy = $strategy; } public function setStrategy(PricingStrategy $strategy): void { $this->pricingStrategy = $strategy; } public function getPrice(): float { return $this->pricingStrategy->calculate($this->basePrice); } } // Usage $product = new Product(100, new RegularPricing()); echo $product->getPrice(); // 100 $product->setStrategy(new SeasonalDiscount(15)); echo $product->getPrice(); // 85 $product->setStrategy(new VIPPricing()); echo $product->getPrice(); // 80 ``` **Observer Pattern** - Defines subscription mechanism to notify multiple objects: ```go // Go Example - Event system package events type Event struct { Name string Data interface{} } type Observer interface { Update(event Event) } type Subject struct { observers []Observer } func (s *Subject) Attach(observer Observer) { s.observers = append(s.observers, observer) } func (s *Subject) Detach(observer Observer) { for i, obs := range s.observers { if obs == observer { s.observers = append(s.observers[:i], s.observers[i+1:]...) break } } } func (s *Subject) Notify(event Event) { for _, observer := range s.observers { observer.Update(event) } } // Concrete observers type EmailNotifier struct{} func (e *EmailNotifier) Update(event Event) { log.Printf("Email notification for event: %s", event.Name) } type LogObserver struct{} func (l *LogObserver) Update(event Event) { log.Printf("Logging event: %s with data: %v", event.Name, event.Data) } // Usage subject := &Subject{} subject.Attach(&EmailNotifier{}) subject.Attach(&LogObserver{}) subject.Notify(Event{ Name: "UserRegistered", Data: map[string]string{"email": "user@example.com"}, }) ``` ## Implementing Clean Architecture ### Layered Structure ``` project/ ├── domain/ # Business logic, entities, domain events ├── application/ # Use cases, application services ├── infrastructure/ # External dependencies (DB, API, queue) └── interfaces/ # Controllers, CLI, API handlers ``` ### Go Example with Clean Architecture ```go // domain/user.go - Core business entity package domain import "errors" type User struct { ID string Email string Password string Active bool } func NewUser(email, password string) (*User, error) { if email == "" { return nil, errors.New("email required") } if len(password) < 8 { return nil, errors.New("password must be at least 8 characters") } return &User{ Email: email, Password: password, Active: true, }, nil } type UserRepository interface { Save(user *User) error FindByEmail(email string) (*User, error) } // application/register_user.go - Use case package application import "project/domain" type RegisterUserUseCase struct { repo domain.UserRepository } func NewRegisterUserUseCase(repo domain.UserRepository) *RegisterUserUseCase { return &RegisterUserUseCase{repo: repo} } func (uc *RegisterUserUseCase) Execute(email, password string) error { // Check if user exists existing, _ := uc.repo.FindByEmail(email) if existing != nil { return errors.New("user already exists") } // Create new user user, err := domain.NewUser(email, password) if err != nil { return err } // Save user return uc.repo.Save(user) } // infrastructure/postgres_user_repository.go - Implementation package infrastructure import ( "database/sql" "project/domain" ) type PostgresUserRepository struct { db *sql.DB } func NewPostgresUserRepository(db *sql.DB) *PostgresUserRepository { return &PostgresUserRepository{db: db} } func (r *PostgresUserRepository) Save(user *domain.User) error { _, err := r.db.Exec( "INSERT INTO users (email, password, active) VALUES ($1, $2, $3)", user.Email, user.Password, user.Active, ) return err } func (r *PostgresUserRepository) FindByEmail(email string) (*domain.User, error) { user := &domain.User{} err := r.db.QueryRow( "SELECT id, email, password, active FROM users WHERE email = $1", email, ).Scan(&user.ID, &user.Email, &user.Password, &user.Active) if err == sql.ErrNoRows { return nil, nil } return user, err } // interfaces/http/handler.go - API layer package http import ( "encoding/json" "net/http" "project/application" ) type RegisterRequest struct { Email string `json:"email"` Password string `json:"password"` } type UserHandler struct { registerUseCase *application.RegisterUserUseCase } func NewUserHandler(registerUseCase *application.RegisterUserUseCase) *UserHandler { return &UserHandler{registerUseCase: registerUseCase} } func (h *UserHandler) Register(w http.ResponseWriter, r *http.Request) { var req RegisterRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } err := h.registerUseCase.Execute(req.Email, req.Password) if err != nil {
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub