Angular – الگوی طراحی انتزاعی-DRY و مسئولیت مشترک تک
الگوی روش انتزاعی یک الگوی طراحی محبوب است که در برنامه های Angular استفاده می شود. این یک الگوی طراحی رفتاری است که ساختار اسکلتی یک الگوریتم را در یک عملیات تعریف میکند و جزئیات پیادهسازی را میگذارد تا توسط کلاسهای فرعی پر شود. در این وبلاگ، الگوی Abstract Method در Angular و نحوه پیاده سازی آن در برنامه های ما را بررسی خواهیم کرد.
ابتدا بیایید بفهمیم که الگوی Abstract Method چیست؟
چکیده الگوی روش راهی برای تعریف مجموعهای از روشها است که باید توسط کلاسهای فرعی پیادهسازی شوند. این یک الگوی روش الگو است که مراحل یک الگوریتم را تعریف می کند، اما اجرای مراحل را به زیر کلاس ها واگذار می کند. الگوی Abstract Method در موقعیت هایی مفید است که مجموعه ای از اشیاء دارای برخی رفتارهای مشترک هستند، اما رفتارهای متفاوتی نیز دارند که باید در کلاس های فرعی تعریف شوند.
الگوی Abstract Method یک الگوی طراحی است در TypeScript که یک کلاس پایه انتزاعی را ارائه می دهد که شامل یک یا چند روش انتزاعی است. سپس این روشهای انتزاعی توسط زیر کلاسهای مشخصی اجرا میشوند که جزئیات پیادهسازی خاص را برای روشهای انتزاعی ارائه میکنند. این الگو زمانی مفید است که میخواهید مجموعهای از رفتارها را تعریف کنید که باید توسط زیر کلاسهای بتن پیادهسازی شوند، اما نمیخواهید جزئیات پیادهسازی را در کلاس پایه مشخص کنید.
یکی از مزایای کلیدی الگوی روش انتزاعی این است که به شما امکان میدهد مجموعهای از رفتارها را تعریف کنید که باید توسط زیر کلاسهای مشخص اجرا شوند، در حالی که هنوز برخی عملکردهای مشترک را ارائه میدهد که میتواند در همه زیر کلاسها به اشتراک گذاشته شود. این می تواند حفظ کد شما را در طول زمان آسان تر کند، زیرا می توانید عملکرد رایج در کلاس پایه انتزاعی را بدون نیاز به تغییر هر زیر کلاس جداگانه به روز کنید.
یکی دیگر از مزایای الگوی روش انتزاعی این است که میتواند به اجرای شیوههای طراحی خوب کمک کند، زیرا مستلزم آن است که زیر کلاسها روشهای خاصی را به روشی ثابت اجرا کنند. این می تواند به اطمینان حاصل شود که کد شما قابل پیش بینی تر است و کمتر مستعد خطا یا رفتار غیرمنتظره است.
هنگام استفاده از الگوی Abstract Methodمهم است که به خاطر داشته باشید که روش های انتزاعی باید توسط همه زیر کلاس های مشخص اجرا شوند. اگر یک زیر کلاس نتواند یک متد انتزاعی را پیاده سازی کند، یک خطای کامپایل دریافت خواهید کرد، که می تواند به شناسایی اشکالات در مراحل اولیه توسعه کمک کند.
علاوه بر تعریف روش های انتزاعی، از الگوی Abstract Method نیز می توان برای تعریف ویژگی های انتزاعی استفاده کرد. ویژگی های انتزاعی شبیه به روش های انتزاعی هستند، اما به جای تعریف امضای متد، امضای ویژگی را تعریف می کنند. این می تواند زمانی مفید باشد که می خواهید اطمینان حاصل کنید که یک ویژگی توسط همه زیر کلاس ها پیاده سازی شده است، اما نمی خواهید یک پیاده سازی پیش فرض در کلاس پایه انتزاعی ارائه دهید.
با تعریف یک کلاس پایه انتزاعی که شامل عملکرد مشترک و یک یا چند روش انتزاعی است، میتوانیم مجموعهای از زیر کلاسهای مشخصی ایجاد کنیم که پیادهسازیهای خاصی را برای هر روش ارائه میدهند. این به ما امکان میدهد تا از عملکردهای مشترک در چندین مؤلفه مجدداً استفاده کنیم، در حالی که همچنان اجازه میدهد هر مؤلفه در صورت نیاز سفارشی شود.
در اینجا مثالی از نحوه استفاده از الگوی Abstract Method با چندین مؤلفه در یک برنامه Angular آورده شده است:
فرض کنید مجموعهای از مؤلفههای رابط کاربری داریم که همگی نیاز به نمایش دادههای مشترک دارند، اما هر مؤلفه باید این دادهها را به روشی متفاوت نشان دهد. به عنوان مثال، ممکن است یک جزء جدول، یک جزء کارت و یک جزء لیست داشته باشیم که هر کدام باید لیستی از کاربران را در قالب متفاوتی نمایش دهند.
برای پیاده سازی این قابلیت با استفاده از الگوی Abstract Method
میتوانیم با تعریف یک کلاس پایه انتزاعی که شامل عملکرد مشترک برای واکشی و نمایش دادهها است، شروع کنیم. در اینجا یک مثال از آنچه ممکن است شبیه باشد آورده شده است:
import { Component, OnInit } from '@angular/core';
abstract class UserListComponent implements OnInit {
users: any[];
ngOnInit(): void {
this.fetchUsers();
}
abstract fetchUsers(): void;
abstract displayUsers(): void;
}
در این مثال، ما یک کلاس انتزاعی به نام UserListComponent تعریف کردهایم که کلاس Angular Component را گسترش داده و رابط OnInit را پیادهسازی میکند. این کلاس شامل دو متد انتزاعی fetchUsers و displayUsers است که ما از آنها برای تعریف عملکرد خاص برای هر یک از اجزای UI خود استفاده خواهیم کرد.
// Create a concrete subclass for a table component
@Component({
selector: 'app-table',
templateUrl: './table.component.html',
styleUrls: ['./table.component.css']
})
export class TableComponent extends UserListComponent {
fetchUsers(): void {
// Fetch users data from API and store it in the 'users' property
}
displayUsers(): void {
// Display users data in a table format
}
}
-----------------------------------------------------------------------
// Create a concrete subclass for a card component
@Component({
selector: 'app-card',
templateUrl: './card.component.html',
styleUrls: ['./card.component.css']
})
export class CardComponent extends UserListComponent {
fetchUsers(): void {
// Fetch users data from API and store it in the 'users' property
}
displayUsers(): void {
// Display users data in a card format
}
}
-----------------------------------------------------------------------
// Create a concrete subclass for a list component
@Component({
selector: 'app-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.css']
})
export class ListComponent extends UserListComponent {
fetchUsers(): void {
// Fetch users data from API and store it in the 'users' property
}
displayUsers(): void {
// Display users data in a list format
}
}
سپس ما سه زیر کلاس مشخص از ایجاد کردیم UserListComponent، یکی برای هر یک از اجزای رابط کاربری ما: یک جزء جدول، یک جزء کارت، و یک جزء لیست. هر یک از این زیر کلاس ها گسترش می یابد UserListComponent و پیاده سازی خاصی را برای fetchUsers و displayUsers مواد و روش ها.
با استفاده از الگوی Abstract Method، میتوانیم مجموعهای از اجزای قابل استفاده مجدد ایجاد کنیم که عملکردهای مشترکی دارند و در عین حال به هر مؤلفه اجازه میدهد تا رفتار منحصر به فرد خود را ارائه دهد. این باعث می شود کد ما قابل نگهداری تر، توسعه پذیرتر و درک آن آسان تر باشد.
فرض کنید می خواهیم هر سه نما را در یک صفحه و در کنار هم نمایش دهیم. ما می توانیم با ایجاد یک به این دست یابیم جزء والد که به سادگی شامل سه جزء فرزند است:
@Component({
selector: 'app-user-list',
templateUrl: './user-list.component.html',
styleUrls: ['./user-list.component.css']
})
export class UserListComponent {
constructor() { }
}
<div class="user-list-container">
<app-table></app-table>
<app-list></app-list>
<app-tile></app-tile>
</div>
این رویکرد به ما اجازه میدهد تا کد هر نما را مجزا و سازماندهیشده نگه داریم، در حالی که همچنان به ما امکان میدهد همه آنها را با هم در یک صفحه یا نمای واحد نمایش دهیم.
فرض کنید می خواهیم یک ویژگی جستجو را به جزء لیست کاربران خود اضافه کنیم. می توانیم یک روش انتزاعی جدید تعریف کنیم جستجو کاربران در ما UserListComponent:
export abstract class UserListComponent implements OnInit {
users: User[] = [];
constructor() { }
ngOnInit() {
this.fetchUsers();
}
abstract fetchUsers(): void;
abstract displayUsers(): void;
abstract searchUsers(term: string): void;
}
حالا هر کدام از مؤلفه های فرزند ما می توانند این روش را به روش خود پیاده کنند. اینجا یک اجرای مثال برای TableComponent:
@Component({
selector: 'app-table',
templateUrl: './table.component.html',
styleUrls: ['./table.component.css']
})
export class TableComponent extends UserListComponent {
searchUsers(term: string): void {
// Filter users data based on search term
this.users = this.users.filter(user => user.name.toLowerCase().includes(term.toLowerCase()));
this.displayUsers();
}
fetchUsers(): void {
// Fetch users data from API and store it in the 'users' property
}
displayUsers(): void {
// Display users data in a table format
}
}
<div class="user-list-container">
<app-table></app-table>
<app-list></app-list>
<app-tile></app-tile>
</div>
<app-search (search)="onSearch($event)"></app-search>
در اینجا، ما یک را اضافه کرده ایم جزء نوار جستجو (برنامه-جستجو) به صفحه ما و یک کنترل کننده رویداد تعریف کرد در جستجو که به جستجو کاربران روش در مؤلفه فرزند نمایش داده شده در حال حاضر. رویداد جستجوی منتشر شده توسط مؤلفه نوار جستجو حاوی عبارت جستجوی وارد شده توسط کاربر است.
نتیجه
به طور خلاصه، الگوی Abstract Method می تواند ابزار قدرتمندی برای ایجاد کدهای ماژولار و قابل استفاده مجدد در یک برنامه Angular باشد، به خصوص هنگام کار با چندین مؤلفه که نیاز به اشتراک گذاری یک رابط یا رفتار مشترک دارند. با تعریف یک کلاس پایه انتزاعی با متدهای انتزاعی و داشتن چندین مؤلفه گسترش و پیاده سازی آن متدها، می توانیم به درجه بالایی از انعطاف پذیری و قابلیت نگهداری در کد خود دست یابیم.
به طور کلی، الگوی Abstract Method می تواند ابزار مفیدی برای طراحی سیستم های شی گرا در TypeScript باشد. با تعریف متدهای انتزاعی در یک کلاس پایه انتزاعی، می توانید اطمینان حاصل کنید که کد شما در طول زمان انعطاف پذیرتر، توسعه پذیرتر و قابل نگهداری است.