Notice: file_put_contents(): Write of 9515 bytes failed with errno=28 No space left on device in /var/www/tgoop/post.php on line 50

Warning: file_put_contents(): Only 12288 of 21803 bytes written, possibly out of free disk space in /var/www/tgoop/post.php on line 50
Web Devs@fullStackDevs P.445
FULLSTACKDEVS Telegram 445
🌀 Specification pattern: C# implementation

در این پست به معرفی الگوی Specification میپردازیم و یک مثال فوق العده کاربردی ارائه میدهیم که یک گام معماری و کدتان به Domain Driven Design و Clean Code نزدیکتر میکند.
*توضیحات تکمیلی : این پست را بهتر است با تلگرام دسکتاب و در سایز maximize مطالعه فرمایید.

🔸 یکی مزایای استفاده از این الگو را میتواند Encapsulation کردن اطلاعاتی که در مورد Domain میباشد دریک قسمت واحد بشمار آورد.
موارد استفاده از این الگو با ذکر یک مثال به طور کامل بیان شده است.

فرض کنید یکی از کلاس های دامین مدل ما کلاس Movie باشد که به صورت زیر تعریف شده است :

public class Movie : Entity
{
public string Name { get; }
public DateTime ReleaseDate{get;}
public MpaaRating MpaaRating {get;}
public string Genre { get; }
public double Rating { get; }
}

public enum MpaaRating
{
G,
PG13,
R
}
🔹 حالا فرض کنیم که کاربر فیلم های تازه ساخته شده را میخواهد تماشا کند. برای نمایش این فیلم ها به کاربر معمولا در Repository مربوطه متدی به شکل زیر تعریف میکنیم :

public class MovieRepository
{
public IReadOnlyList<Movie> GetByReleaseDate(DateTime minReleaseDate)
{
/* ... */
}
}
یا اگر به فیلم هایی براساس Rate یا Genre یا دیگر شاخص ها نیاز داشته باشیم بدین شکل معمولا متد های ریپازیتوری مان را تعریف میکنیم :
public class MovieRepository
{
public IReadOnlyList<Movie> GetByReleaseDate(DateTime maxReleaseDate) { }

public IReadOnlyList<Movie> GetByRating(double minRating) { }

public IReadOnlyList<Movie> GetByGenre(string genre) { }
}
🔸 ریپازیتوری قدری پیچیده میشود اگر پارامترهای جست و جوی ما پیچیده تر شوند مثلا اگر تمامیه فیلم هایی را که در تاریخ انتشار مشخص و با ژانر خاصی هستند نیاز داشته باشید معمولا دوباره به ازای آن یک متد در ریپازیتوری مربوطه تعریف میکنید.
برای نوشتن این متد روش های زیادی وجود دارد مانند اکستنشن متد،یا یک متدی که به صورت جداگانه این فیلتر ها را بروی Dbset<Movie> اعمال کند. اما این راه حل ها راهای درستی نیستند و از جمله معیاب آن میتوان به نقض کردن اصل DRY میباشد چون بایستی به ازای هر Dbset این متد ها را که حتی ممکن است logic های یکسانی داشته باشند ، تکرار کنید.
اکنون شاید با خود میگویید خب میتوانیم از یک متد Generic برای جلوگیری از این تکرار استفاده کنیم .
راه حل این مشکل استفاده از الگوی specification است . اما با یک پیاده سازی خاص .در این پست دو پیاده سازی از این الگو ارائه خواهییم داد.
پیاده سازی اول یک پیاده سازی ساده با عنوان Naive implementation است.و در ادامه به سمت بهتر کردن ان پیش میرویم.
اولین راه حل برای مقابله با مشکل بالا (ایجاد متد های متعدد برای شاخص های متعدد در جست و جو و مرتب سازی و..) استفاده از امکان expressions در سی شارپ است تا حدی زیادی آنها خودشان هم یک پیاده سازی از الگوی specification هستند. پس میتوانید یک متد در ریپازیتوری خود بنویسیدکه به عنوان پارامتر یک expression ورودی بگیرد مثال :
// Controller
public void SomeMethod()
{
Expression<Func<Movie, bool>> expression = m => m.MpaaRating == MpaaRating.G;
var movies = _repository.Find(expression); // Getting a list of movies
}
// Repository
public IReadOnlyList<Movie> Find(Expression<Func<Movie, bool>> expression)
{
return db
.Where(expression)
.ToList();
}
مشکلی که با این روش وجود دارد این است که با اینکه شروط مربوط به دامین مدل مان را در یک مکان واحد جمع اوری کردیم (در متغیر Expression) اما چنین متغیر هایی در این سطح (Controller) برای چنین اطلاعات مهمی اصلا مناسب نیستند.در این روش امکان دوباره استفاده از این شروط بسیار سخت میشود و حتی تمایل به duplicate در کل اپلیکیشن بشدت افزایش پیدا میکتد.و متاسفانه دوباره در نهایت به مشکل اول باز میگردیم.
حال نوبت به یک پیاده سازیه ساده از الگوی Specification تحت عنوان GenericSpecification میرسد.
public class GenericSpecification<T>
{
public Expression<Func<T , bool>> Expression { get; }

public GenericSpecification(Expression<Func<T , bool>> expression)
{
Expression = expression;
}
public bool IsSatisfiedBy(T entity)
{
return Expression.Compile().Invoke(entity);
}
}
نحوه استفاده از آن در پست بعدی ...

@fullStackDevs



tgoop.com/fullStackDevs/445
Create:
Last Update:

🌀 Specification pattern: C# implementation

