یک معماری تمیز نظر در زنگ زدگی

همانطور که در پست قبلی خود اشاره کردم ، طی چند ماه گذشته با Rust بسیار زیاد شده ام و واقعاً از تجربه توسعه ای که ارائه می دهد لذت می برم. صادقانه بگویم ، از زمان یادگیری یک زبان جدید ، این سرگرم کننده و چالش برانگیز است.
در طول سالها تجربه خود ، من بیشتر خدمات وب (با جاوا ، PHP ، گره ، پایتون …) را توسعه داده ام و اکنون نیز با Rust. از آنجا که معماری هایی مانند شش ضلعی ، معماری تمیز و DDD تقاضای زیادی دارند ، من می خواستم سعی کنم تمام این ایده ها را برای زنگ زدگی استفاده کنم تا ببینم چگونه آنها مناسب هستند.
بعد از بحث و گفتگو با یک همکار (از آلبرتو از صبر و حوصله و زمان صرف شده برای این کار) در مورد طراحی مناسب برای یک پروژه ، ما به چنین چیزی رسیدیم:
تجارت
├── business # Business logic layer
│ ├── Cargo.toml # Rust library config for business logic
│ └── src
│ ├── application # Use cases and application logic
│ │ └── product
│ │ └── use_cases # CRUD operations for Product
│ │ ├── create.rs
│ │ ├── delete.rs
│ │ ├── get_by.rs
│ │ └── update.rs
│ ├── domain # Pure domain model, business rules
│ │ └── product
│ │ ├── errors.rs # Domain-specific error definitions
│ │ ├── model.rs # Product entity (attributes and behavior)
│ │ ├── repository.rs # Interface for product data access
│ │ ├── use_cases # Domain logic for specific cases
│ │ │ ├── create.rs
│ │ │ ├── delete.rs
│ │ │ ├── get_by.rs
│ │ │ └── update.rs
│ │ └── value_objects.rs # Value objects related to Product
│ ├── lib.rs # Entry point for business library
این لایه قلب پروژه است ، کاملاً آگنوستیک از هرگونه وابستگی شخص ثالث. این همه منطق کسب و کار ، دامنه خالص را در خود جای داده است و مواردی را نشان می دهد که قوانین و رفتارهای اصلی را نشان می دهد – بدون اینکه اجازه دهید جزئیات فنی یا زیرساختی را به وجود آورد. در زنگ زدگی ، این جدایی به لطف مدولار بودن و سازماندهی توسط جعبه ها کاملاً واضح است.
زیرساخت
├── infrastructure # Technical implementations (DB, events, notifications)
│ ├── README.md
│ ├── events # Integration with messaging/event systems
│ │ ├── Cargo.toml # Rust library config for events
│ │ ├── kafka.rs
│ │ └── rabbitmq.rs
│ ├── notifications # External notification services
│ │ ├── Cargo.toml # Rust library config for notifications
│ │ ├── sendgrid.rs
│ │ └── twilio.rs
│ └── persistence # Data persistence (databases)
│ ├── Cargo.toml # Rust library config for DB
│ └── mongo
│ └── product
│ ├── data_model.rs # DB data model (mapping)
│ └── repository.rs # Mongodb repository implementation
در این لایه ، ما تمام پیاده سازی های فنی را که از برنامه پشتیبانی می کنند ، مانند بانکهای اطلاعاتی ، پیام رسانی یا خدمات خارجی قرار می دهیم. از آنجا که لایه تجاری فقط به رابط ها بستگی دارد ، در اینجا ما به راحتی می توانیم بدون تأثیر بر منطق اصلی ، پیاده سازی ها را عوض کنیم. سیستم و ماژول های نوع Rust به روشن و کنترل این وابستگی ها کمک می کنند ، و همچنین ادغام با فناوری خارجی از طریق جعبه های خاص برای Kafka ، RabbitMQ یا خدمات اطلاع رسانی را آسان می کند.
ارائه
├── presentation # User interface / system entry point
│ ├── README.md
│ ├── cli # Command-line interface
│ │ ├── Cargo.toml
│ │ └── src
│ │ └── main.rs # CLI main entry point
│ ├── cron # Scheduled jobs (recurring tasks)
│ │ ├── Cargo.toml
│ │ └── src
│ │ └── main.rs # Code to run cron tasks
│ └── rest-api # REST API exposing the domain
│ ├── Cargo.toml
│ └── src
│ ├── config # API general configuration
│ │ ├── app_state.rs
│ │ ├── settings.rs
│ │ └── tracing.rs
│ ├── lib.rs # REST library entry point
│ ├── main.rs # Main to launch HTTP server
│ └── router
│ └── product
│ ├── controller.rs # REST controllers for Product
│ └── dto.rs # Data transfer objects
سرانجام ، لایه ارائه ، درب ورودی سیستم است ، تعامل با کاربران یا سایر سیستم های خارجی از طریق API ، CLI ، مشاغل برنامه ریزی شده یا یک زمین بازی برای آزمایش سریع موارد در محلی. جدا نگه داشتن این لایه ، جزئیات نحوه دریافت یا ارسال داده ها را با منطق تجارت یا زیرساخت ها خراب نمی کند.
پایان
من واقعاً از چگونگی معلوم شدن طرح نهایی خوشحالم. این امکان را به من می دهد تا بدون نگرانی در مورد جزئیات زیرساخت های فنی ، روی عملکرد و منطق کسب و کار تمرکز کنم. بعلاوه ، جداسازی فن آوری های خاص به کاهش بار شناختی کمک می کند و باعث می شود پروژه قابل حفظ و مقیاس پذیر باشد. به طور خلاصه ، من معتقدم که این معماری راهی عالی برای سازماندهی یک پروژه زنگ زدگی کامل و حرفه ای است.
shop-project/
├── Cargo.toml # Main Rust project config file
├── business # Business logic layer
│ ├── Cargo.toml # Rust library config for business logic
│ └── src
│ ├── application # Use cases and application logic
│ │ └── product
│ │ └── use_cases # Operations for Product
│ │ ├── create.rs
│ │ ├── delete.rs
│ │ ├── get_by.rs
│ │ └── update.rs
│ ├── domain # Pure domain model, business rules
│ │ └── product
│ │ ├── errors.rs # Domain-specific error definitions
│ │ ├── model.rs # Product entity (attributes and behavior)
│ │ ├── repository.rs # Interface for product data access
│ │ ├── use_cases # Domain logic for specific cases
│ │ │ ├── create.rs
│ │ │ ├── delete.rs
│ │ │ ├── get_by.rs
│ │ │ └── update.rs
│ │ └── value_objects.rs # Value objects related to Product
│ ├── lib.rs # Entry point for business library
├── docker-compose.yml # Docker services configuration
├── infrastructure # Technical implementations (DB, events, notifications)
│ ├── README.md
│ ├── events # Integration with messaging/event systems
│ │ ├── Cargo.toml # Rust library config for events
│ │ ├── kafka.rs
│ │ └── rabbitmq.rs
│ ├── notifications # External notification services
│ │ ├── Cargo.toml # Rust library config for notifications
│ │ ├── sendgrid.rs
│ │ └── twilio.rs
│ └── persistence # Data persistence (databases)
│ ├── Cargo.toml # Rust library config for DB
│ └── mongo
│ └── product
│ ├── data_model.rs # DB data model (mapping)
│ └── repository.rs # Mongo repository implementation
├── presentation # User interface / system entry point
│ ├── README.md
│ ├── cli # Command-line interface
│ │ ├── Cargo.toml
│ │ └── src
│ │ └── main.rs # CLI main entry point
│ ├── cron # Scheduled jobs (recurring tasks)
│ │ ├── Cargo.toml
│ │ └── src
│ │ └── main.rs # Code to run cron tasks
│ └── rest-api # REST API exposing the domain
│ ├── Cargo.toml
│ └── src
│ ├── config # API general configuration
│ │ ├── app_state.rs
│ │ ├── settings.rs
│ │ └── tracing.rs
│ ├── lib.rs # REST library entry point
│ ├── main.rs # Main to launch HTTP server
│ └── router
│ └── product
│ ├── controller.rs # REST controllers for Product
│ └── dto.rs # Data transfer objects