|
| 1 | +--- |
| 2 | +title: "الگوی طراحی Abstract Factory در جاوا: مهارت در ایجاد شیء با ظرافت" |
| 3 | +shortTitle: Abstract Factory |
| 4 | +description: "با مثالهای دنیای واقعی، دیاگرامهای کلاس و آموزشها، الگوی Abstract Factory را در جاوا بیاموزید. منظور، کاربرد، مزایا و نمونههای واقعی آن را درک کنید و دانش طراحی الگوهایتان را افزایش دهید." |
| 5 | +category: Creational |
| 6 | +language: fa |
| 7 | +tag: |
| 8 | + - Abstraction |
| 9 | + - Decoupling |
| 10 | + - Gang of Four |
| 11 | + - Instantiation |
| 12 | + - Polymorphism |
| 13 | +--- |
| 14 | + |
| 15 | +## همچنین به این عنوان شناخته میشود |
| 16 | + |
| 17 | +* کیت |
| 18 | + |
| 19 | +## هدف از الگوی طراحی Abstract Factory |
| 20 | + |
| 21 | +الگوی Abstract Factory در جاوا یک واسط برای ایجاد خانوادههایی از اشیای مرتبط یا وابسته فراهم میکند بدون آنکه کلاسهای مشخص آنها را تعیین کند، و این کار موجب افزایش مدولاریتی و انعطافپذیری در طراحی نرمافزار میشود. |
| 22 | + |
| 23 | +## توضیح دقیق الگوی Abstract Factory با مثالهای دنیای واقعی |
| 24 | + |
| 25 | +مثال دنیای واقعی |
| 26 | + |
| 27 | +> تصور کنید یک شرکت مبلمان وجود دارد که از الگوی Abstract Factory در جاوا برای تولید سبکهای مختلف مبلمان استفاده میکند: مدرن، ویکتوریایی و روستایی. هر سبک شامل محصولاتی مانند صندلیها، میزها و کاناپهها است. برای اطمینان از یکنواختی در هر سبک، شرکت از یک الگوی Abstract Factory استفاده میکند. |
| 28 | +> |
| 29 | +> در این سناریو، Abstract Factory یک واسط برای ایجاد خانوادههایی از اشیای مبلمان مرتبط (صندلیها، میزها، کاناپهها) است. هر Factory مشخص (کارخانهی مبلمان مدرن، کارخانهی مبلمان ویکتوریایی، کارخانهی مبلمان روستایی) این واسط را پیادهسازی میکند و مجموعهای از محصولات مطابق با سبک خاص ایجاد میکند. به این ترتیب، مشتریان میتوانند یک مجموعه کامل از مبلمان مدرن یا ویکتوریایی ایجاد کنند بدون اینکه نگران جزئیات ساخت آنها باشند. این باعث حفظ یکنواختی سبک میشود و امکان تغییر آسان سبک مبلمان را فراهم میکند. |
| 30 | +
|
| 31 | +به زبان ساده |
| 32 | + |
| 33 | +> کارخانهای از کارخانهها؛ یک Factory یا کارخانه که مجموعهای از کارخانههای مرتبط یا وابسته را بدون مشخص کردن کلاسهای concrete آنها گروهبندی میکند. |
| 34 | +
|
| 35 | +ویکیپدیا میگوید |
| 36 | + |
| 37 | +> الگوی Abstract Factory راهی برای کپسوله کردن مجموعهای از کارخانههای منحصر به فرد با یک تم مشترک بدون تعیین کلاسهای concrete آنها فراهم میکند. |
| 38 | +
|
| 39 | +دیاگرام کلاس |
| 40 | + |
| 41 | + |
| 42 | + |
| 43 | +## مثال برنامهنویسی از Abstract Factory در جاوا |
| 44 | + |
| 45 | +برای ایجاد یک پادشاهی با استفاده از الگوی Abstract Factory در جاوا، ما به اشیایی با یک تم مشترک نیاز داریم. یک پادشاهی اِلف (Elf) به یک پادشاه اِلف، یک قلعهی اِلف، و یک ارتش اِلف نیاز دارد، در حالی که یک پادشاهی اورک (Orc) به یک پادشاه اورک، یک قلعهی اورک، و یک ارتش اورک نیاز دارد. بین اشیای موجود در پادشاهی وابستگی وجود دارد. |
| 46 | + |
| 47 | +ترجمهی مثال پادشاهی بالا. ابتدا ما برخی واسطها و پیادهسازیهایی برای اشیای موجود در پادشاهی داریم: |
| 48 | + |
| 49 | +```java |
| 50 | +public interface Castle { |
| 51 | + String getDescription(); |
| 52 | +} |
| 53 | + |
| 54 | +public interface King { |
| 55 | + String getDescription(); |
| 56 | +} |
| 57 | + |
| 58 | +public interface Army { |
| 59 | + String getDescription(); |
| 60 | +} |
| 61 | + |
| 62 | +// Elven implementations -> |
| 63 | +public class ElfCastle implements Castle { |
| 64 | + static final String DESCRIPTION = "This is the elven castle!"; |
| 65 | + |
| 66 | + @Override |
| 67 | + public String getDescription() { |
| 68 | + return DESCRIPTION; |
| 69 | + } |
| 70 | +} |
| 71 | + |
| 72 | +public class ElfKing implements King { |
| 73 | + static final String DESCRIPTION = "This is the elven king!"; |
| 74 | + |
| 75 | + @Override |
| 76 | + public String getDescription() { |
| 77 | + return DESCRIPTION; |
| 78 | + } |
| 79 | +} |
| 80 | + |
| 81 | +public class ElfArmy implements Army { |
| 82 | + static final String DESCRIPTION = "This is the elven Army!"; |
| 83 | + |
| 84 | + @Override |
| 85 | + public String getDescription() { |
| 86 | + return DESCRIPTION; |
| 87 | + } |
| 88 | +} |
| 89 | + |
| 90 | +// Orcish implementations similarly -> ... |
| 91 | +``` |
| 92 | + |
| 93 | +سپس واسط و پیادهسازیهای کارخانهی پادشاهی را داریم: |
| 94 | + |
| 95 | +```java |
| 96 | +public interface KingdomFactory { |
| 97 | + Castle createCastle(); |
| 98 | + King createKing(); |
| 99 | + Army createArmy(); |
| 100 | +} |
| 101 | + |
| 102 | +public class ElfKingdomFactory implements KingdomFactory { |
| 103 | + |
| 104 | + @Override |
| 105 | + public Castle createCastle() { |
| 106 | + return new ElfCastle(); |
| 107 | + } |
| 108 | + |
| 109 | + @Override |
| 110 | + public King createKing() { |
| 111 | + return new ElfKing(); |
| 112 | + } |
| 113 | + |
| 114 | + @Override |
| 115 | + public Army createArmy() { |
| 116 | + return new ElfArmy(); |
| 117 | + } |
| 118 | +} |
| 119 | + |
| 120 | +// Orcish implementations similarly -> ... |
| 121 | +``` |
| 122 | + |
| 123 | +اکنون میتوانیم یک کارخانه برای کارخانههای مختلف پادشاهی طراحی کنیم. در این مثال، ما `FactoryMaker` را ایجاد کردیم که مسئول برگرداندن یک نمونه از `ElfKingdomFactory` یا `OrcKingdomFactory` است. مشتری می تواند از `FactoryMaker` برای ایجاد کارخانه concrete مورد نظر استفاده کند که به نوبه خود اشیاء concrete مختلف (مشتق شده از ارتش، پادشاه، قلعه) را تولید میکند. در این مثال، ما همچنین از یک enum برای پارامتری کردن نوع کارخانه پادشاهی که مشتری درخواست خواهد کرد استفاده کردیم. |
| 124 | + |
| 125 | +```java |
| 126 | +public static class FactoryMaker { |
| 127 | + |
| 128 | + public enum KingdomType { |
| 129 | + ELF, ORC |
| 130 | + } |
| 131 | + |
| 132 | + public static KingdomFactory makeFactory(KingdomType type) { |
| 133 | + return switch (type) { |
| 134 | + case ELF -> new ElfKingdomFactory(); |
| 135 | + case ORC -> new OrcKingdomFactory(); |
| 136 | + }; |
| 137 | + } |
| 138 | +} |
| 139 | +``` |
| 140 | + |
| 141 | +نمونهای از تابع اصلی برنامه: |
| 142 | + |
| 143 | +```java |
| 144 | +LOGGER.info("elf kingdom"); |
| 145 | +createKingdom(Kingdom.FactoryMaker.KingdomType.ELF); |
| 146 | +LOGGER.info(kingdom.getArmy().getDescription()); |
| 147 | +LOGGER.info(kingdom.getCastle().getDescription()); |
| 148 | +LOGGER.info(kingdom.getKing().getDescription()); |
| 149 | + |
| 150 | +LOGGER.info("orc kingdom"); |
| 151 | +createKingdom(Kingdom.FactoryMaker.KingdomType.ORC); |
| 152 | +LOGGER.info(kingdom.getArmy().getDescription()); |
| 153 | +LOGGER.info(kingdom.getCastle().getDescription()); |
| 154 | +LOGGER.info(kingdom.getKing().getDescription()); |
| 155 | +``` |
| 156 | + |
| 157 | +خروجی برنامه: |
| 158 | + |
| 159 | +``` |
| 160 | +07:35:46.340 [main] INFO com.iluwatar.abstractfactory.App -- elf kingdom |
| 161 | +07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the elven army! |
| 162 | +07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the elven castle! |
| 163 | +07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the elven king! |
| 164 | +07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- orc kingdom |
| 165 | +07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the orc army! |
| 166 | +07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the orc castle! |
| 167 | +07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the orc king! |
| 168 | +``` |
| 169 | + |
| 170 | +## چه زمانی باید از الگوی Abstract Factory در جاوا استفاده کرد؟ |
| 171 | + |
| 172 | +* زمانی که سیستم باید مستقل از نحوهی ایجاد، ترکیب و نمایش محصولاتش باشد. |
| 173 | +* زمانی که نیاز به پیکربندی سیستم با یکی از چند خانواده محصول دارید. |
| 174 | +* زمانی که باید خانوادهای از اشیای مرتبط با هم استفاده شوند، برای اطمینان از یکنواختی. |
| 175 | +* زمانی که میخواهید کتابخانهای از محصولات را فراهم کنید و فقط واسطهای آنها را نمایان کنید، نه پیادهسازیها را. |
| 176 | +* زمانی که طول عمر وابستگیها کوتاهتر از مصرفکننده باشد. |
| 177 | +* زمانی که نیاز به ساخت وابستگیها با مقادیر یا پارامترهای زمان اجرا باشد. |
| 178 | +* زمانی که باید در زمان اجرا انتخاب کنید که کدام خانواده از محصول را استفاده کنید. |
| 179 | +* زمانی که افزودن محصولات یا خانواده های جدید نباید نیاز به تغییر در کد موجود داشته باشد. |
| 180 | + |
| 181 | +## آموزشهای الگوی Abstract Factory در جاوا |
| 182 | + |
| 183 | +* [Abstract Factory Design Pattern in Java (DigitalOcean)](https://www.digitalocean.com/community/tutorials/abstract-factory-design-pattern-in-java) |
| 184 | +* [Abstract Factory (Refactoring Guru)](https://refactoring.guru/design-patterns/abstract-factory) |
| 185 | + |
| 186 | +## مزایا و معایب الگوی Abstract Factory |
| 187 | + |
| 188 | +مزایا: |
| 189 | + |
| 190 | +> * انعطافپذیری: به راحتی میتوان خانوادههای محصول را تعویض کرد بدون تغییر کد. |
| 191 | +
|
| 192 | +> * جداسازی (Decoupling): کد مشتری فقط با واسطهای انتزاعی کار میکند که باعث قابلیت حمل و نگهداری میشود. |
| 193 | +
|
| 194 | +> * قابلیت استفاده مجدد: کارخانههای انتزاعی و محصولات امکان استفاده مجدد از مؤلفهها را فراهم میکنند. |
| 195 | +
|
| 196 | +> * قابلیت نگهداری: تغییرات در خانوادههای محصول محلی شده و بهروزرسانی را سادهتر میکند. |
| 197 | +
|
| 198 | +معایب: |
| 199 | + |
| 200 | +> * پیچیدگی: تعریف واسطهای انتزاعی و کارخانههای مشخص سربار اولیه ایجاد میکند. |
| 201 | +
|
| 202 | +> * غیرمستقیم بودن: کد مشتری از طریق کارخانهها با محصولات کار میکند که ممکن است شفافیت را کاهش دهد. |
| 203 | +
|
| 204 | +## نمونههای واقعی استفاده از الگوی Abstract Factory در جاوا |
| 205 | + |
| 206 | +* کلاسهای `LookAndFeel` در Java Swing برای ارائه گزینه های مختلف look-and-feel |
| 207 | +* پیادهسازیهای مختلف در Java AWT برای ایجاد اجزای مختلف GUI |
| 208 | +* [javax.xml.parsers.DocumentBuilderFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html) |
| 209 | +* [javax.xml.transform.TransformerFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/transform/TransformerFactory.html#newInstance--) |
| 210 | +* [javax.xml.xpath.XPathFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/xpath/XPathFactory.html#newInstance--) |
| 211 | + |
| 212 | +## الگوهای طراحی مرتبط با جاوا |
| 213 | + |
| 214 | +* الگوی [Factory Method](https://java-design-patterns.com/patterns/factory-method/): الگوی کارخانهی انتزاعی از روشهای کارخانهای برای ایجاد محصولات استفاده میکند. |
| 215 | +* الگوی [Singleton](https://java-design-patterns.com/patterns/singleton/): کلاسهای کارخانهی انتزاعی اغلب به صورت Singleton پیادهسازی میشوند. |
| 216 | +* الگوی [Factory Kit](https://java-design-patterns.com/patterns/factory-kit/): مشابه کارخانهی انتزاعی اما بر پیکربندی و مدیریت مجموعهای از اشیای مرتبط تمرکز دارد. |
| 217 | + |
| 218 | +## منابع و ارجاعات |
| 219 | + |
| 220 | +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI) |
| 221 | +* [Design Patterns in Java](https://amzn.to/3Syw0vC) |
| 222 | +* [Head First Design Patterns: Building Extensible and Maintainable Object-Oriented Software](https://amzn.to/49NGldq) |
| 223 | +* [Java Design Patterns: A Hands-On Experience with Real-World Examples](https://amzn.to/3HWNf4U) |
0 commit comments