فروشگاه لباس (تا پایان جلسه دوازدهم)
سطح سوال: سخت
آنچه از این جلسه باید بدانید: آشنایی با واسط (Interface)
یک فروشگاه لباس برای نگهداری اطلاعات لباسهای خود از یک برنامهی جاوا استفاده میکند. این فروشگاه چهار نوع لباس (Clothing) دارد که برای هر یک، یک کلاس درنظر گرفته شده است:
- جوراب (Socks)
- پیراهن (Shirt)
- شلوار (Pants)
- ژاکت (Jacket)
برای هر لباس نیز سه ویژگی مشترک نگهداری میشود:
- نام: name
- فصل مناسب برای پوشیدن لباس: season (بهار، تابستان، پاییز و زمستان)
- قیمت پایه: basePrice
یک رفتار مهم و تغییرپذیر در این برنامه، محاسبهی قیمت هر لباس با توجه به تخفیفهای مختلف (زمستانه، شب یلدا و …) است که هماکنون با این منطق پیادهسازی شدهاست:
- در تخفیف تابستانه: لباسهای بهاری: 40% تخفیف، لباسهای تابستانی: 50% تخفیف و لباسهای زمستانه: 30% تخفیف.
- در تخفیف زمستانه: لباسهای پاییزی: 40% تخفیف، لباسهای زمستانی: 50% تخفیف و لباسهای تابستانی: 25% تخفیف. به علاوه، تمامی ژاکتها از 10% تخفیف دیگر نیز برخوردار هستند. یعنی یک ژاکت پاییزی ابتدا 40% از قیمتش کسر میشود چون لباس پاییزیست و سپس مجددا 10% دیگر نیز از قیمتش کاسته میشود.
- در تخفیف شب یلدا: تمامی ژاکتها: 10% تخفیف، تمامی جورابها: 20% تخفیف و بقیهی لباسها: 25% تخفیف.
برنامهنویس، در نسخهی قدیمی این برنامه در کلاس Clothing یک متد به نامgetPrice با ورودی نوع تخفیف (discountType) قرار داده بود که با توجه به نوع تخفیف، نوع لباس و ویژگیهای لباس، قیمت نهایی را محاسبه میکرد:
public long getPrice(DiscountType discountType) { if (discountType == DiscountType.YALDA) { // return with YALDA discount } else if (discountType == DiscountType.SUMMER) { // return with SUMMER discount } else if (discountType == DiscountType.WINTER) { // return with WINTER discount } return price; }
حال پس از چند ماه مسئول فروشگاه از او میخواهد چند نوع تخفیف جدید برای مناسبتهای مختلف اضافه کرده و رفتار چند نوع تخفیف موجود را تغییر دهد. برنامهنویس متوجه مسالهای میشود؛ با اضافهکردن این تغییرات به متد getPrice و تغییرات احتمالی آینده، این متد رفتهرفته بزرگتر و ناخواناتر میشود. او با مطالعهی سرفصلهای چندریختی (Polymorphism) و واسط (Interface) از سایت جاواکاپ به ایدهی جدیدی میرسد. او برای شروع، متد getPrice خود را حذف میکند؛ ولی او این مباحث را بهتازگی مطالعه کردهاست، پس به او کمک کنید تا ایدهی خود را پیادهسازی کند.
ابتدا بستهی ir.javacup.shop را دانلود کنید.
او میخواهد وظیفهی محاسبهی هر تخفیف را به کلاسهای مجزایی بسپارد. برای این کار ابتدا یک واسط به نام DiscountStrategy ایجاد کنید:
public interface DiscountStrategy { long priceByDiscount(Clothing clothing); }
سپس به ازای هر نوع تخفیف، یک کلاس ایجاد کنید که این واسط را پیادهسازی میکند. در متدpriceByDiscount هر یک از این کلاسها باید رفتار نوع تخفیف مربوطه را پیادهسازی کنید:
- برای تخفیف تابستانه: کلاس SummerDiscountStrategy
- برای تخفیف زمستانه: کلاس WinterDiscountStrategy
- برای تخفیف شب یلدا: کلاس YaldaDiscountStrategy
در کلاس Clothing متد زیر را برای دریافت و ثبت نوع تخفیف فعلی پیادهسازی کنید:
public void setDiscountStrategy(DiscountStrategy discountStrategy) { // TODO set discountStrategy }
حال در متد getPrice جدید (که دیگر پارامتر ورودی ندارد) با استفاده از discountStrategy مشخصشده، قیمت با تخفیف را محاسبه کرده و برگردانید:
public long getPrice() { // TODO get price by considering discountStrategy }
اگر هیچ discountStrategyای تعیین نشده بود، باید قیمت پایهی لباس برگردانده شود.
مثال:
Jacket linenCoat = new Jacket("Linen Coat", Season.FALL, 100000); System.out.println("Linen Coat: " + linenCoat.getPrice()); linenCoat.setDiscountStrategy(new YaldaDiscountStrategy()); System.out.println("Linen Coat with Yalda discount: " + linenCoat.getPrice()); linenCoat.setDiscountStrategy(new WinterDiscountStrategy()); System.out.println("Linen Coat with Winter discount: " + linenCoat.getPrice()); Clothing woolenSocks = new Pants("Woolen Socks", Season.WINTER, 10000); System.out.println("Woolen Socks: " + woolenSocks.getPrice()); woolenSocks.setDiscountStrategy(new SummerDiscountStrategy()); System.out.println("Woolen Socks with Summer discount: " + woolenSocks.getPrice()); woolenSocks.setDiscountStrategy(new WinterDiscountStrategy()); System.out.println("Woolen Socks with Winter discount: " + woolenSocks.getPrice());
خروجی:
Linen Coat: 100000 Linen Coat with Yalda discount: 90000 Linen Coat with Winter discount: 54000 Woolen Socks: 10000 Woolen Socks with Summer discount: 7000 Woolen Socks with Winter discount: 5000
نکته:
متد getPrice از کلاس Clothing نباید از نحوهی محاسبهی تخفیفهای مختلف خبر داشته باشد. به عبارت دیگر، تمام منطق محاسبهی هر نوع تخفیف باید در کلاس مربوط به خود نوشته شود.
آنچه باید آپلود کنید:
یک فایل زیپ شامل بستهی ir.javacup.shop است. به صورتی که وقتی فایل زیپ را باز میکنیم، دقیقا شاخهی ir را ببینیم که درون آن شاخهی javacup و درون آن نیز شاخهی shop قرار دارد. در داخل شاخهی shop پنج فایل با نامهای Clothing.java و DiscountStrategy.java و SummerDiscountStrategy.java و WinterDiscountStrategy.java و YaldaDiscountStrategy.java باید وجود داشته باشد.
برای داوری تمرین، میتوانید پاسخ خود را در سایت Quera به نحوی که در بالا گفته شد، بارگذاری کنید.
با ما همراه باشید:
آدرس کانال تلگرام: IranianJavaDevelopers@
آدرس صفحه اینستاگرام: javacup.ir
آدرس گروه لینکدین: Iranian Java Developers
سلام . واسه متد setDiscountStrategy با توجه به اینکه discountStrategy یه ورودی از نوع Clothing میگیره نمیدونم چجوری باید پیاده سازیش کنم میشه راهنماییم کنید؟
سلام
لطفا در کوئرا در بخش «سوال بپرسید» سوالتون رو مطرح کنید. تیم پشتیبانی راهنماییتون میکنن.
سلام میشه جواب این سوال رو برای ایمیلم ارسال کنید خیلی نیاز دارم.ممنون
سلام
خیر متاسفانه. امکان انتشار پاسخ سوالات به هیچ روشی وجود ندارد.
با سلام و عرض خسته نباشید بسته ir.javacup.shop قابل دانلود نمیباشذ لطفا بررسی کتید …
با تشکر از سایت خوبتون
سلام
ما بررسی کردیم و ظاهرا مشکلی وجود نداشت.
لطفا یکبار دیگر تلاش کنید.
با تشکر