الگوی specification، یک گزاره است که بر روی یک داده یا ماهیت اجرا می شود.
زمانی که در مورد الگوی specification صحبت می کنیم، با سه حوزه مختلف Selection, Validate, Construction-to-Order روبرو می شویم.
موضوع selection، اشاره به این دارد که گاهی بین یک دسته از داده ها، نیاز داریم بسته به شرایطی داده ای را انتخاب کنیم.
گاهی نیاز داریم که از predicate مورد نظر خود به عنوان یک گزاره جهت validate کردن داده ها استفاده کنیم. برای مثال در هر تیکت از پرواز، حداقل یک بزرگسال باید حضور داشته باشد.
موضوع Construction-to-Order، به چگونگی انجام کار یک شی، بدون توضیح جزئیات نحوه انجام آن می پردازد.
هر سه موضوع در مورد یک انتزاع صحبت می کنند که قصد دارند یک criteria را بر روی یک object اجرا کنند.
الگوی specification به شما در جداسازی الزامات و validationها کمک می کند. بنابراین در استفاده از الگوی specification باید به این مساله فکر کنید که آیا این گونه جداسازی، به حل مشکل در طراحی شما کمک می کند یا خیر.
وجود specificationها، باعث بوجود آمدن یک ساختار واضح تر در طراحی شما می شود. شما به جای استفاده از operationها در گزاره هایی که استفاده می کنید، می توانید مشخصا در مورد یک مفهوم که دارای یک structure می باشد صحبت کنید.
در استفاده از specification باید به این مساله فکر کنید که آیا منطق شما در کوئری زدن، validate کردن یا construction to order در جاهای مختلف اپلیکیشن به دفعات تکرار می شود؟ همچنین در specificationها تا چه حد تنوع دارم و این تنوع در طول زمان تا چه حد ممکن است کم و زیاد شود و جداسازی آن ها تا چه می تواند به ما را در طراحی بهتر کمک کند؟ فارغ از متنوع بودن، نحوه استفاده متفاوت از specificationها می تواند در استفاده از آن ها تاثیر گذار باشد. در حالت های مختلف، تعداد چک کردن specificationها می تواند متفاوت باشد.
یک نمونه specification وجود دارد که به آن Hard Coded Specification گفته می شود.
از آنجایی که Hard Coded Specificationها به زبان domain نزدیک هستند بنابراین مزیتی که در این نمونه دیده می شود، ساده بودن آن ها است. و ایرادی که در آن ها دیده می شود، انعطاف پذیری کم در مقابل تغییرات است.
در اینجا یک نمونه مشاهده می کنید که به طور مشخص یک شرط را با مقادیرش در داخل خود hard code کرده است.
public class IsAdultSpec : ISpecification<Passenger> { public bool IsSatisfiedBy(Passenger passenger) { return passenger.Age >= 12; } }
یک نمونه specification به نام Parameterized Specification وجود دارد.
در جاهایی که flexibility بیشتری نیاز داریم می توانیم از این مدل استفاده کنیم.
من این امکان را دارم که در نمونه بالا مقدار را از طریق پارامتر دریافت کنم و آن را به یک Parameterized Specification تبدیل کنم.
public class AgeSpec : ISpecification<Passenger> { private int _maximumAge; public AgeSpec(int maximumAge) { _maximumAge = maximumAge; } public bool IsSatisfiedBy(Passenger passenger) { return passenger.Age >= _maximumAge; } }
در Parameterized Specification، ما به حداقل یک کلاس و یک یا چندین مشخصه از آن وابسته هستیم که در مثال بالا کلاس Passenger می باشد.
نوع دیگری که از specification وجود دارد، Composite Specification است.
این امکان وجود دارد که به صورت ترکیبی از انواع ذکر شده استفاده کنیم.
به طور خلاصه، در این الگو predicateها و criteria جزو variability ما هستند و candidate به عنوان یک تایپ که predicate بر روی آن اجرا می شود، commonality ما است.