در این پست به معرفی الگوی Specification میپردازیم و یک مثال فوق العده کاربردی ارائه میدهیم که یک گام معماری و کدتان به Domain Driven Design و Clean Code نزدیکتر میکند.
*توضیحات تکمیلی : این پست را بهتر است با تلگرام دسکتاب و در سایز maximize مطالعه فرمایید.

🔸 یکی مزایای استفاده از این الگو را میتواند Encapsulation کردن اطلاعاتی که در مورد Domain میباشد دریک قسمت واحد بشمار آورد.
موارد استفاده از این الگو با ذکر یک مثال به طور کامل بیان شده است.

فرض کنید یکی از کلاس های دامین مدل ما کلاس Movie باشد که به صورت زیر تعریف شده است :

public class Movie : Entity
{
public string Name { get; }
public DateTime ReleaseDate{get;}
public MpaaRating MpaaRating {get;}
public string Genre { get; }
public double Rating { get; }
}

public enum MpaaRating
{
G,
PG13,
R
}
🔹 حالا فرض کنیم که کاربر فیلم های تازه ساخته شده را میخواهد تماشا کند. برای نمایش این فیلم ها به کاربر معمولا در Repository مربوطه متدی به شکل زیر تعریف میکنیم :

public class MovieRepository
{
public IReadOnlyList<Movie> GetByReleaseDate(DateTime minReleaseDate)
{
/* ... */
}
}
یا اگر به فیلم هایی براساس Rate یا Genre یا دیگر شاخص ها نیاز داشته باشیم بدین شکل معمولا متد های ریپازیتوری مان را تعریف میکنیم :
public class MovieRepository
{
public IReadOnlyList<Movie> GetByReleaseDate(DateTime maxReleaseDate) { }

public IReadOnlyList<Movie> GetByRating(double minRating) { }

public IReadOnlyList<Movie> GetByGenre(string genre) { }
}
🔸 ریپازیتوری قدری پیچیده میشود اگر پارامترهای جست و جوی ما پیچیده تر شوند مثلا اگر تمامیه فیلم هایی را که در تاریخ انتشار مشخص و با ژانر خاصی هستند نیاز داشته باشید معمولا دوباره به ازای آن یک متد در ریپازیتوری مربوطه تعریف میکنید.
برای نوشتن این متد روش های زیادی وجود دارد مانند اکستنشن متد،یا یک متدی که به صورت جداگانه این فیلتر ها را بروی Dbset<Movie> اعمال کند. اما این راه حل ها راهای درستی نیستند و از جمله معیاب آن میتوان به نقض کردن اصل DRY میباشد چون بایستی به ازای هر Dbset این متد ها را که حتی ممکن است logic های یکسانی داشته باشند ، تکرار کنید.
اکنون شاید با خود میگویید خب میتوانیم از یک متد Generic برای جلوگیری از این تکرار استفاده کنیم .
راه حل این مشکل استفاده از الگوی specification است . اما با یک پیاده سازی خاص .در این پست دو پیاده سازی از این الگو ارائه خواهییم داد.
پیاده سازی اول یک پیاده سازی ساده با عنوان Naive implementation است.و در ادامه به سمت بهتر کردن ان پیش میرویم.
اولین راه حل برای مقابله با مشکل بالا (ایجاد متد های متعدد برای شاخص های متعدد در جست و جو و مرتب سازی و..) استفاده از امکان expressions در سی شارپ است تا حدی زیادی آنها خودشان هم یک پیاده سازی از الگوی specification هستند. پس میتوانید یک متد در ریپازیتوری خود بنویسیدکه به عنوان پارامتر یک expression ورودی بگیرد مثال :
// Controller
public void SomeMethod()
{
Expression<Func<Movie, bool>> expression = m => m.MpaaRating == MpaaRating.G;
var movies = _repository.Find(expression); // Getting a list of movies
}
// Repository
public IReadOnlyList<Movie> Find(Expression<Func<Movie, bool>> expression)
{
return db
.Where(expression)
.ToList();
}
مشکلی که با این روش وجود دارد این است که با اینکه شروط مربوط به دامین مدل مان را در یک مکان واحد جمع اوری کردیم (در متغیر Expression) اما چنین متغیر هایی در این سطح (Controller) برای چنین اطلاعات مهمی اصلا مناسب نیستند.در این روش امکان دوباره استفاده از این شروط بسیار سخت میشود و حتی تمایل به duplicate در کل اپلیکیشن بشدت افزایش پیدا میکتد.و متاسفانه دوباره در نهایت به مشکل اول باز میگردیم.
حال نوبت به یک پیاده سازیه ساده از الگوی Specification تحت عنوان GenericSpecification میرسد.
public class GenericSpecification<T>
{
public Expression<Func<T , bool>> Expression { get; }

public GenericSpecification(Expression<Func<T , bool>> expression)
{
Expression = expression;
}
public bool IsSatisfiedBy(T entity)
{
return Expression.Compile().Invoke(entity);
}
}
نحوه استفاده از آن در پست بعدی ...

@fullStackDevs

BY Web Devs


Share with your friend now:
tgoop.com/fullStackDevs/445

View MORE
Open in Telegram


Telegram News

Date: |

Telegram has announced a number of measures aiming to tackle the spread of disinformation through its platform in Brazil. These features are part of an agreement between the platform and the country's authorities ahead of the elections in October. On Tuesday, some local media outlets included Sing Tao Daily cited sources as saying the Hong Kong government was considering restricting access to Telegram. Privacy Commissioner for Personal Data Ada Chung told to the Legislative Council on Monday that government officials, police and lawmakers remain the targets of “doxxing” despite a privacy law amendment last year that criminalised the malicious disclosure of personal information. How to create a business channel on Telegram? (Tutorial) How to build a private or public channel on Telegram? Healing through screaming therapy
from us


Telegram Web Devs
FROM American