سلام و خسته نباشید. مطالب خیلی خوب بود فقط یه سوال:
اون متد constructor توی EmailBodyDecorator که اینترفیس EmailBody رو به عنوان ورودی میگیره، چه نقشی در این مثال داشت؟
همون تعریف abstract public function loadBody در کلاس EmailBodyDecorator کافی بود و همین نقش رو ایفا میکرد (حداقل در این مثال)
سلام و خسته نباشید. مطالب خیلی خوب بود فقط یه سوال:
اون متد constructor توی EmailBodyDecorator که اینترفیس EmailBody رو به عنوان ورودی میگیره، چه نقشی در این مثال داشت؟
همون تعریف abstract public function loadBody در کلاس EmailBodyDecorator کافی بود و همین نقش رو ایفا میکرد (حداقل در این مثال)
سلام و خسته نباشید. مطالب خیلی خوب بود فقط یه سوال:
اون متد constructor توی EmailBodyDecorator که اینترفیس EmailBody رو به عنوان ورودی میگیره، چه نقشی در این مثال داشت؟
همون تعریف abstract public function loadBody در کلاس EmailBodyDecorator کافی بود و همین نقش رو ایفا میکرد (حداقل در این مثال)
سلام .
constructor کلاس EmailBodyDecorator یک شیء از نوع EmailBody رو به عنوان ورودی میگیره. این شیء اصلی هست که میخوایم روی اون دکوراتور اعمال کنیم.
در ضمن شیء ورودی در یک متغیر ذخیره میشه تا در متدهای دیگه کلاس قابل دسترسی باشه
استفاده ی زنجیره ای از دکوراتور ها هم داریم مثلا وقتی یک دکوراتور جدید ایجاد میکنیم، شیء قبلی (که خود ممکنه یک دکوراتور باشه) رو به عنوان ورودی به سازنده اون میدیم. به این ترتیب، یک زنجیره از دکوراتورها ایجاد میشه.
سلام .
constructor کلاس EmailBodyDecorator یک شیء از نوع EmailBody رو به عنوان ورودی میگیره. این شیء اصلی هست که میخوایم روی اون دکوراتور اعمال کنیم.
در ضمن شیء ورودی در یک متغیر ذخیره میشه تا در متدهای دیگه کلاس قابل دسترسی باشه
استفاده ی زنجیره ای از دکوراتور ها هم داریم مثلا وقتی یک دکوراتور جدید ایجاد میکنیم، شیء قبلی (که خود ممکنه یک دکوراتور باشه) رو به عنوان ورودی به سازنده اون میدیم. به این ترتیب، یک زنجیره از دکوراتورها ایجاد میشه.
ممنون از توضیحات شما. اما به نظر شما الگوی استراتژی را توضیح دادید.
فرض کنیم می خواهیم عملیاتی انجام بدهیم که فقط قسمتی از آن متفاوت است. مثلا عملیات دم کردن چای و دمنوش، ممکنه فقط در یک یا چند مرحله متفاوت هستند در پیاده سازی، در این سبک سناریوها ما به سراغ این الگو می رویم.
ممنون از توضیحات شما. اما به نظر شما الگوی استراتژی را توضیح دادید.
فرض کنیم می خواهیم عملیاتی انجام بدهیم که فقط قسمتی از آن متفاوت است. مثلا عملیات دم کردن چای و دمنوش، ممکنه فقط در یک یا چند مرحله متفاوت هستند در پیاده سازی، در این سبک سناریوها ما به سراغ این الگو می رویم.
این مثالی که زدید اصل OCP رو نقض میکنه ، مثلا اگه یه مدل ماشین جدید بخوایم باید بریم شروط داخل متد make رو تغییر بدیم که بازم میگم این برخلاف اصول SOLIDه ، در واقع شما میتوانستید یه کلاس تحت عنوان CarModels و اونجا یه پراپرتی models با یه متد getModels تعریف کنید ، بعد یه پراپرتی models داخل CarFactory تعریف میکردید و برای نقض نکردن اصل DIP داخل کانستراکتور اون کلاس یه کلاس CarModels میگرفتید و به پراپرتی models پاس میدادید ، سپس یه متد isValidModel تعریف و اونجا بررسی میکردید آیا دیتایی که به فانکشن پاس داده شده در دیتایی که متد getModels ( که روی پراپرتی models فرا خوانده میشه ) بر میگردونه وجود داره یا نه و فانکشن isValidModel رو داخل make صدا میزدید ، اگه مدل معتبر نبود آبجکتی از کلاس CarModelNotDefined ساخته میشد در غیر این صورت مدل پاس داده شده به فانکشن رو uppercase میکردیم و با کمک داینامیک کال و بدون هیچ شرط اضافه ای یه آبجکت از مدل مد نظرمون میساختیم ،
حالا به خیال راحت میتونیم مدلهای ماشین مختلف بسازیم و میتونیم داخل کلاس CarModels که اصطلاحا به عنوان یه لیست برای ما عمل میکنه اسم مدل جدید را وارد کنیم ...،
این مثالی که زدید اصل OCP رو نقض میکنه ، مثلا اگه یه مدل ماشین جدید بخوایم باید بریم شروط داخل متد make رو تغییر بدیم که بازم میگم این برخلاف اصول SOLIDه ، در واقع شما میتوانستید یه کلاس تحت عنوان CarModels و اونجا یه پراپرتی models با یه متد getModels تعریف کنید ، بعد یه پراپرتی models داخل CarFactory تعریف میکردید و برای نقض نکردن اصل DIP داخل کانستراکتور اون کلاس یه کلاس CarModels میگرفتید و به پراپرتی models پاس میدادید ، سپس یه متد isValidModel تعریف و اونجا بررسی میکردید آیا دیتایی که به فانکشن پاس داده شده در دیتایی که متد getModels ( که روی پراپرتی models فرا خوانده میشه ) بر میگردونه وجود داره یا نه و فانکشن isValidModel رو داخل make صدا میزدید ، اگه مدل معتبر نبود آبجکتی از کلاس CarModelNotDefined ساخته میشد در غیر این صورت مدل پاس داده شده به فانکشن رو uppercase میکردیم و با کمک داینامیک کال و بدون هیچ شرط اضافه ای یه آبجکت از مدل مد نظرمون میساختیم ،
حالا به خیال راحت میتونیم مدلهای ماشین مختلف بسازیم و میتونیم داخل کلاس CarModels که اصطلاحا به عنوان یه لیست برای ما عمل میکنه اسم مدل جدید را وارد کنیم ...،
این مثالی که زدید اصل OCP رو نقض میکنه ، مثلا اگه یه مدل ماشین جدید بخوایم باید بریم شروط داخل متد make رو تغییر بدیم که بازم میگم این برخلاف اصول SOLIDه ، در واقع شما میتوانستید یه کلاس تحت عنوان CarModels و اونجا یه پراپرتی models با یه متد getModels تعریف کنید ، بعد یه پراپرتی models داخل CarFactory تعریف میکردید و برای نقض نکردن اصل DIP داخل کانستراکتور اون کلاس یه کلاس CarModels میگرفتید و به پراپرتی models پاس میدادید ، سپس یه متد isValidModel تعریف و اونجا بررسی میکردید آیا دیتایی که به فانکشن پاس داده شده در دیتایی که متد getModels ( که روی پراپرتی models فرا خوانده میشه ) بر میگردونه وجود داره یا نه و فانکشن isValidModel رو داخل make صدا میزدید ، اگه مدل معتبر نبود آبجکتی از کلاس CarModelNotDefined ساخته میشد در غیر این صورت مدل پاس داده شده به فانکشن رو uppercase میکردیم و با کمک داینامیک کال و بدون هیچ شرط اضافه ای یه آبجکت از مدل مد نظرمون میساختیم ،
حالا به خیال راحت میتونیم مدلهای ماشین مختلف بسازیم و میتونیم داخل کلاس CarModels که اصطلاحا به عنوان یه لیست برای ما عمل میکنه اسم مدل جدید را وارد کنیم ...،
فکر میکنم اصل ocp بیان میکنه که اصلاح نداشته باشیم اما افزودن یک توانایی جدید مشکلی نداره. در اینجا یک مدل ماشین جدید همون افزودن توانایی هست و این اصل رو نقض نمیکنه. البته با شما موافقم که اگر یک پراپرتی داشت فکتوری ما و توی اون یک آرایه با کلید هایی از جتس مدل های ماشین و مقدار هر المان هم اسم کلاسی بود که باید ساخته میشد کد تمیزتری داشتیم.
فکر میکنم اصل ocp بیان میکنه که اصلاح نداشته باشیم اما افزودن یک توانایی جدید مشکلی نداره. در اینجا یک مدل ماشین جدید همون افزودن توانایی هست و این اصل رو نقض نمیکنه. البته با شما موافقم که اگر یک پراپرتی داشت فکتوری ما و توی اون یک آرایه با کلید هایی از جتس مدل های ماشین و مقدار هر المان هم اسم کلاسی بود که باید ساخته میشد کد تمیزتری داشتیم.
فکر میکنم اصل ocp بیان میکنه که اصلاح نداشته باشیم اما افزودن یک توانایی جدید مشکلی نداره. در اینجا یک مدل ماشین جدید همون افزودن توانایی هست و این اصل رو نقض نمیکنه. البته با شما موافقم که اگر یک پراپرتی داشت فکتوری ما و توی اون یک آرایه با کلید هایی از جتس مدل های ماشین و مقدار هر المان هم اسم کلاسی بود که باید ساخته میشد کد تمیزتری داشتیم.
حتی اکر بخواید میتونیم پا رو از این هم فراتر بذاریم و اینکه هر مدل ماشین به چه کلاسی وصله رو توی سطح کد نداشته باشیم و از فایل کانفیگ برای این موضوع استفاده کنیم. سپس توی فکتوری اون فایل کانفیگ رو بخونیم.
اینجوری اضافه کردن یک مدل جدید یا حذف اون توی کد های کلاس های ما تاثیری نمیذاشت.
حتی اکر بخواید میتونیم پا رو از این هم فراتر بذاریم و اینکه هر مدل ماشین به چه کلاسی وصله رو توی سطح کد نداشته باشیم و از فایل کانفیگ برای این موضوع استفاده کنیم. سپس توی فکتوری اون فایل کانفیگ رو بخونیم.
اینجوری اضافه کردن یک مدل جدید یا حذف اون توی کد های کلاس های ما تاثیری نمیذاشت.
خوب بود ولی توی مثال ها و توضیحات سایت های خارجی مثلا نشون میده که ممکنه کلاس PaperBook و مثلا کلاس Ebook متود های متفاوت دیگری داشته باشن که از template به ارث نبرن. این مثال شما بیشتر بدرد دیزاین پترن استراتژی میخورد
خوب بود ولی توی مثال ها و توضیحات سایت های خارجی مثلا نشون میده که ممکنه کلاس PaperBook و مثلا کلاس Ebook متود های متفاوت دیگری داشته باشن که از template به ارث نبرن. این مثال شما بیشتر بدرد دیزاین پترن استراتژی میخورد
عالی فقط یه نکته رعایت نشده
که شما اسم کلاس هارو و متود هارو یکسان نوشتید با کانستراکتور اشتباه گرفته میشه توسط php مثلا کلاس Move که متود move داخلش دا بعنوان یه متود سازنده در نظر گرفته میشه برای همین شما نمیتونی return type اش رو مشخص کنی و ارور میده
عالی فقط یه نکته رعایت نشده
که شما اسم کلاس هارو و متود هارو یکسان نوشتید با کانستراکتور اشتباه گرفته میشه توسط php مثلا کلاس Move که متود move داخلش دا بعنوان یه متود سازنده در نظر گرفته میشه برای همین شما نمیتونی return type اش رو مشخص کنی و ارور میده
عالی فقط یه نکته رعایت نشده
که شما اسم کلاس هارو و متود هارو یکسان نوشتید با کانستراکتور اشتباه گرفته میشه توسط php مثلا کلاس Move که متود move داخلش دا بعنوان یه متود سازنده در نظر گرفته میشه برای همین شما نمیتونی return type اش رو مشخص کنی و ارور میده
این موردی که شما گفتین تو نسخه 4 PHP استفاده میشد و از نسخه 5.3.3, به بعد دیگه به این صورت نیست و متدی هم نام با کلاس به عنوان کانستراکتور در نظر گرفته نمیشه
این موردی که شما گفتین تو نسخه 4 PHP استفاده میشد و از نسخه 5.3.3, به بعد دیگه به این صورت نیست و متدی هم نام با کلاس به عنوان کانستراکتور در نظر گرفته نمیشه
این موردی که شما گفتین تو نسخه 4 PHP استفاده میشد و از نسخه 5.3.3, به بعد دیگه به این صورت نیست و متدی هم نام با کلاس به عنوان کانستراکتور در نظر گرفته نمیشه
یعنی الان شما توی متود های State های مختلف میتونی Return type رو مشخص کنی و مثلا کدت رو اینشکلی تغییر بدی؟:
public function move() :ElevatorStateInterface
{
return new Move();
}
چون من ورژن php ام 8 هست و بهم ارور داد که مقدار بازگشتی متود های کانستراکتور رو نمیشه تعیین کرد!
یعنی الان شما توی متود های State های مختلف میتونی Return type رو مشخص کنی و مثلا کدت رو اینشکلی تغییر بدی؟:
public function move() :ElevatorStateInterface
{
return new Move();
}
چون من ورژن php ام 8 هست و بهم ارور داد که مقدار بازگشتی متود های کانستراکتور رو نمیشه تعیین کرد!
یعنی الان شما توی متود های State های مختلف میتونی Return type رو مشخص کنی و مثلا کدت رو اینشکلی تغییر بدی؟:
public function move() :ElevatorStateInterface
{
return new Move();
}
چون من ورژن php ام 8 هست و بهم ارور داد که مقدار بازگشتی متود های کانستراکتور رو نمیشه تعیین کرد!
این مورد برای __construct هستاما فکر نکنم برای متدی که با اسم کلاس یکیه هم باشه
این مورد برای __construct هستاما فکر نکنم برای متدی که با اسم کلاس یکیه هم باشه
سلام. ممنونم از توضیحاتتون.
در بخش توضیحات مربوط به abstract طبق منطق این کلاس باید از کدهای تکراری جلوگیری بشه ولی شما صرفا مانند intefacde ها باهاش رفتار کردید و بدنه تکراری تابع generateName رو بردید در کلاس های خودشون نوشتید که این نقض میکنه قانون dupplicate نشدن کدهارو. فکر میکنم باید ساختار اصلی کد رو هم میبردید داخل کلاس abstract و صرفا متن رو بهش پاس میدادین.
سلام. ممنونم از توضیحاتتون.
در بخش توضیحات مربوط به abstract طبق منطق این کلاس باید از کدهای تکراری جلوگیری بشه ولی شما صرفا مانند intefacde ها باهاش رفتار کردید و بدنه تکراری تابع generateName رو بردید در کلاس های خودشون نوشتید که این نقض میکنه قانون dupplicate نشدن کدهارو. فکر میکنم باید ساختار اصلی کد رو هم میبردید داخل کلاس abstract و صرفا متن رو بهش پاس میدادین.
سلام. ممنونم از توضیحاتتون.
در بخش توضیحات مربوط به abstract طبق منطق این کلاس باید از کدهای تکراری جلوگیری بشه ولی شما صرفا مانند intefacde ها باهاش رفتار کردید و بدنه تکراری تابع generateName رو بردید در کلاس های خودشون نوشتید که این نقض میکنه قانون dupplicate نشدن کدهارو. فکر میکنم باید ساختار اصلی کد رو هم میبردید داخل کلاس abstract و صرفا متن رو بهش پاس میدادین.
سلام. در اینجا echo شدن متن مثال ساده ای هست برای نشون دادن پیاده سازی های مختلفی که در هر کلاس فرزند ممکنه وجود داشته باشه. اما در صورتی که یک رفتار بین همه کلاس های فرزند مشترک باشه منطقیه که در کلاس abstract قرار بگیره
سلام. در اینجا echo شدن متن مثال ساده ای هست برای نشون دادن پیاده سازی های مختلفی که در هر کلاس فرزند ممکنه وجود داشته باشه. اما در صورتی که یک رفتار بین همه کلاس های فرزند مشترک باشه منطقیه که در کلاس abstract قرار بگیره
سلام یه اشتباهی در توضیحات شما وجود داره. در اصل context (کلاس ShoppingCart در مثال شما) هیچ مسئولیتی در قبال انتخاب الگوریتم مناسب نداره و این وظیفه برعهده client هست. و علت اصلی ای که باعث این اشتباه شده این هست که اصولن مثال شما مناسب این استراتژی نیست چراکه کاربرد این پترن بیشتر برای زمانی هست که منطق خاصی پشت انتخاب الگوریتم نباشه و اگرم هست سمت کلایند انجام میشه.
سلام یه اشتباهی در توضیحات شما وجود داره. در اصل context (کلاس ShoppingCart در مثال شما) هیچ مسئولیتی در قبال انتخاب الگوریتم مناسب نداره و این وظیفه برعهده client هست. و علت اصلی ای که باعث این اشتباه شده این هست که اصولن مثال شما مناسب این استراتژی نیست چراکه کاربرد این پترن بیشتر برای زمانی هست که منطق خاصی پشت انتخاب الگوریتم نباشه و اگرم هست سمت کلایند انجام میشه.
در واقع ما با استفاده از این دیزاین پترن میایم و یک کلاس بین کلاسه محصول و کلاسه سازنده ی محصول قرار میدیم بنام factory و حالا دیگه factory کار ساختن محصول رو برامون انجام میده.
و وقتی هم بخوایم برنامه رو توسعه بدیم کلاس factory رو توسعه میدیم و یک کلاسه محصول جدید درست میکنیم.
درسته؟
در واقع ما با استفاده از این دیزاین پترن میایم و یک کلاس بین کلاسه محصول و کلاسه سازنده ی محصول قرار میدیم بنام factory و حالا دیگه factory کار ساختن محصول رو برامون انجام میده.
و وقتی هم بخوایم برنامه رو توسعه بدیم کلاس factory رو توسعه میدیم و یک کلاسه محصول جدید درست میکنیم.
درسته؟
ممنون از مقاله خوبتون دو سوال داشتم در لاراول
۱-context همون مدل هست؟
۲-باید در مایگریشن یک فیلد برای state در نظر گرفته بشه که مقدار اون رو توی دیتا بیس ذخیره کنیم؟
به طور کلی اگر یک مقاله هم در مورد پیاده سازی این دیزاین پترن در لاراول روی سایت قرار بدید ممنون میشم
ممنون از مقاله خوبتون دو سوال داشتم در لاراول
۱-context همون مدل هست؟
۲-باید در مایگریشن یک فیلد برای state در نظر گرفته بشه که مقدار اون رو توی دیتا بیس ذخیره کنیم؟
به طور کلی اگر یک مقاله هم در مورد پیاده سازی این دیزاین پترن در لاراول روی سایت قرار بدید ممنون میشم
ممنون از مقاله خوبتون دو سوال داشتم در لاراول
۱-context همون مدل هست؟
۲-باید در مایگریشن یک فیلد برای state در نظر گرفته بشه که مقدار اون رو توی دیتا بیس ذخیره کنیم؟
به طور کلی اگر یک مقاله هم در مورد پیاده سازی این دیزاین پترن در لاراول روی سایت قرار بدید ممنون میشم
بله context رو میشه همون مدل در نظر گرفت. البته من دیدم جاهایی که توی لاراول هم context رو جدا می کنند که مدل شلوغ نشه و قانون تک وظیفه بودن هم رعایت بشه.
بله context رو میشه همون مدل در نظر گرفت. البته من دیدم جاهایی که توی لاراول هم context رو جدا می کنند که مدل شلوغ نشه و قانون تک وظیفه بودن هم رعایت بشه.
ممنون از مقاله خوبتون دو سوال داشتم در لاراول
۱-context همون مدل هست؟
۲-باید در مایگریشن یک فیلد برای state در نظر گرفته بشه که مقدار اون رو توی دیتا بیس ذخیره کنیم؟
به طور کلی اگر یک مقاله هم در مورد پیاده سازی این دیزاین پترن در لاراول روی سایت قرار بدید ممنون میشم
تو نمونه هایی که من دیدم همیشه یک ستون براش در نظر گرفته میشه داخل دیتابیس
تو نمونه هایی که من دیدم همیشه یک ستون براش در نظر گرفته میشه داخل دیتابیس
با عرض سلام، این Circuit breaker جز کدام دسته از سه دستهی الگوهای طراحی قرار میگیرد؟ و بنظرتان چرا در refactoring.guru قرار ندارد؟ با تشکر از شما
سلام. طبق سرچ من (که نتایج محدودی دقیقا روی این موضوع صحبت کرده بودن) میشه این الگو رو در دسته structural دستهبندی کرد. به نظرم خیلی روی دستهبندیها حساس نباشیم بهتره و بیشتر این الگوها رو توی ذهنمون داشته باشیم تا در موارد مناسب ازشون استفاده کنیم. در مورد این هم که چرا توی سایت refactoring.guru نیست این رو باید مد نظر قرار داد که این سایت لزوما همهی الگوها رو توضیح نداده و شما میتونید لیست بلندتر از الگوهای طراحی رو توی صفحهی ویکیپدیای اون ببینید (https://en.wikipedia.org/wiki/Software_design_pattern). توی ویکیپدیا میبینید که کلی الگوی دیگه هست که توی سایت refactoring.guru نیست. در کل خودتون رو محدود به یه سایت نکنید.
سلام. طبق سرچ من (که نتایج محدودی دقیقا روی این موضوع صحبت کرده بودن) میشه این الگو رو در دسته structural دستهبندی کرد. به نظرم خیلی روی دستهبندیها حساس نباشیم بهتره و بیشتر این الگوها رو توی ذهنمون داشته باشیم تا در موارد مناسب ازشون استفاده کنیم. در مورد این هم که چرا توی سایت refactoring.guru نیست این رو باید مد نظر قرار داد که این سایت لزوما همهی الگوها رو توضیح نداده و شما میتونید لیست بلندتر از الگوهای طراحی رو توی صفحهی ویکیپدیای اون ببینید (https://en.wikipedia.org/wiki/Software_design_pattern). توی ویکیپدیا میبینید که کلی الگوی دیگه هست که توی سایت refactoring.guru نیست. در کل خودتون رو محدود به یه سایت نکنید.
با عرض سلام، تشکر میکنم از سایت خیلی خوب شما، آموزشهای شما بسیار عالی هست، من دارم از روی این سری مطلب آموزشی شما دیزاین پترن رو یاد میگیرم، بهتر از سایت شما پیدا نکردم، چند مقاله و فیلم آموزشی قبلا دیدم ولی هیچ کدام به خوبی این مطالب نبوده است، با تشکر و با آرزوی سلامتی برای شما
با عرض سلام، تشکر میکنم از سایت خیلی خوب شما، آموزشهای شما بسیار عالی هست، من دارم از روی این سری مطلب آموزشی شما دیزاین پترن رو یاد میگیرم، بهتر از سایت شما پیدا نکردم، چند مقاله و فیلم آموزشی قبلا دیدم ولی هیچ کدام به خوبی این مطالب نبوده است، با تشکر و با آرزوی سلامتی برای شما
با عرض سلام، تشکر میکنم از سایت خیلی خوب شما، آموزشهای شما بسیار عالی هست، من دارم از روی این سری مطلب آموزشی شما دیزاین پترن رو یاد میگیرم، بهتر از سایت شما پیدا نکردم، چند مقاله و فیلم آموزشی قبلا دیدم ولی هیچ کدام به خوبی این مطالب نبوده است، با تشکر و با آرزوی سلامتی برای شما
سلام و خسته نباشید. مطالب خیلی خوب بود فقط یه سوال: اون متد constructor توی EmailBodyDecorator که اینترفیس EmailBody رو به عنوان ورودی میگیره، چه نقشی در این مثال داشت؟ همون تعریف abstract public function loadBody در کلاس EmailBodyDecorator کافی بود و همین نقش رو ایفا میکرد (حداقل در این مثال)
سلام . constructor کلاس EmailBodyDecorator یک شیء از نوع EmailBody رو به عنوان ورودی میگیره. این شیء اصلی هست که میخوایم روی اون دکوراتور اعمال کنیم. در ضمن شیء ورودی در یک متغیر ذخیره میشه تا در متدهای دیگه کلاس قابل دسترسی باشه استفاده ی زنجیره ای از دکوراتور ها هم داریم مثلا وقتی یک دکوراتور جدید ایجاد میکنیم، شیء قبلی (که خود ممکنه یک دکوراتور باشه) رو به عنوان ورودی به سازنده اون میدیم. به این ترتیب، یک زنجیره از دکوراتورها ایجاد میشه.
ممنون از توضیحات شما. اما به نظر شما الگوی استراتژی را توضیح دادید. فرض کنیم می خواهیم عملیاتی انجام بدهیم که فقط قسمتی از آن متفاوت است. مثلا عملیات دم کردن چای و دمنوش، ممکنه فقط در یک یا چند مرحله متفاوت هستند در پیاده سازی، در این سبک سناریوها ما به سراغ این الگو می رویم.
هیچی نفهمیدم :| :(
این خیلی خیلی خفن بود باحال بود کلا کیف کردم
این مثالی که زدید اصل OCP رو نقض میکنه ، مثلا اگه یه مدل ماشین جدید بخوایم باید بریم شروط داخل متد make رو تغییر بدیم که بازم میگم این برخلاف اصول SOLIDه ، در واقع شما میتوانستید یه کلاس تحت عنوان CarModels و اونجا یه پراپرتی models با یه متد getModels تعریف کنید ، بعد یه پراپرتی models داخل CarFactory تعریف میکردید و برای نقض نکردن اصل DIP داخل کانستراکتور اون کلاس یه کلاس CarModels میگرفتید و به پراپرتی models پاس میدادید ، سپس یه متد isValidModel تعریف و اونجا بررسی میکردید آیا دیتایی که به فانکشن پاس داده شده در دیتایی که متد getModels ( که روی پراپرتی models فرا خوانده میشه ) بر میگردونه وجود داره یا نه و فانکشن isValidModel رو داخل make صدا میزدید ، اگه مدل معتبر نبود آبجکتی از کلاس CarModelNotDefined ساخته میشد در غیر این صورت مدل پاس داده شده به فانکشن رو uppercase میکردیم و با کمک داینامیک کال و بدون هیچ شرط اضافه ای یه آبجکت از مدل مد نظرمون میساختیم ، حالا به خیال راحت میتونیم مدلهای ماشین مختلف بسازیم و میتونیم داخل کلاس CarModels که اصطلاحا به عنوان یه لیست برای ما عمل میکنه اسم مدل جدید را وارد کنیم ...،
فکر میکنم اصل ocp بیان میکنه که اصلاح نداشته باشیم اما افزودن یک توانایی جدید مشکلی نداره. در اینجا یک مدل ماشین جدید همون افزودن توانایی هست و این اصل رو نقض نمیکنه. البته با شما موافقم که اگر یک پراپرتی داشت فکتوری ما و توی اون یک آرایه با کلید هایی از جتس مدل های ماشین و مقدار هر المان هم اسم کلاسی بود که باید ساخته میشد کد تمیزتری داشتیم.
حتی اکر بخواید میتونیم پا رو از این هم فراتر بذاریم و اینکه هر مدل ماشین به چه کلاسی وصله رو توی سطح کد نداشته باشیم و از فایل کانفیگ برای این موضوع استفاده کنیم. سپس توی فکتوری اون فایل کانفیگ رو بخونیم. اینجوری اضافه کردن یک مدل جدید یا حذف اون توی کد های کلاس های ما تاثیری نمیذاشت.
این الگو زیاد در php کاربرد نداره و فکر میکنم بیشتر بدرد اپلیکیشن هایی که با زبانی مثل جاوا ساخته میشه بخوره
خوب بود ولی توی مثال ها و توضیحات سایت های خارجی مثلا نشون میده که ممکنه کلاس PaperBook و مثلا کلاس Ebook متود های متفاوت دیگری داشته باشن که از template به ارث نبرن. این مثال شما بیشتر بدرد دیزاین پترن استراتژی میخورد
عالی فقط یه نکته رعایت نشده که شما اسم کلاس هارو و متود هارو یکسان نوشتید با کانستراکتور اشتباه گرفته میشه توسط php مثلا کلاس Move که متود move داخلش دا بعنوان یه متود سازنده در نظر گرفته میشه برای همین شما نمیتونی return type اش رو مشخص کنی و ارور میده
این موردی که شما گفتین تو نسخه 4 PHP استفاده میشد و از نسخه 5.3.3, به بعد دیگه به این صورت نیست و متدی هم نام با کلاس به عنوان کانستراکتور در نظر گرفته نمیشه
یعنی الان شما توی متود های State های مختلف میتونی Return type رو مشخص کنی و مثلا کدت رو اینشکلی تغییر بدی؟: public function move() :ElevatorStateInterface { return new Move(); } چون من ورژن php ام 8 هست و بهم ارور داد که مقدار بازگشتی متود های کانستراکتور رو نمیشه تعیین کرد!
این مورد برای __construct هستاما فکر نکنم برای متدی که با اسم کلاس یکیه هم باشه
عالی بود
مقاله خوبی نوشتید
خیلی خوب بود:] میشه برای مثال خیلی بارز به میدلور های لاراول اشاره کرد
مثالی که زدید مناسب این الگو نیست و یه جورایی هم فکتوری پیاده کردید همچنین open/close رو هم رعایت نکردید.
سلام. ممنونم از توضیحاتتون. در بخش توضیحات مربوط به abstract طبق منطق این کلاس باید از کدهای تکراری جلوگیری بشه ولی شما صرفا مانند intefacde ها باهاش رفتار کردید و بدنه تکراری تابع generateName رو بردید در کلاس های خودشون نوشتید که این نقض میکنه قانون dupplicate نشدن کدهارو. فکر میکنم باید ساختار اصلی کد رو هم میبردید داخل کلاس abstract و صرفا متن رو بهش پاس میدادین.
سلام. در اینجا echo شدن متن مثال ساده ای هست برای نشون دادن پیاده سازی های مختلفی که در هر کلاس فرزند ممکنه وجود داشته باشه. اما در صورتی که یک رفتار بین همه کلاس های فرزند مشترک باشه منطقیه که در کلاس abstract قرار بگیره
ممنون
سلام یه اشتباهی در توضیحات شما وجود داره. در اصل context (کلاس ShoppingCart در مثال شما) هیچ مسئولیتی در قبال انتخاب الگوریتم مناسب نداره و این وظیفه برعهده client هست. و علت اصلی ای که باعث این اشتباه شده این هست که اصولن مثال شما مناسب این استراتژی نیست چراکه کاربرد این پترن بیشتر برای زمانی هست که منطق خاصی پشت انتخاب الگوریتم نباشه و اگرم هست سمت کلایند انجام میشه.
پر قدرت ادامه بدین. ممنون
در واقع ما با استفاده از این دیزاین پترن میایم و یک کلاس بین کلاسه محصول و کلاسه سازنده ی محصول قرار میدیم بنام factory و حالا دیگه factory کار ساختن محصول رو برامون انجام میده. و وقتی هم بخوایم برنامه رو توسعه بدیم کلاس factory رو توسعه میدیم و یک کلاسه محصول جدید درست میکنیم. درسته؟
ممنون از مقاله خوبتون دو سوال داشتم در لاراول ۱-context همون مدل هست؟ ۲-باید در مایگریشن یک فیلد برای state در نظر گرفته بشه که مقدار اون رو توی دیتا بیس ذخیره کنیم؟ به طور کلی اگر یک مقاله هم در مورد پیاده سازی این دیزاین پترن در لاراول روی سایت قرار بدید ممنون میشم
بله context رو میشه همون مدل در نظر گرفت. البته من دیدم جاهایی که توی لاراول هم context رو جدا می کنند که مدل شلوغ نشه و قانون تک وظیفه بودن هم رعایت بشه.
تو نمونه هایی که من دیدم همیشه یک ستون براش در نظر گرفته میشه داخل دیتابیس
با عرض سلام، این Circuit breaker جز کدام دسته از سه دستهی الگوهای طراحی قرار میگیرد؟ و بنظرتان چرا در refactoring.guru قرار ندارد؟ با تشکر از شما
سلام. طبق سرچ من (که نتایج محدودی دقیقا روی این موضوع صحبت کرده بودن) میشه این الگو رو در دسته structural دستهبندی کرد. به نظرم خیلی روی دستهبندیها حساس نباشیم بهتره و بیشتر این الگوها رو توی ذهنمون داشته باشیم تا در موارد مناسب ازشون استفاده کنیم. در مورد این هم که چرا توی سایت refactoring.guru نیست این رو باید مد نظر قرار داد که این سایت لزوما همهی الگوها رو توضیح نداده و شما میتونید لیست بلندتر از الگوهای طراحی رو توی صفحهی ویکیپدیای اون ببینید (https://en.wikipedia.org/wiki/Software_design_pattern). توی ویکیپدیا میبینید که کلی الگوی دیگه هست که توی سایت refactoring.guru نیست. در کل خودتون رو محدود به یه سایت نکنید.
با عرض سلام، تشکر میکنم از سایت خیلی خوب شما، آموزشهای شما بسیار عالی هست، من دارم از روی این سری مطلب آموزشی شما دیزاین پترن رو یاد میگیرم، بهتر از سایت شما پیدا نکردم، چند مقاله و فیلم آموزشی قبلا دیدم ولی هیچ کدام به خوبی این مطالب نبوده است، با تشکر و با آرزوی سلامتی برای شما
ما هم خوشحالیم که آموزش هامون براتون مفید هستند.