درک اصول محکم (بدون خوابیدن)

آیا تا به حال در مورد جامد خوانده اید و احساس کرده اید که پلک های شما در نیمه راه “S” فرو می رود؟ بیایید آن را برطرف کنیم.
این که آیا شما در ساعت 2 صبح کد اسپاگتی را اشکال زدایی می کنید یا سعی می کنید آینده شما را از خشم و با عصبانیت جلوگیری کنید ، اصول محکم در اینجا برای کمک به شما هستند. اما بیایید صادق باشیم – آنها غالباً با خشک ترین روش ممکن تدریس می شوند.
در این مقاله ، شما را با استفاده از TypeScript ، قیاس های دنیای واقعی و برخی از طنزهای بسیار مورد نیاز ، شما را از طریق اصول محکم قدم می زنم. بدون جارگون بدون دست زدن به دست. فقط نمونه هایی از کد قابل تمیز و قابل خواندن را که می فهمید و به یاد می آورید.
چرا مهم است (و چرا اغلب کسل کننده است)
جامد مجموعه ای از پنج اصل طراحی است که کد شما را ایجاد می کند:
با این حال ، بیشتر توضیحات احساس می کنند که توسط یک ربات برای سایر روبات ها نوشته شده است. اکنون به پایان می رسد.
بیایید هر اصل را خراب کنیم مانند اینکه ما اولین پروژه بوت کامپ شما را تغییر می دهیم – یک اشکال در یک زمان.
🧱 S – اصل مسئولیت واحد (SRP)
“یک کلاس باید یک و تنها یک دلیل برای تغییر داشته باشد.”
ترجمه: یک کلاس. یک کار چند وظیفه ای ندارد.
🚨 تخلف:
class User {
constructor(public username: string, public password: string) {}
login() {
// auth logic
}
saveToDB() {
// db logic
}
logActivity() {
// logging logic
}
}
این کلاس بیش از حد انجام می دهد. این تأیید کننده ، داده های مداوم و ورود به سیستم است. بعد قهوه درست می کند.
✅ رفع:
class AuthService {
login(username: string, password: string) {
// auth logic
}
}
class UserRepository {
save(user: User) {
// db logic
}
}
class Logger {
log(message: string) {
console.log(message);
}
}
class User {
constructor(public username: string, public password: string) {}
}
هر کلاس اکنون یک کار دارد. شما فقط یک پنجم آینده کسب کرده اید.
🚪 O – اصل باز/بسته (OCP)
“نهادهای نرم افزاری باید برای پسوند باز باشند ، اما برای اصلاح بسته شده اند.”
ترجمه: با افزودن کد ، ویژگی های جدید را اضافه کنید ، نه بازنویسی کد قدیمی.
🚨 تخلف:
class Payment {
pay(method: string) {
if (method === 'paypal') {
// PayPal logic
} else if (method === 'stripe') {
// Stripe logic
}
}
}
هر بار که یک روش پرداخت جدید اضافه می کنید ، باید این کلاس را ویرایش کنید. این یک مین تعمیر و نگهداری است.
✅ رفع:
interface PaymentMethod {
pay(amount: number): void;
}
class PayPal implements PaymentMethod {
pay(amount: number) {
console.log(`Paid ${amount} using PayPal`);
}
}
class Stripe implements PaymentMethod {
pay(amount: number) {
console.log(`Paid ${amount} using Stripe`);
}
}
class PaymentProcessor {
constructor(private method: PaymentMethod) {}
process(amount: number) {
this.method.pay(amount);
}
}
اکنون می توانیم بدون لمس منطق موجود ، یک روش پرداخت جدید اضافه کنیم. این OCP در عمل است.
🦢 L – اصل تعویض لیسکوف (LSP)
“زیرگروه ها باید برای انواع پایه آنها قابل تعویض باشند.”
ترجمه: اگر Dog
تمدید کردن Animal
، هنوز هم باید مانند یک رفتار کند Animal
بشر
🚨 تخلف:
class Rectangle {
constructor(public width: number, public height: number) {}
setWidth(w: number) {
this.width = w;
}
setHeight(h: number) {
this.height = h;
}
area() {
return this.width * this.height;
}
}
class Square extends Rectangle {
setWidth(w: number) {
this.width = w;
this.height = w;
}
setHeight(h: number) {
this.width = h;
this.height = h;
}
}
سعی کنید استفاده کنید Square
کجا Rectangle
انتظار می رود و شما رفتار تعجب آور خواهید داشت. که LSP را می شکند.
✅ رفع:
تمدید نکنید Rectangle
برای Square
بشر یا رابط های جداگانه ای ایجاد یا ایجاد کنید. LSP سازگاری رفتاری را نسبت به راحتی وراثت ترجیح می دهد.
🧩 I – اصل تفکیک رابط (ISP)
“مشتریان نباید مجبور شوند به روشهایی که از آنها استفاده نمی کنند وابسته باشند.”
ترجمه: رابط های خود را لاغر و متمرکز نگه دارید.
🚨 تخلف:
interface Machine {
print(): void;
scan(): void;
fax(): void;
}
class OldPrinter implements Machine {
print() {
console.log("Printing...");
}
scan() {
throw new Error("Not supported");
}
fax() {
throw new Error("Not supported");
}
}
چرا یک چاپگر باید اسکن و نمابر را پیاده سازی کند؟
✅ رفع:
interface Printer {
print(): void;
}
interface Scanner {
scan(): void;
}
class SimplePrinter implements Printer {
print() {
console.log("Printing...");
}
}
اکنون کلاس ها فقط آنچه را که در واقع به آن نیاز دارند ، پیاده سازی می کنند. اصل خوشحال است. بنابراین ورود به خطای شما است.
🔌 D – اصل وارونگی وابستگی (DIP)
“به انتزاع بستگی دارد ، نه بتن.”
ترجمه: وابستگی های خود را سخت نکنید. از رابط ها استفاده کنید.
🚨 تخلف:
class UserService {
private db = new Database(); // tight coupling
getUser(id: string) {
return this.db.find(id);
}
}
شما نمی توانید مبادله کنید Database
با MockDatabase
یا CloudDatabase
بشر آزمایش؟ موفق باشید
✅ رفع:
interface IDatabase {
find(id: string): any;
}
class UserService {
constructor(private db: IDatabase) {}
getUser(id: string) {
return this.db.find(id);
}
}
اکنون می توانید هرگونه اجرای پایگاه داده را تزریق کنید. کد شما انعطاف پذیر تر و قابل آزمایش است.
🔑 غذای اصلی
-
SRP: یک کلاس = یک کار. آن را متمرکز کنید.
-
OCP: بدون تغییر کد موجود ، رفتار را گسترش دهید.
-
LSP: زیر کلاس ها باید مانند والدین خود کار کنند.
-
ISP: کلاس ها را مجبور به اجرای آنچه لازم نیست.
-
DIP: کد به رابط ها ، نه پیاده سازی.
بیایید این کار را ادامه دهیم
کدام اصل محکم شما را بیشتر می کند؟ یک نظر را رها کنید – بحث کنید!
اگر این کمک کرد ، آن را با دوستی که هنوز فکر می کند SRP یک پروتکل WiFi است به اشتراک بگذارید.
🌐 با من ارتباط برقرار کنید:
📍 لینکدین
📍 x (توییتر)
📍 تلگرام
📍 اینستاگرام
برنامه نویسی مبارک!