Understanding Design Patterns in Software
Understanding Design Patterns in Software
ﺟﯿﺖ ﺗﻘﺪم ﺣﻠﻮل ﻧﻤﻮذﺟﯿﮫ وﻓﻌﺎﻟﮫ ﻟﻤﺸﺎﻛﻞ ﻗﺒﻠﻨﺎھﺎ ﻗﺒﻞ ﻛﺪه وﻋﺸﺎن ﻛﺪه ﻣﻦ اﻟﻤﮭﻢ اﻧﻚ ﺗﻌﺮف ﻓﻲ Design patterns
وﻋﻠﺸﺎن ﺗﻘﺪر ﺗﺤﻞ اﻟﻤﺸﺎﻛﻞ دي وﺗﻘﺪر ﺗﻌﻤﻞ object Oriented Software
اﻗﺪر اﻋﻤﻠﮫ
: re-useable-1ﻧﻘﺪر ﻧﻌﯿﺪ اﺳﺘﻌﻤﺎﻟﮫ
: Maintainability -2ﻗﺎﺑﻞ ﻟﻠﺼﯿﺎﻧﮫ واﻟﺘﻌﺪﯾﻞ ﻓﯿﮫ
It’s more of general concept for solving problems rather than a piece of code
ھﻲ ﻋﺒﺎره ﻋﻦ general conceptﻣﻤﻜﻦ ﺗﻌﻤﻞ ﻟﯿﮭﺎ customizationﺣﺴﺐ اﻟﻤﺸﻜﻠﮫ او اﻟﻜﻮد ﺑﺘﺎﻋﻚ
o
ﺟﮫ ﯾﻮﻓﺮ ﻟﯿﻨﺎ ﺣﻠﻮل ﻟﻌﻼﻗﮫ ال objectﺑﺒﻌﻀﮭﺎ اﻟﺒﻌﺾ وازاي ﻧﻘﺪر ﻧﺠﻤﻌﮭﺎ ف structureﻛﺒﯿﺮ
ﯾﻌﻨﻲ زي ﻟﻤﺎ ﺗﻜﻮن ﺑﺘﺒﻨﻲ ﻋﻤﺎرة ﻻزم ﺗﻌﺮف إزاي ﺗﺮﺑﻂ اﻟﻐﺮف ﺑﺒﻌﻀﮭﺎ
SOLID
-----------------------------
M
ﻣﺒﺎدئ SOLIDدي زي اﻟﻘﻮاﻋﺪ اﻟﻠﻲ ﺑﺘﻤﺸﻲ ﻋﻠﯿﮭﺎ وإﻧﺖ ﺑﺘﻜﺘﺐ ﻛﻮد ﻋﺸﺎن ﻟﻤﺎ اﻟﺪﻧﯿﺎ ﺗﻜﺒﺮ ﻣﺎ ﺗﻘﻌﺶ ﻋﻠﻰ دﻣﺎﻏﻚ .
Single Responsibility: A class should have only reason to change • اﻟـ S -ﯾﻌﻨﻲ ﻛﻞ ﺣﺎﺟﺔ ﻟﯿﮭﺎ ﺷﻐﻼﻧﺔ واﺣﺪة ﺑﺲ:
ﯾﻌﻨﻲ ﻟﻤﺎ ﺗﻌﻤﻞ ﻛﻼس ﻣﺎ ﺗﺤﻄﺶ ﻓﯿﮫ ﻛﻞ ﺣﺎﺟﺔ ﻛﻞ ﻛﻼس ﯾﺒﻘﻰ ﻣﺴﺆول ﻋﻦ ﺣﺎﺟﺔ واﺣﺪة .
زي ﻟﻮ ﻋﻨﺪك ﺳﻮﺑﺮ ﻣﺎرﻛﺖ ﻣﺎ ﺗﺨﻠﯿﺶ اﻟﻠﻲ ﺑﯿﺤﺎﺳﺐ ھﻮ ﻧﻔﺴﮫ اﻟﻠﻲ ﺑﯿﺤﻂ اﻟﺒﻀﺎﻋﺔ ﻋﻠﻰ اﻟﺮﻓﻮف ﻛﻞ واﺣﺪ ﻟﯿﮫ ﺷﻐﻼﻧﺘﮫ.
ﻣﺜﺎل :ﻟﻮ ﻋﻨﺪك ﻛﻼس ﺑﯿﻌﻤﻞ ﺣﺴﺎﺑﺎت اﻟﺮواﺗﺐ ﻣﺎ ﺗﺨﻠﯿﮭﻮش ھﻮ ﻧﻔﺴﮫ اﻟﻠﻲ ﯾﺒﻌﺖ إﯾﻤﯿﻼت ﻟﻠﻤﻮظﻔﯿﻦ ﺧﻠﻲ ﻛﻼس ﺗﺎﻧﻲ ﯾﻌﻤﻞ ﺷﻐﻞ اﻹﯾﻤﯿﻼت.
o
• اﻟـ O -ﯾﻌﻨﻲ ﺧﻠﻲ اﻟﻜﻼس ﻣﻔﺘﻮح ﻟﻠﺰﯾﺎدة ﺑﺲ ﻣﺶ ﻟﻠﺘﻌﺪﯾﻞ:
Open Closed principle (OCP) : Software entities should open for extension but closed for modification
et • ﯾﻌﻨﻲ ﻟﻤﺎ ﺗﻌﻤﻞ ﺣﺎﺟﺔ ،ﻟﻮ ﻋﺎﯾﺰ ﺗﻀﯿﻒ ﻋﻠﯿﮭﺎ ﺑﻌﺪﯾﻦ ﻣﺎ ﺗﻀﻄﺮش ﺗﻜﺴﺮ اﻟﻜﻮد اﻟﻘﺪﯾﻢ.
زي ﻟﻮ ﺑﺘﺒﻨﻲ ﺑﯿﺖ ﻣﻤﻜﻦ ﺗﺰود أوﺿﺔ ﻣﻦ ﻏﯿﺮ ﻣﺎ ﺗﮭﺪ اﻟﻠﻲ ﺑﻨﯿﺘﮫ.
ﻣﺜﺎل :ﻟﻮ ﻋﻨﺪك ﻛﻼس ﺑﯿﺤﺴﺐ اﻟﺨﺼﻢ وﻛﻞ ﻣﺎ ﯾﺠﯿﻠﻚ ﻧﻮع ﺧﺼﻢ ﺟﺪﯾﺪ ﺑﺘﻐﯿﺮ ﻓﻲ اﻟﻜﻼس ده ﻏﻠﻂ .
اﻋﻤﻞ إﻧﺘﺮﻓﯿﺲ وﻛﻞ ﻧﻮع ﺧﺼﻢ ﯾﺒﻘﻰ ﻓﻲ ﻛﻼس ﻟﻮﺣﺪه ﻋﺸﺎن ﺗﻀﯿﻒ ﺑﺴﮭﻮﻟﺔ ﻣﻦ ﻏﯿﺮ ﻣﺎ ﺗﻐﯿﺮ اﻟﻘﺪﯾﻢ.
Sh
•
• اﻟـ L -ﯾﻌﻨﻲ اﻟﻠﻲ ﯾﯿﺠﻲ ﻣﻜﺎن اﻟﻠﻲ ﻗﺒﻠﮫ ﻻزم ﯾﺸﺘﻐﻞ زﯾﮫ:
Liskov substitution : If C is a subtype of P then object of type P in a program may be replaced with
_R
object of type C without altering any of the desirable properties of that program
ﯾﻌﻨﻲ ﻟﻮ ﻋﻨﺪك ﻛﻼس أب وﻛﻼس اﺑﻦ ﻣﻨﮫ ،اﻻﺑﻦ ﻻزم ﯾﻘﺪر ﯾﺸﺘﻐﻞ ﻣﻜﺎن اﻷب ﻣﻦ ﻏﯿﺮ ﻣﺎ ﯾﻌﻤﻞ ﻣﺸﺎﻛﻞ .زي ﻟﻮ ﻋﻨﺪك ﻣﻮﺑﺎﯾﻞ ﻗﺪﯾﻢ وﻣﻮﺑﺎﯾﻞ ﺟﺪﯾﺪ ،ﻻزم اﻟﺠﺪﯾﺪ ﯾﻌﻤﻞ ﻛﻞ
ﺣﺎﺟﺔ اﻟﻘﺪﯾﻢ ﻛﺎن ﺑﯿﻌﻤﻠﮭﺎ وأﻛﺘﺮ ،ﻣﺶ أﻗﻞ.
ﻣﺜﺎل :ﻟﻮ ﻋﻨﺪك ﻛﻼس" ﻋﺮﺑﯿﺔ "وﻛﻼس اﺑﻦ ﻣﻨﮫ" ﻋﺮﺑﯿﺔ ﺳﺒﺎق" ،ﻻزم" ﻋﺮﺑﯿﺔ ﺳﺒﺎق "ﺗﻘﺪر ﺗﺘﺤﻂ ﻓﻲ أي ﺣﺘﺔ ﻛﻨﺖ ﺑﺘﺤﻂ ﻓﯿﮭﺎ" ﻋﺮﺑﯿﺔ "ﻣﻦ ﻏﯿﺮ ﻣﺎ اﻟﺴﯿﺴﺘﻢ ﯾﻔﺮﻗﻊ.
M
ﯾﻌﻨﻲ ﻟﻮ ﻋﻨﺪك إﻧﺘﺮﻓﯿﺲ ﻓﯿﮫ ﻣﯿﺜﻮدات ﻛﺘﯿﺮ ،ﻣﺎ ﺗﺠﺒﺮش ﻛﻞ ﻛﻼس ﯾﺴﺘﺨﺪم ﻛﻞ اﻟﻤﯿﺜﻮدات دي .زي ﻟﻮ ﺑﺘﻌﻤﻞ ﻋﻘﺪ ﺷﻐﻞ ،ﻣﺎ ﺗﺤﻄﺶ ﻓﯿﮫ ﺣﺎﺟﺎت ﻣﺶ ھﺘﻨﻔﻊ اﻟﻠﻲ ھﯿﻮﻗّﻊ.
ﻣﺜﺎل :ﻟﻮ ﻋﻨﺪك إﻧﺘﺮﻓﯿﺲ ﻓﯿﮫ ﻣﯿﺜﻮد" ﯾﻄﯿﺮ "وﻣﯿﺜﻮد" ﯾﻌﻮم" ،ﻣﺎ ﺗﺠﺒﺮش ﻛﻼس" ﻛﻠﺐ "ﯾﻨﻔﺬ" ﯾﻄﯿﺮ" ،ﻗﺴّﻢ اﻹﻧﺘﺮﻓﯿﺲ ﻟﺠﺰﺋﯿﻦ ،ﺟﺰء ﻟﻠﻲ ﺑﯿﻄﯿﺮ وﺟﺰء ﻟﻠﻲ ﺑﯿﻌﻮم.
Dependency inversion : high level modules should not depend on low level modules both should depend on abstraction
abstraction should not depend on detail details the should depend on abstraction
ﯾﻌﻨﻲ اﻟﻜﻼﺳﺎت اﻟﻜﺒﯿﺮة ﻣﺎ ﺗﻌﺘﻤﺪش ﻋﻠﻰ اﻟﻜﻼﺳﺎت اﻟﺼﻐﯿﺮة ﺑﺸﻜﻞ ﻣﺒﺎﺷﺮ ﺧﻠﻲ ﻓﯿﮫ إﻧﺘﺮﻓﯿﺲ وﺳﯿﻂ.
زي ﻟﻮ ﺑﺘﺒﻨﻲ ﻣﺸﺮوع ﻣﺎ ﺗﺘﻌﺎﻣﻠﺶ ﻣﻊ اﻟﻌﻤﺎل واﺣﺪ واﺣﺪ اﺗﻌﺎﻣﻞ ﻣﻊ اﻟﻤﻘﺎول وھﻮ ﯾﻈﺒﻂ.
ﻣﺜﺎل :ﻟﻮ ﻋﻨﺪك ﻛﻼس ﺑﯿﺴﺘﺨﺪم ﻗﺎﻋﺪة ﺑﯿﺎﻧﺎت ، MySQLﻣﺎ ﺗﻌﻤﻠﺶ اﻟﺮﺑﻂ ﻣﺒﺎﺷﺮة ،اﻋﻤﻞ إﻧﺘﺮﻓﯿﺲ" داﺗﺎﺑﯿﺰ "وﺧﻠّﻲ اﻟﻜﻼس ﯾﻌﺘﻤﺪ ﻋﻠﯿﮫ ،ﻋﺸﺎن ﻟﻮ ﻏﯿﺮت ﻟـ
PostgreSQLﻣﺎ ﺗﺘﻌﺒﻜﺶ.
r n s
t te
Pa
ra l o
et
v i o
Sh
e h a
B
R_
M
Mahmoud Shetawy
Design-Pattern Page 3
Strategy Pattern
Tuesday, July 1, 2025 2:49 PM
ˉﺴﻢ ﷲ اﻟﺮﲪﻦ اﻟﺮﺣﲓ
ﻟﯿﺠﺰي ﷲ اﻟﺼﺎدﻗﲔ ﺑﺼﺪﻗﻬﻢ
Strategy Pattern
ھﻮ ﻧﻤﻂ ﺗﺼﻤﯿﻢ ﺳﻠﻮﻛﻲ ﺑﻨﺴﺘﺨﺪﻣﮫ ﻟﻤﺎ ﯾﻜﻮن ﻋﻨﺪﻧﺎ أﻛﺘﺮ ﻣﻦ طﺮﯾﻘﺔ ﻟﺤﻞ ﻣﺸﻜﻠﺔ ﻣﻌﯿﻨﺔ وﻛﻞ طﺮﯾﻘﺔ دي ﺧﻮارزﻣﯿﺔ ﻣﺴﺘﻘﻠﺔ.
اﻟﻔﻜﺮة إﻧﮫ ﺑﯿﻔﺼﻞ طﺮﯾﻘﺔ اﻟﺘﻨﻔﯿﺬ ﻋﻦ اﻟﻜﻼس اﻟﻠﻲ ﺑﯿﺴﺘﺨﺪﻣﮭﺎ ﺑﺤﯿﺚ ﺗﻘﺪر ﺗﻐﯿﺮ طﺮﯾﻘﺔ اﻟﺘﻨﻔﯿﺬ دي واﻧﺖ ﺷﻐﺎل ﻣﻦ ﻏﯿﺮ ﻣﺎ ﺗﻌﺪل ﻓﻲ اﻟﻜﻼس اﻷﺳﺎﺳﻲ.
إﻧﻚ ﺗﺨﻠﻲ ﻋﻨﺪك ﻣﺮوﻧﺔ ﻛﺒﯿﺮة ﻓﻲ اﺧﺘﯿﺎر وﺗﺒﺪﯾﻞ اﻟﻄﺮق ﺑﺪل ﻣﺎ ﯾﺒﻘﻰ ﻋﻨﺪك ﺷﻮﯾﺔ if elseﺟﻮا اﻟﻜﻼس
ﺑﺘﺨﻠﻲ ﻛﻞ طﺮﯾﻘﺔ ﻓﻲ ﻛﻼس ﻟﻮﺣﺪھﺎ واﻟﻜﻼس اﻟﺮﺋﯿﺴﻲ ﻣﺎ ﯾﻌﺮﻓﺶ أي ﺗﻔﺎﺻﯿﻞ ﻋﻨﮭﻢ
ھﻮ ﺑﺲ ﺑﯿﺴﺘﺪﻋﯿﮭﻢ ﻋﻦ طﺮﯾﻖ interfaceﻣﻮﺣﺪ
o
زﺑﻮن ﻋﺎوز اﻟﺘﻮﺻﯿﻞ ﯾﻜﻮن ﺑﺄرﺧﺺ طﺮﯾﻘﺔ )ﻣﺸﻲ ً
ﻣﺜﻼ(
{ )"if (type == "walking زﺑﻮن ﺗﺎﻧﻲ ﻣﺴﺘﻌﺠﻞ وﻋﺎوز ﻋﺮﺑﯿﺔ.
ﺣﺴﺎب ﺗﻜﻠﻔﺔ اﻟﻤﺸﻲ // زﺑﻮن ﺗﺎﻟﺖ ﻋﻨﺪه ﺷﺤﻨﺔ ﻛﺒﯿﺮة وﻋﺎوز ﺷﺎﺣﻨﺔ
{ )"} else if (type == "car
ﺣﺴﺎب ﺗﻜﻠﻔﺔ اﻟﻌﺮﺑﯿﺔ //
{ )"} else if (type == "truck
et ﻟﻮ اﻧﺖ ﻛﻞ ﻣﺮة ھﺘﻜﺘﺐ ﻛﻮد ﺑﺎﻟﺸﻜﻞ ده:
Sh
ﺣﺴﺎب ﺗﻜﻠﻔﺔ اﻟﺸﺎﺣﻨﺔ //
}
ھﺘﻼﻗﻲ ﻧﻔﺴﻚ ﺑﻌﺪ ﺷﮭﺮ:
اﻟﻜﻮد اﺗﻌﻘﺪ ﺟﺪا
ﻛﻞ ﻣﺎ ﺗﺤﺐ ﺗﻀﯿﻒ طﺮﯾﻘﺔ ﺟﺪﯾﺪة ھﺘﺪﺧﻞ ﺗﻌﺪل ﺟﻮه اﻟﻜﻮد اﻷﺳﺎﺳﻲ.
ﻟﻮ ﺣﺼﻞ ﺧﻄﺄ ھﺘﻔﻀﻞ ﺗﺪور ﻓﻲ اﻟﺸﺮوط.
_R
.3ﺗﺎﻟت ﺣﺎﺟﺔ Contextوده اﻟﻛﻼس اﻟﻠﻲ ﺑﯾﺳﺗﺧدم اﻻﺳﺗراﺗﯾﺟﯾﺔ وﺑﯾﻧﺎدي ﻋﻠﯾﮭﺎ وﻗت ﻣﺎ ﯾﺣﺗﺎج ﯾﻧﻔذ اﻟﺳﻠوك.
#################################################################
where different products may have varying pricing logic based on factors such as customer segment.
then at the checkout the customer could pay with different methods like PayPal, VisaCard and Bank_Transfer.
Each payment method vary in it’s logic of processing the payment and conducting required fees
o
et
Sh
R_
if ([Link](PaymentMethod.VISA_CARD)) {
[Link]("Processing PAYPALPayment");
else if ([Link](PaymentMethod.BANK_TRANSFER)) {
،Strategy Pattern وده اﻟﻠﻲ ﺑﻌﺪ ﻛﺪه ھﻨﺤﺴﻨﮫ ﻋﻦ طﺮﯾﻖ إﻧﻨﺎ ﻧﻔﺼﻞ ﻛﻞ طﺮﯾﻘﺔ دﻓﻊ ﻓﻲ ﻛﻼس ﻣﺴﺘﻘﻞ وﻧﺴﺘﺨﺪم
. ﻛﻞ ﻣﺮةif else ﺑﺤﯿﺚ ﻟﻮ ﺣﺒﯿﻨﺎ ﻧﻀﯿﻒ طﺮﯾﻘﺔ دﻓﻊ ﺟﺪﯾﺪة ﻣﺶ ھﻨﻀﻄﺮ ﻧﻌﺪل اﻟـ
واﻟـ Productواﻟـ Checkoutﻣﺎ ﺑﻘﻮش ﯾﻌﺮﻓﻮا ﺗﻔﺎﺻﯿﻞ اﻟﺘﻨﻔﯿﺬ ﻛﻞ اﻟﻠﻲ ﺑﯿﻌﻤﻠﻮه إﻧﮭﻢ ﺑﯿﻨﺎدوا ﻋﻠﻰ اﻟـ Strategyاﻟﻠﻲ اﺗﺤﺪدت
ده ﺧﻠﻰ اﻟﻜﻮد ﻣﺮن ﺟﺪًا وﺳﮭﻞ إﻧﻨﺎ ﻧﻀﯿﻒ أي طﺮﯾﻘﺔ ﺟﺪﯾﺪة ﻓﻲ اﻟﻤﺴﺘﻘﺒﻞ ﻣﻦ ﻏﯿﺮ ﻣﺎ ﻧﻌﺪل أي ﺣﺎﺟﺔ ﻓﻲ اﻟﻜﻼﺳﺎت اﻷﺳﺎﺳﯿﺔ
o
CODE : Mahmoud-Shetawy/Design-Pattern
ﺑﺺ ﯾﺎ ﺳﯿﺪي اﻟـ Strategy Patternﺑﺘﺴﺘﺨﺪﻣﮫ ﻓﻲ اﻟﺤﺎﻻت اﻟﻠﻲ ﺑﯿﺒﻘﻰ ﻋﻨﺪك ﻓﯿﮭﺎ ﻧﻔﺲ اﻟﮭﺪف اﻟﻨﮭﺎﺋﻲ ﺑﺲ اﻟﻄﺮق اﻟﻠﻲ ﺑﺘﺤﻘﻖ اﻟﮭﺪف ده ﻣﺨﺘﻠﻔﺔ وﻣﻤﻜﻦ ﺗﺘﻐﯿﺮ.
ﻣﻼﺣﻈﺔ ﻣﻔﯿﺪة
M
ﻟﻮ اﻟﻄﺮق او اﻟﻌﻤﻠﯿﺎت اﻟﻠﻲ ﻋﻨﺪك ﺑﺴﯿﻄﺔ ﺟﺪا وﻣﺎﻓﯿﺶ ﻓﺮوق ﺟﻮھﺮﯾﺔ ﺑﯿﻨﮭﻢ ﺳﺎﻋﺘﮭﺎ ﻣﻤﻜﻦ ﺗﻜﺘﻔﻲ إﻧﻚ ﺗﺴﺘﺨﺪم polymorphismاﻟﻌﺎدي
Template Method
ھﻮ أﺳﻠﻮب ﺗﺼﻤﯿﻢ ﺑﯿﺴﻤﺤﻠﻚ ﺗﻜﺘﺐ ﺗﺴﻠﺴﻞ ﺛﺎﺑﺖ ﻟﺨﻄﻮات ﻣﻌﯿﻨﺔ ﻓﻲ ﻛﻼس أﺳﺎﺳﻲ Abstract Class
وﺗﺴﯿﺐ ﺗﻔﺎﺻﯿﻞ ﺗﻨﻔﯿﺬ اﻟﺨﻄﻮات ﻟﻠﻜﻼﺳﺎت اﻟﻔﺮﻋﯿﺔ Subclassesاﻟﻨﻤﻂ ده ﺑﯿﻮﻓﺮﻟﻚ طﺮﯾﻘﺔ ﺗﺤﻜﻢ واﺿﺤﺔ ﻓﻲ ﺗﺮﺗﯿﺐ اﻟﺨﻄﻮات ﺑﺲ ﻣﻦ
ﻏﯿﺮ ﻣﺎ ﺗﺠﺒﺮ اﻟﻜﻼﺳﺎت اﻟﺘﺎﻧﯿﺔ ﺗﻠﺘﺰم ﺑﻨﻔﺲ اﻟﺘﻔﺎﺻﯿﻞ
ده ھو إﻧﻧﺎ ﻧﺣﻘﻖ ﻣﺑدأ اﻟـ ") Don't Repeat Yourself" (DRYﺑﺷﻛل ﻓﻌﺎل ﺟدا ً.
ﺑدل ﻣﺎ ﻧﻛﺗب ﻧﻔس اﻟﻛود اﻟﻠﻲ ﺑﯾﻣﺛل اﻟﺧطوات اﻟﺛﺎﺑﺗﺔ ﻓﻲ أﻛﺗر ﻣن ﻣﻛﺎن ﺑﻧﺣطﮫ ﻣرة واﺣدة ﺑس ﻓﻲ اﻟﻛﻼس اﻷب وﺑﻧﺧﻠﻲ اﻟﻛﻼﺳﺎت اﻷﺑﻧﺎء ھﻲ اﻟﻠﻲ ﺗﮭﺗم ﺑﺗﻔﺎﺻﯾل
اﻟﺧطوات اﻟﻣﺗﻐﯾرة .ده ﺑﯾﺧﻠﻲ اﻟﻛود أﻧﺿف وأﺳﮭل ﻓﻲ اﻟﺻﯾﺎﻧﺔ واﻟﺗﻌدﯾل.
و إﻧك ﺗﺿﻣن إن ﻛل اﻟﻌﻣﻠﯾﺎت اﻟﻠﻲ ﺑﺗﺗم ﻋﻠﻰ ﻧﻔس ال Workflowﻣﺎﺷﯾﺔ ﺑﻧﻔس اﻟﺗرﺗﯾب وﺑﻧﻔس اﻟﮭﯾﻛل
ﻟﻛن ﻓﻲ ﻧﻔس اﻟوﻗت ﺗدي ﺣرﯾﺔ ﻟﻠﻛﻼﺳﺎت اﻟﻔرﻋﯾﺔ إﻧﮭﺎ ﺗﺣدد ﺗﻔﺎﺻﯾل اﻟﺗﻧﻔﯾذ ﻟوﺣدھﺎ ده ﺑﯾﺧﻠﻲ اﻟﻛود ﻣﻧظم وﻗﺎﺑل ﻹﻋﺎدة اﻻﺳﺗﺧدام وﺳﮭل اﻟﺻﯾﺎﻧﺔ
o
et ﺗﺨﯿﻞ ﻣﺜﻼ إن ﻋﻨﺪك ﺑﺮﻧﺎﻣﺞ ﺑﯿﻘﺮأ ﺑﯿﺎﻧﺎت ﻣﻦ أﻛﺘﺮ ﻣﻦ ﻣﺼﺪر زي ﻗﺎﻋﺪة ﺑﯿﺎﻧﺎت وAPI
وﻣﻠﻒ ﻧﺼﻲ ﻓﻲ ﻛﻞ ﺣﺎﻟﺔ اﻧﺖ ﻋﺎﯾﺰ ﺗﻨﻔﺬ ﻧﻔﺲ اﻟﺨﻄﻮات ﺑﺎﻟﻈﺒﻂ ﻓﺘﺢ اﻻﺗﺼﺎل ﺟﻠﺐ اﻟﺒﯿﺎﻧﺎت ﻏﻠﻖ اﻻﺗﺼﺎل ﻟﻜﻦ طﺮﯾﻘﺔ ﺗﻨﻔﯿﺬ ﻛﻞ ﺧﻄﻮة ﺑﺘﺨﺘﻠﻒ ھﻨﺎ Template
Methodﺑﯿﻜﻮن ﻣﺜﺎﻟﻲ
Sh
_R
M
Memento Pattern
ﻓﻜﺮﺗﮫ اﻷﺳﺎﺳﯿﺔ ھﻲ إﻧﻚ ﺗﺤﻔﻆ ﺣﺎﻟﺔ ﻛﺎﺋﻦ ) (objectﻓﻲ ﻟﺤﻈﺔ ﻣﻌﯿﻨﺔ وﺗﺮﺟﻊ ﻟﮫ اﻟﺤﺎﻟﺔ دي ﻓﻲ أي وﻗﺖ ﻻﺣﻖ ﻣﻦ ﻏﯿﺮ ﻣﺎ ﺗﻜﺴﺮ ﻣﺒﺪأ اﻟﻜﺒﺴﻮﻟﺔ )(encapsulation
ﯾﻌﻨﻲ اﻟﻜﺎﺋﻦ ﯾﻔﻀﻞ ﻣﺤﺎﻓﻆ ﻋﻠﻰ ﺣﺎﻟﺘﮫ اﻟﺪاﺧﻠﯿﺔ وﻣﺤﺪش ﯾﻘﺪر ﯾﻌﺒﺚ ﺑﯿﮭﺎ ﻟﻜﻦ ﻓﻲ ﻧﻔﺲ اﻟﻮﻗﺖ ﻧﻘﺪر ﻧﻌﻤﻞ ﻟﮫ "ﺣﻔﻆ" و"اﺳﺘﺮﺟﺎع" ﻟﻠﺤﺎﻟﺔ.
اوھﻮ patternﺑﯿﺴﻤﺤﻠﻚ ﺗﺤﻔﻆ snapshotﻣﻦ ﺣﺎﻟﺔ objectﻣﻌﯿﻦ ﻓﻲ وﻗﺖ ﻣﻌﯿﻦ وﺗﺮﺟﻌﻠﮫ ﺑﻌﺪﯾﻦ ﻟﻮ ﺣﺼﻞ ﺣﺎﺟﺔ
ﯾﻌﻨﻲ ﻟﻮ ﺑﺘﻜﺘﺐ ﺣﺎﺟﺔ ﻓﻲ ﻣﻠﻒ وﻛﺘﺒﺖ ﻛﻼم ﻛﺘﯿﺮ وﺑﻌﺪﯾﻦ ﺿﻐﻄﺖ Ctrl + Z
اﻟﺒﺮﻧﺎﻣﺞ ﺑﯿﺮﺟﻌﻚ ﻟﺤﺎﻟﺔ أﻗﺪم ﻣﻦ اﻟﻜﻼم اﻟﻠﻲ ﻛﻨﺖ ﻛﺎﺗﺒﮫ
إﻣﺘﻰ ﺗﺴﺘﺨﺪﻣﮫ؟
o
ﻟﻤﺎ ﯾﻜﻮن ﻋﻨﺪك objectﺣﺎﻟﺘﮫ ﺑﺘﺘﻐﯿﺮ ﻛﺘﯿﺮوﻋﺎﯾﺰ ﺗﻘﺪر ﺗﺮﺟﻊ ورا ﻷي ﻟﺤﻈﺔ ﻣﻦ ﻏﯿﺮ ﻣﺎ ﺗﻐﯿﺮ اﻟﻜﺎﺋﻦ ﺑﺈﯾﺪك
وﻓﻲ ﻧﻔﺲ اﻟﻮﻗﺖ ﻋﺎﯾﺰ ﺗﺤﺎﻓﻆ ﻋﻠﻰ إن اﻟـ dataﺟﻮا اﻟﻜﺎﺋﻦ ﻣﺘﺒﻘﺎش ﻣﻜﺸﻮﻓﺔ ﻟﺒﺮا
ﺑﯿﺘﻜﻮن ﻣﻦ إﯾﮫ؟
ﻓﯿﮫ ٣أطﺮاف رﺋﯿﺴﯿﯿﻦ ﻓﻲ Memento Pattern
Originator .1
M
وده ھﻮ اﻟـ objectاﻟﻠﻲ ﺣﺎﻟﺘﮫ ﺑﺘﺘﻐﯿﺮ وھﻮ اﻟﻠﻲ ﺑﯿﺨﻠﻖ اﻟـ Mementoوﺑﯿﺴﺘﺮﺟﻌﮫ
Memento .2
Caretaker .3
ده اﻟﻠﻲ ﺑﯿﺨﺰن اﻟـ Mementosوﺑﯿﻄﻠﺐ ﻣﻦ Originatorﯾﺮﺟﻊ ﺣﺎﻟﺔ ﻣﻌﯿﻨﺔ ﻟﻤﺎ ﯾﺤﺐ
.3ﺑﻌﺪ ﺷﻮﯾﺔ ﻟﻮ اﻟﺤﺎﻟﺔ ﺗﻐﯿﺮت واﻟﻤﺴﺘﺨﺪم ﻋﺎﯾﺰ ﯾﺮﺟﻊ Caretakerﯾﺒﻌﺚ Mementoﻟﻠـ Originatorو Originatorﯾﺮﺟﻊ ﻟﺤﺎﻟﺘﮫ اﻟﺴﺎﺑﻘﺔ
o
et ﻣﺶ ﻓﺎھﻢ
Visitor Patternﻓﻜﺮﺗﮫ إﻧﻚ ﺗﻔﺼﻞ اﻟﻌﻤﻠﯿﺎت ) (operationsاﻟﻠﻲ ﺑﺘﺘﻄﺒﻖ ﻋﻠﻰ ﻣﺠﻤﻮﻋﺔ ﻛﺎﺋﻨﺎت ﻣﺨﺘﻠﻔﺔ ﻋﻦ اﻟﻜﺎﺋﻨﺎت ﻧﻔﺴﮭﺎ
ﯾﻌﻨﻲ ﻣﺶ ﻛﻞ ﻛﺎﺋﻦ ھﯿﺤﺘﻮي ﻋﻠﻰ ﻛﻞ اﻟﻮظﺎﯾﻒ اﻟﻠﻲ ﺑﺘﺘﻌﻤﻞ ﻋﻠﯿﮫ ﻟﻜﻦ ﺗﻘﺪر ﺗﺒﻌﺘﻠﮫ )(Visitor
واﻟﺰاﺋﺮ ده ﯾﻌﺮف ﯾﻄﺒﻖ اﻟﻌﻤﻠﯿﺔ اﻟﻤﻄﻠﻮﺑﺔ ﻣﻦ ﻏﯿﺮ ﻣﺎ ﯾﻌﺪل ﻋﻠﻰ اﻟﻜﺎﺋﻦ ﻧﻔﺴﮫ
ﻧﺨﻠﻲ اﻟﻜﺎﺋﻦ ﻧﻔﺴﮫ ﺑﺴﯿﻂ وﻧﺒﻌﺘﮫ "ﯾﺰور" ﻛﻼس ﺗﺎﻧﻲ ﻓﯿﮫ اﻟﻌﻤﻠﯿﺎت دي ﻛﻠﮭﺎ واﻟﻜﺎﺋﻦ ﯾﺴﻤﺢ ﻟﻠـ visitorﯾﻨﻔﺬ ﻋﻠﯿﮫ اﻟﻠﻲ ھﻮ ﻋﺎﯾﺰه
ﺑﻜﺪه اﻟﻜﺎﺋﻦ ﻣﺶ ﺑﯿﺘﻐﯿﺮ واﻟﻌﻤﻠﯿﺎت ﺑﺘﻔﻀﻞ ﻣﻨﻈﻤﺔ ﻓﻲ ﻣﻜﺎن واﺣﺪ
o
et اﻷطﺮاف اﻟﻤﺸﺎرﻛﺔ
ﻓﯿﮫ ﻛﺬا طﺮف ﺑﯿﺸﺘﻐﻠﻮا ﻓﻲ Visitor Pattern
Sh
ﺗﻌﺎﻟﻰ ﻧﻮﺿﺤﮭﻢ ﺑﺒﺴﺎطﺔ:
) Element .1أو (Visitable
ده اﻟﻜﺎﺋﻦ اﻟﻠﻲ ھﯿﺘﻢ ﻋﻠﯿﮫ اﻟﻌﻤﻠﯿﺎت ﺑﯿﺤﺘﻮي ﻋﻠﻰ methodواﺣﺪة اﺳﻤﮭﺎ ) accept(Visitor visitorاﻟﻠﻲ ﺑﯿﺨﻠﻲ اﻟﺰاﺋﺮ ﯾﺪﺧﻞ وﯾﺸﺘﻐﻞ ﻋﻠﯿﮫ
Visitor .2
_R
ده اﻟﻜﺎﺋﻦ اﻟﻠﻲ ﺑﯿﺤﻤﻞ اﻟﻌﻤﻠﯿﺎت ﺟﻮاه methodﻟﻜﻞ ﻧﻮع ﻣﻦ ﻋﻨﺎﺻﺮ Elementﯾﻌﻨﻲ ﻟﻮ ﻋﻨﺪﻧﺎ ﻛﺎﺋﻨﯿﻦ )ﻣﺜﻼً Fileو (Folderھﯿﻜﻮن ﺟﻮاه ) visit(File fو )visit(Folder f
ده اﻟﻜﺎﺋﻦ اﻟﻔﻌﻠﻲ اﻟﻠﻲ ھﯿﺘﻨﻔﺬ ﻋﻠﯿﮫ اﻟﺰﯾﺎرة وﺑﯿﻄﺒﻖ )( acceptوﺑﯿﺴﺘﺪﻋﻲ ﻓﯿﮭﺎ )[Link](this
M
ده اﻟﻠﻲ ﺑﯿﺤﻤﻞ اﻟﻌﻤﻠﯿﺎت اﻟﻔﻌﻠﯿﺔ وﺑﯿﻄﺒﻖ )( visitﻟﻜﻞ ﻧﻮع ﻣﻦ اﻟﻌﻨﺎﺻﺮ اﻟﻠﻲ ﻋﻨﺪك
ﯾﺒﻘﻰ اﻟﺤﻞ؟
ھﻮ اﺳﺘﺨﺪام Visitor Patternﻋﻠﺸﺎن ﺗﻀﯿﻒ ﺳﻠﻮك ﺟﺪﯾﺪ )إدارة اﻹﺟﺎزات( ﻣﻦ ﻏﯿﺮ ﻣﺎ ﺗﻌﺪل ﻓﻲ اﻟﻜﻼﺳﺎت اﻷﺳﺎﺳﯿﺔ
ھﺪﻓﮫ إﻧﻚ ﺗﻮﻓﺮ طﺮﯾﻘﺔ ﻣﻮﺣﺪة ﻟﻠﺘﻨﻘﻞ ) (iterationﺟﻮه ﻣﺠﻤﻮﻋﺔ ﻋﻨﺎﺻﺮ )(collection
ﺑﻨﺴﺘﺨﺪﻣﮫ ﻟﯿﮫ؟
ﻋﻠﺸﺎن ﺗﻔﺼﻞ طﺮﯾﻘﺔ اﻟﺘﻌﺎﻣﻞ ﻣﻊ اﻟﻌﻨﺎﺻﺮ ﻋﻦ طﺮﯾﻘﺔ ﺗﺨﺰﯾﻨﮭﻢ
ﻋﻠﺸﺎن ﺗﻘﺪر ﺗﻐﯿﺮ اﻟـ structureاﻟﺪاﺧﻠﻲ )زي ﺗﺘﺤﻮل ﻣﻦ Listﻟـ (Treeﻣﻦ ﻏﯿﺮ ﻣﺎ ﺗﻐﯿﺮ طﺮﯾﻘﺔ اﻟﺘﻌﺎﻣﻞ ﻣﻊ اﻟﺒﯿﺎﻧﺎت ﻧﻔﺴﮭﺎ
ﻋﻠﺸﺎن ﺗﻮﺣﺪ طﺮﯾﻘﺔ اﻟﺘﻜﺮار ﻋﻠﻰ ﻣﺠﻤﻮﻋﺎت ﻣﺨﺘﻠﻔﺔ ﺣﺘﻰ ﻟﻮ ﻛﻞ واﺣﺪة ﻣﺘﺨﺰﻧﺔ ﺑﺸﻜﻞ ﻣﺨﺘﻠﻒ
o
ﺗﺨﯿﻞ ﻣﻌﺎﯾﺎ ﻋﻨﺪك ﻛﺎﺋﻦ اﺳﻤﮫ EmployeeListﻓﯿﮫ Arrayداﺧﻠﻲ ﻟﻮ ﺟﯿﺖ ﺗﻤﺸﻲ ﻋﻠﯿﮫ ھﺘﺤﺘﺎج ﺗﻌﻤﻞ for loopﻋﻠﯿﮫ ﺟﻮا اﻟﻜﻮد اﻟﻠﻲ ﺑﯿﺴﺘﺨﺪﻣﮫ
وﻟﻮ ﺑﻜﺮة ﻗﺮرت ﺗﺨﺰﻧﮫ ﻓﻲ LinkedListﺑﺪل Arrayھﺘﺤﺘﺎج ﺗﻌﯿﺪ ﻛﺘﺎﺑﺔ اﻟﻜﻮد ﻛﻠﮫ اﻟﻠﻲ ﻛﺎن ﺑﯿﺴﺘﺨﺪﻣﮫ
et ده اﺳﻤﮫ couplingﻋﺎﻟﻲ ﺟﺪًا ﺑﯿﻦ اﻟﺒﻨﯿﺔ وطﺮﯾﻘﺔ اﻟﺘﻌﺎﻣﻞ ﻣﻌﮭﺎ
اﻓﺼﻞ اﻟـ structureﻋﻦ طﺮﯾﻘﺔ اﻟﺘﻜﺮار ﺧﻠﻲ اﻟﻜﺎﺋﻦ ﻧﻔﺴﮫ ﯾﺪﯾﻠﻚ ﻛﺎﺋﻦ ﺗﺎﻧﻲ اﺳﻤﮫ " "Iteratorھﻮ اﻟﻠﻲ ﻣﺴﺆول ﯾﻤﺸﻲ ﻋﻠﻰ اﻟﻌﻨﺎﺻﺮ واﺣﺪة واﺣﺪة
Sh
اﻟـ Patternده ﺑﯾﺗﻛون ﻣن ﺧﻣس أطراف رﺋﯾﺳﯾﯾن ﻛل واﺣد ﻟﯾﮫ وظﯾﻔﺔ ﻣﺣددة وﻣﻧﻔﺻﻠﺔ ﺗﻣﺎ ًﻣﺎ
_R
ده Interfaceﻓﯾﮫ دوال ﺑﺳﯾطﺔ زي hasNextو nextﯾﻌﻧﻲ ﺑﯾﺳﺄﻟك "ھل ﻓﯾﮫ ﻋﻧﺻر ﺗﺎﻧﻲ؟" و"ھﺎﺗﻠﻲ اﻟﻌﻧﺻر اﻟﻠﻲ ﺑﻌده"
ده اﻟﻛﻼس اﻟﻠﻲ ﺑﯾﻧﻔذ ﻓﻌﻠﯾﺎ اﻟـ Interfaceاﻟﻠﻲ ﻓوق وﺑﯾﺣﺗﻔظ ﺑﻣؤﺷر داﺧﻠﻲ ﻋﻠﺷﺎن ﯾﻌرف ﻣﻛﺎﻧﮫ ﻓﯾن ﻓﻲ اﻟﻣﺟﻣوﻋﺔ ھو اﻟﻠﻲ ﺑﯾﺗﺣرك ﺧطوة ﺧطوة ﺟوا اﻟـ Collection
ده Interfaceﺑﯾﻘول إن اﻟﻛﺎﺋن ده ﻣﻣﻛن ﯾﺗﻌﻣﻠﮫ Iteratorﯾﻌﻧﻲ ﺑﯾﺣﺗوي ﻋﻠﻰ داﻟﺔ واﺣدة اﺳﻣﮭﺎ createIterator
ده اﻟﻛﺎﺋن اﻟﻠﻲ ﻓﻌﻠﯾﺎ ﺑﯾﺧزن اﻟﺑﯾﺎﻧﺎت زي Listأو Setوﺑﯾوﻓر ﻧﺳﺧﺔ Iteratorﻟﻣﺎ ﺣد ﯾطﻠب
وده اﻟﻣﺳﺗﺧدم اﻟﻧﮭﺎﺋﻲ اﻟﻠﻲ ﺑﯾﺎﺧد اﻟـ Iteratorوﯾﻣﺷﻲ ﺑﯾﮫ ﻋﻠﻰ اﻟﻌﻧﺎﺻر ﻣن ﻏﯾر ﻣﺎ ﯾﻌرف أي ﺗﻔﺎﺻﯾل داﺧﻠﯾﺔ
إﻧﺖ ﻋﻨﺪك Systemﻹدارة اﻟﻤﻮظﻔﯿﻦ وﻣﻄﻠﻮب ﻣﻨﻚ ﺗﻀﯿﻒ طﺮﯾﻘﺔ ﻣﻨﻈﻤﺔ ﻟﺘﻤﻜﯿﻦ أي ﺣﺪ ﺑﯿﺴﺘﺨﺪم اﻟﻤﻜﺘﺒﺔ دي إﻧﮫ ﯾﻠﻒ ) (iterateﻋﻠﻰ اﻟﻤﻮظﻔﯿﻦ داﺧﻞ ھﯿﻜﻞ اﻟﺸﺮﻛﺔ.
ﯾﻌﻨﻲ ً
ﻣﺜﻼ:
ﻟﻮ ﻣﻌﺎك ﻣﻮظﻒ ﺗﻘﺪر ﺗﺠﯿﺐ اﻟـ Direct Reportsﺑﺘﻮﻋﮫ )اﻟﻠﻲ ﺗﺤﺘﮫ ﻓﻲ اﻟﮭﯿﻜﻞ(
ﺗﻘﺪر ﺗﺠﯿﺐ زﻣﺎﯾﻠﮫ ﻓﻲ ﻧﻔﺲ اﻟﻤﺴﺘﻮى ) (Co-workersوﺗﻘﺪر ﻛﻤﺎن ﺗﻤﺸﻲ ﻋﻠﻰ اﻟـ Subordinatesﺑﺘﻮﻋﮫ )ﻛﻞ اﻟﻠﻲ ﺗﺤﺘﮫ ﻓﻲ اﻟﺸﺠﺮة(
M
ﯾﺒﻘﻰ اﻟﺤﻞ اﻟﻜﻼﺳﯿﻜﻲ ھﻨﺎ ھﻮ ﺗﻄﺒﯿﻖ Iterator Patternﻣﺨﺼﺺ ﻟﻜﻞ ﻧﻮع ﻋﻼﻗﺔ
ﺗﻌﺎل ﻧﻤﺸﻲ ﺧﻄﻮة ﺑﺨﻄﻮة ﺑﺄﺳﻠﻮب واﺿﺢ واﺣﺘﺮاﻓﻲ
o
أھﻢ اﻷﻧﻮاع اﻟﻠﻲ ﺗﺤﺖ Structural Patterns
Facade
Composite
_R
Bridge
Proxy
Flyweight
M
Decorator
ﻟﻮ ﻋﻨﺪك ﻛﺎﺋﻦ وﻋﺎﯾﺰ ﺗﺰودﻟﮫ وظﺎﺋﻒ ﺟﺪﯾﺪة ﻣﻦ ﻏﯿﺮ ﻣﺎ ﺗﻐﯿﺮه ﻓﺒﺘﻠﻔﮫ ﺑﻜﺎﺋﻦ ﺗﺎﻧﻲ ﯾﺰودﻟﮫ ﺣﺎﺟﺔ زي ﻛﺄﻧﻚ ﺑﺘﺤﻂ ﻛﻮﺑﺎﯾﺔ ﺟﻮة ﻛﻮﻓﺮ ﯾﺨﻠﯿﮭﺎ ﺗﺒﺮد أو ﺗﺴﺨﻦ أو ﺗﺘﺰﯾﻦ
Facade
ﻟﻮ ﻋﻨﺪك Systemﻣﻌﻘﺪ ﻓﯿﮫ ﻛﻼﺳﺎت ﻛﺘﯿﺮ وﻋﺎﯾﺰ ﺗﻮﻓﺮ واﺟﮭﺔ ﺑﺴﯿﻄﺔ ﻟﻠﻲ ھﯿﺴﺘﺨﺪﻣﮫ ﻓﺒﺘﻌﻤﻞ Facadeﯾﻐﻄﻲ اﻟﺘﻌﻘﯿﺪ ده
زي ﻟﻤﺎ ﺗﺪﺧﻞ ﺑﻨﻚ وﻣﻮظﻒ واﺣﺪ ﯾﺨﻠﺼﻠﻚ ﻛﻞ ﺣﺎﺟﺔ
Composite
ﻟﻮ ﻋﻨﺪك ﺷﺠﺮة ﻛﺎﺋﻨﺎت وﻛﻞ ﻋﻨﺼﺮ ﻣﻤﻜﻦ ﯾﺒﻘﻰ Leafأو ﻣﺠﻤﻮﻋﺔ ﻣﻦ اﻟـ Leafsوﻋﺎﯾﺰ ﺗﺘﻌﺎﻣﻞ ﻣﻊ ﻛﻠﮫ ﺑﻨﻔﺲ اﻟﺸﻜﻞ
Composite
Bridge
ﻟﻮ ﻋﻨﺪك ﻛﻼس ﺑﯿﻐﯿﺮ ﻓﻲ أﻛﺘﺮ ﻣﻦ ﻣﺤﻮرﻣﺜﻼ اﻟﺸﻜﻞ ﺑﯿﺨﺘﻠﻒ واﻟﻨﻮع ﺑﯿﺨﺘﻠﻒ ﻓﺒﺘﻔﺼﻞ اﻟﻤﺤﻮرﯾﻦ ﻋﻦ ﺑﻌﺾ
ﯾﻌﻨﻲ ﺗﺮﺑﻂ ﺑﯿﻨﮭﻢ ﺑﻜﻮﺑﺮي ) (Bridgeﯾﺨﻠﯿﮭﻢ ﯾﺸﺘﻐﻠﻮا ﻣﻊ ﺑﻌﺾ ﺑﺤﺮﯾﺔ
Proxy
ﻟﻮ ﻋﻨﺪك ﻛﺎﺋﻦ ﺗﻘﯿﻞ أو ﺣﺴﺎس أو ﻣﺤﺘﺎج ﻣﺮاﻗﺒﺔ ﻓﺒﺘﺤﻂ ﻗﺪاﻣﮫ ﻛﺎﺋﻦ Proxyﯾﺘﺤﻜﻢ ﻓﻲ اﻟﻮﺻﻮل ﻟﯿﮫ زي اﻟﺠﺪار اﻟﻨﺎري اﻟﻠﻲ ﺑﯿﻘﻌﺪ ﺑﯿﻨﻚ وﺑﯿﻦ اﻹﻧﺘﺮﻧﺖ
Flyweight
ﻟﻮ ﻋﻨﺪك ﻋﺪد ﻛﺒﯿﺮ ﺟﺪًا ﻣﻦ اﻟﻜﺎﺋﻨﺎت اﻟﻤﺘﺸﺎﺑﮭﺔ وﻣﺶ ﻋﺎﯾﺰ ﺗﻀﯿﻊ ذاﻛﺮة ﻓﺒﺘﺸﺎرك اﻟﺤﺎﻟﺔ اﻟﻤﺘﻜﺮرة ﺑﯿﻨﮭﻢ وﺗﻔﺼﻞ اﻟﻤﺘﻐﯿﺮ
زي ﺧﻄﻮط اﻟﺤﺮوف :ﻛﻞ اﻟﺤﺮوف ﺑﺘﺸﺎرك ﻓﻲ ﻧﻔﺲ ﺷﻜﻞ اﻟﺨﻂ
o
ﻷﻧﻚ واﻧﺖ ﺷﻐﺎل ﻋﻠﻰ Systemsﻛﺒﯿﺮة
ﯾﻌﻨﻲ ﻣﻦ اﻵﺧﺮ ،دي Patternsﺑﺘﺴﺎﻋﺪك ﻓﻲ ھﻨﺪﺳﺔ اﻟﻌﻼﻗﺎت ﺑﯿﻦ اﻟﻜﻼﺳﺎت ﻣﺶ ﺑﺲ ﻓﻲ ﻛﺘﺎﺑﺔ اﻟﻜﻮد
_R
M
ﻓﻜﺮﺗﮫ إﻧﮫ ﺑﯿﻌﻤﻞ زي "اﻟﻮﺻﻠﺔ أو اﻟﻤﺤﻮل" ﺑﯿﺮﺑﻂ ﺑﯿﻦ ﻛﺎﺋﻨﯿﻦ ﻣﺶ ﻣﺘﻮاﻓﻘﯿﻦ ﻓﻲ اﻟـ Interfaceﺑﺘﺎﻋﮭﻢ ﺑﺲ ﻋﺎﯾﺰھﻢ ﯾﺸﺘﻐﻠﻮا ﻣﻊ ﺑﻌﺾ
ﺑﻤﻌﻨﻰ ﺗﺎﻧﻲ:
ﻟﻮ ﻋﻨﺪك ﻛﻮد ﺑﯿﻄﻠﺐ داﻟﺔ ﻣﻌﯿﻨﺔ ﺑﺲ اﻟﻜﻮد اﻟﻠﻲ ﻋﻨﺪك ﺑﯿﻮﻓﺮ داﻟﺔ ﻣﺨﺘﻠﻔﺔ ﺑﺪل ﻣﺎ ﺗﻐﯿﺮ اﻟﻜﻮد أو ﺗﻌﺪل ﻓﻲ اﻟﻜﻼﺳﺎت اﻟﻘﺪﯾﻤﺔ ﺑﺘﺒﻨﻲ Adapterﯾﺘﺮﺟﻢ ﻣﺎ ﺑﯿﻦ اﻟﻄﺮﻓﯿﻦ
o
أﻧﻮاع اﻟـ Adapter
ﻓﯿﮫ ﻧﻮﻋﯿﻦ رﺋﯿﺴﯿﯿﻦ:
Client
M
Target Interface
اﻟﺸﻜﻞ اﻟﻠﻲ اﻟـ Clientﺑﯿﺘﻮﻗﻌﮫ
Adaptee
اﻟﻜﻼس اﻷﺻﻠﻲ اﻟﻠﻲ ﻣﺶ ﻣﺘﻮاﻓﻖ ﻣﻊ اﻟـ Target
Adapter
اﻟﻜﻼس اﻟﻠﻲ ﺑﯿﺮﺑﻂ ﺑﯿﻦ Targetو Adaptee
o
اﻟﻄﻠﺐ اﻟﺠﺪﯾﺪ ﺑﻘﻰ:
long, lat
ﯾﺤﻮﻟﮭﻢ إﻟﻰ cityو ) countryﻋﻦ طﺮﯾﻖ ﺧﺪﻣﺔ ﺧﺎرﺟﯿﺔ أو dummy logicﻣﺆﻗﺖ( ّ
ﯾﺒﻌﺜﮭﻢ ﻟﻠﻤﻜﺘﺒﺔ اﻟﻘﺪﯾﻤﺔ
ﯾﺎﺧﺪ اﻟـ XMLاﻟﻨﺎﺗﺞ ﯾﺤﻮﻟﮫ إﻟﻰ JSONوﯾﺒﻌﺘﮫ ﻟﻠـ Client
اﻟﻜﻮد ع ال GITHUB
o
et
Sh
_R
M
Bridge Pattern
ﺑﯿﻔﺼﻞ ﺑﯿﻦ اﻟـ ) Abstractionاﻟﻮاﺟﮭﺔ( وﺑﯿﻦ اﻟـ ) Implementationطﺮﯾﻘﺔ اﻟﺘﻨﻔﯿﺬ( ﺑﺤﯿﺚ ﺗﻘﺪر ﺗﻐﯿﺮ أي واﺣﺪة ﻓﯿﮭﻢ ﻣﻦ ﻏﯿﺮ ﻣﺎ ﺗﺄﺛﺮ ﻋﻠﻰ اﻟﺘﺎﻧﯿﺔ
ﯾﻌﻨﻲ ﻟﻮ ﻋﻨﺪك ﻛﻼس ﻓﯿﮫ ﺳﻠﻮك ﺑﯿﺘﻐﯿﺮ ﻓﻲ أﻛﺘﺮ ﻣﻦ اﺗﺠﺎه ﺑﺪل ﻣﺎ ﺗﺒﻨﻲ ھﯿﺮارﻛﻲ ﻓﯿﮭﺎ ﻛﻞ اﻻﺣﺘﻤﺎﻻت ﺗﻔﺼﻞ اﻻﺗﺠﺎھﺎت دي وﺗﺮﺑﻄﮭﻢ ﺑﻜﻮﺑﺮي )(Bridge
ﻋﻨﺪك ﻛﻼس ﻓﯿﮫ أﻛﺘﺮ ﻣﻦ dimensionﺑﯿﺘﻐﯿﺮ زي ﻣﺜﻼ ﺷﻜﻞ اﻟﺰر ) (Buttonوﻧﻈﺎم اﻟﺘﺸﻐﯿﻞ اﻟﻠﻲ ﺑﯿﺸﺘﻐﻞ ﻋﻠﯿﮫ
ﻟﻮ ﺑﺪأت ﺗﺒﻨﻲ inheritance treeﻣﻌﻘﺪة وﻛﻞ ﻣﺮة ﺗﻀﯿﻒ ﻓﯿﮭﺎ optionﺟﺪﯾﺪ ﻻزم ﺗﻌﻤﻞ Subclassﺟﺪﯾﺪ
ﻟﻮ ﻋﺎﯾﺰ ﺗﺨﻠﻲ ﻛﻞ dimensionﻣﺴﺘﻘﻞ وﺳﮭﻞ اﻟﺘﻌﺪﯾﻞ ﺗﻘﺪر ﺗﻀﯿﻒ ﺷﻜﻞ ﺟﺪﯾﺪ أو ﺗﻨﻔﯿﺬ ﺟﺪﯾﺪ ﻣﻦ ﻏﯿﺮ ﻣﺎ ﺗﻜﺴﺮ اﻟﻜﻮد اﻟﻘﺪﯾﻢ
o
ﺗﺨﯿﻞ ﻣﻌﺎﯾﺎ إﻧﻚ ﺑﺘﺒﻨﻲ Systemﻹرﺳﺎل إﺷﻌﺎرات )(Notifications
NormalEmailNotification
NormalSMSNotification
UrgentEmailNotification
UrgentSMSNotification
ExecutiveSlackNotification
وھﻜﺬا...
ﺗﺨﯿﻞ ﻟﻮ ﺿﻔﺖ وﺳﯿﻠﺔ ﺟﺪﯾﺪة أو ﻧﻮع ﺟﺪﯾﺪ؟ ھﺘﻀﻄﺮ ﺗﻀﯿﻒ Subclassesﻛﺘﯿﺮ ﺟﺪا واﻟﻜﻮد ھﯿﻜﺒﺮ ﺑﺸﻜﻞ ﺑﺸﻊ
اﻷطﺮاف اﻟﻤﺸﺎرﻛﺔ
ﻓﻲ Bridge Patternﺑﻨﻔﺼﻞ اﻟﻜﻮد ﻛﺎﻟﺘﺎﻟﻲ:
Abstraction
اﻟﻜﻼس أو اﻟﻮاﺟﮭﺔ اﻷﺳﺎﺳﯿﺔ اﻟﻠﻲ ﺑﯿﺘﻌﺎﻣﻞ ﻣﻌﺎھﺎ اﻟـ Client
Abstraction Refined
ﻧﺴﺨﺔ أﻛﺜﺮ ﺗﺨﺼﺼﺎ ﻣﻦ اﻟـ Abstraction
Implementor
Interfaceﻓﯿﮫ دوال اﻟﺘﻨﻔﯿﺬ
Implementor Concrete
اﻟﻔﻌﻞ اﻟﺤﻘﯿﻘﻲ اﻟﻠﻲ ﺑﯿﺤﺼﻞ ﻋﻠﻰ اﻷرض
o
et ﻋﺎﯾﺰ ﺗﺒﻨﻲ Streaming Video Platform
Sh
ﺑﺘﺪﻋﻢ ﻣﺰودﯾﻦ ﻣﺨﺘﻠﻔﯿﻦ ﻟﻠﻔﯿﺪﯾﻮ زي YouTubeوTwitch
اﻟﻤﺰود ﺑﯿﺘﻐﯿﺮ
واﻟﺠﻮدة ﺑﺘﺘﻐﯿﺮ
وﻟﻮ ﺣﺎوﻟﺖ ﺗﺒﻨﻲ ﻛﻞ اﻟﺘﺮﻛﯿﺒﺎت دي ﺑﻜﻼﺳﺎت ﻣﺴﺘﻘﻠﺔ ھﺘﻮﺻﻞ ﻟﻌﺪد ﻛﺒﯿﺮ ﺟﺪا ﻣﻦ اﻟﻜﻼﺳﺎت
ﻣﺜﺎل:
YouTubeHDPlayer
YouTubeSDPlayer
TwitchHDPlayer
TwitchSDPlayer
:Bridge Pattern
اﻟﮭﺪف ﻣﻨﮫ إﻧﻚ ﺗﻔﺼﻞ ﺑﯿﻦ Abstractionو Implementationﯾﻌﻨﻲ ﻋﻨﺪك ﻛﺎﺋﻨﯿﻦ ﻣﺴﺘﻘﻠﯿﻦ ﻛﻞ واﺣﺪ ﻓﯿﮭﻢ ﺑﯿﺘﻐﯿﺮ ﻟﻮﺣﺪه ﻓﺒﺘﺮﺑﻄﮭﻢ ﺑﺒﻌﺾ ﺑﻜﻮﺑﺮي ﺑﺪل ﻣﺎ ﺗﺪﻣﺠﮭﻢ ﻓﻲ ﻛﻼس واﺣﺪ
:Strategy Pattern
اﻟﮭﺪف إﻧﻚ ﺗﻐﯿﺮ ﺳﻠﻮك ﻣﻌﯿﻦ ﺟﻮه اﻟﻜﻼس ﻣﻦ ﻏﯿﺮ ﻣﺎ ﺗﻌﺪل اﻟﻜﻼس ﻧﻔﺴﮫ ﯾﻌﻨﻲ اﻟﺴﻠﻮك )اﻟﺠﺰء اﻟﻠﻲ ﺑﯿﺘﻐﯿﺮ( ﺑﯿﺒﻘﻰ External object
o
et طﺒﯿﻌﺔ اﻟﻌﻼﻗﺔ ﺑﯿﻦ اﻟﻜﻼﺳﺎت
:Bridge
اﻟﻌﻼﻗﺔ ﺑﯿﻦ Abstractionو Implementationﻋﺎدة ﺑﺘﻜﻮن ﻋﻼﻗﺔ ﺗﺮﻛﯿﺒﯿﺔ ) (has-aﺑﯿﺘﻢ اﺳﺘﺨﺪاﻣﮭﺎ ﻟﻤﺎ ﯾﻜﻮن ﻋﻨﺪك أﻛﺜﺮ ﻣﻦ ﻣﺤﻮر ﻟﻠﺘﻐﯿﯿﺮ
Sh
:Strategy
اﻟﻌﻼﻗﺔ ﺑﯿﻦ ﻛﻼس وﺳﻠﻮك ﻣﻌﯿﻦ اﻟﺴﻠﻮك ﺑﯿﺘﻐﯿﺮ ﺑﻨﺎء ﻋﻠﻰ اﻟﺴﯿﻨﺎرﯾﻮ ﺑﺘﺴﺘﺨﺪﻣﮭﺎ ﻟﻤﺎ ﯾﻜﻮن ﻋﻨﺪك ﺧﻮارزﻣﯿﺎت ﻣﺨﺘﻠﻔﺔ ﻟﻨﻔﺲ اﻟﻤﮭﻤﺔ
_R
:Strategy
ﺑﯿﺴﻤﺤﻠﻚ إﻧﻚ ﺗﺒﻨﻲ ﻛﺎﺋﻨﺎت ﺑﺸﻜﻞ ) (Hierarchicalوﺗﺘﻌﺎﻣﻞ ﻣﻊ اﻟﻌﻨﺎﺻﺮ اﻟﻔﺮدﯾﺔ ) (Leafواﻟﻤﺮﻛﺒﺔ ) (Compositeﺑﻨﻔﺲ اﻟﺸﻜﻞ.
ﺑﺒﺴﺎطﺔ:
ﻟﻮ ﻋﻨﺪك "ﺣﺎﺟﺔ ﺟﻮاھﺎ ﺣﺎﺟﺎت ﺗﺎﻧﯿﺔ ﻣﻦ ﻧﻔﺲ اﻟﻨﻮع"
وده ﺑﯿﺨﻠﻲ اﻟﺘﻌﺎﻣﻞ ﻣﻌﺎھﻢ ﻛﺄﻧﮭﻢ ﺣﺎﺟﺔ واﺣﺪة رﻏﻢ إﻧﮭﻢ ﺟﻮا ﺑﻌﺾ.
ﻗﺎﺋﻤﺔ ) (Menuﻓﯿﮭﺎ ﻋﻨﺎﺻﺮ ﻋﺎدﯾﺔ وﺟﻮاھﺎ Submenusﻓﯿﮭﺎ ﻋﻨﺎﺻﺮ ﺗﺎﻧﯿﺔ وﻛﻞ ﻋﻨﺼﺮ ﻣﻨﮭﻢ ﻣﻤﻜﻦ ﯾﻜﻮن Actionأو ﻗﺎﺋﻤﺔ ﺗﺎﻧﯿﺔ
{ )'if ([Link] === 'menu ﻟﻮ ﺣﺎوﻟﺖ ﺗﻜﺘﺐ ﻛﻮد ﻟﻜﻞ ﻧﻮع ﻋﻨﺼﺮ ﺑﻄﺮﯾﻘﺔ ﻣﻨﻔﺼﻠﺔ ،ھﺘﻀﻄﺮ ﺗﻜﺘﺐ ﻟﻜﻞ ﺣﺎﻟﺔ ﻛﻮد ﻣﺨﺘﻠﻒ:
;)renderMenu(item
{ )'} else if ([Link] === 'action اﻟﻜﻮد ھﯿﺒﻘﻰ ﻣﻠﯿﺎن if else
وﻣﺶ ھﯿﻜﻮن ﻗﺎﺑﻞ ﻟﻠﺘﻮﺳﻌﺔ ﺑﺴﮭﻮﻟﺔ وﻟﻮ ﻋﺎﯾﺰ ﺗﻀﯿﻒ ﻋﻨﺼﺮ ﺟﺪﯾﺪ ﻻزم ﺗﻌﺪل ﻓﻲ ﻛﻞ ﺣﺘﺔ
;)renderButton(item
}
o
et اﻟﻔﻜﺮة اﻷﺳﺎﺳﯿﺔ
Composite Patternﺑﯿﺨﻠﯿﻚ:
وﺑﺎﻟﺘﺎﻟﻲ ،ﺗﻘﺪر ﺗﺴﺘﺨﺪم ﻧﻔﺲ اﻟﻤﯿﺜﻮد ) (... ,render, show, deleteﻋﻠﻰ اﻟﻜﻞ.
M
:Component Interface
ده اﻟﻮاﺟﮭﺔ اﻟﻤﺸﺘﺮﻛﺔ اﻟﻠﻲ ﻛﻞ اﻟﻌﻨﺎﺻﺮ ﺑﺘﻨﻔﺬھﺎ
ﺑﺘﻌﺮف اﻟﻮظﺎﺋﻒ زي ()renderأو .()display
ّ
:Leaf
ﻋﻨﺼﺮ ﺑﺴﯿﻂ ﻣﺎﻟﻮش أطﻔﺎل ،ﺑﯿﻨﻔﺬ اﻟﻮظﯿﻔﺔ ﺑﻨﻔﺴﮫ.
:Composite
ﻋﻨﺼﺮ ﻣﺮﻛﺐ ﺟﻮاه ﻋﻨﺎﺻﺮ ﺗﺎﻧﯿﺔ وﺑﯿﻨﻔﺬ اﻟﻮظﯿﻔﺔ ﻋﻦ طﺮﯾﻖ اﺳﺘﺪﻋﺎﺋﮭﺎ ﻟﻜﻞ اﻟﻌﻨﺎﺻﺮ اﻟﻠﻲ ﺟﻮاه.
اﻟـ : Creational Design Patternsﺑﺘﺤﻞ اﻟﻤﺸﺎﻛﻞ اﻟﻤﺘﻌﻠﻘﺔ ﺑﺈﻧﺸﺎء اﻟﻜﺎﺋﻨﺎت ) (Objectsﺑﻄﺮﯾﻘﺔ ﻣﺮﻧﺔ ﻗﺎﺑﻠﺔ ﻟﻠﺘﻮﺳﻌﺔ وﺑﺘﻔﺼﻞ اﻟﻜﻮد اﻟﻠﻲ ﺑﯿﺴﺘﺨﺪم اﻟﻜﺎﺋﻦ ﻋﻦ اﻟﻜﻮد اﻟﻠﻲ ﺑﯿﺒﻨﯿﮫ
ﺑﺘﺴﺎﻋﺪﻧﺎ ﻋﻠﻰ:
اﻟﺘﺤﻜﻢ ﻓﻲ ﻋﺪد اﻟـ Instancesو ﺟﻌﻞ اﻟﻜﻮد أﻛﺘﺮ ﻣﺮوﻧﺔ ﻋﻨﺪ اﻟﺘﻐﯿﯿﺮ و ﺗﺤﺴﯿﻦ اﻟـ Testability
:Factory Pattern
ﺗﺨﻠﻲ ﻛﻼس أو ﻓﺎﻧﻜﺸﻦ ﻣﺴﺆوﻟﺔ ﻋﻦ إﻧﺸﺎء ﻛﺎﺋﻨﺎت ،ﺑﺪل ﻣﺎ ﺗﻜﺘﺐ newﻓﻲ ﻛﻞ ﺣﺘﺔ.
Builder Pattern
ﺑﺘﻔﺼﻞ ﺧﻄﻮات ﺑﻨﺎء اﻟﻜﺎﺋﻦ اﻟﻤﻌﻘﺪ ) (object with many optionsﻋﻦ اﻟﻜﻼس ﻧﻔﺴﮫ ،وﺑﺘﺪﯾﻚ طﺮﯾﻘﺔ ﻣﺮﻧﺔ ﺗﺒﻨﻲ ﺑﯿﮭﺎ ﻛﺎﺋﻨﺎت ﺧﻄﻮة ﺑﺨﻄﻮة.
o
Prototype Pattern
ﺗﺴﺘﺨﺪم ﻛﺎﺋﻦ ﻣﻮﺟﻮد ﻛـ ﻗﺎﻟﺐ ) (prototypeوﺗﻨﺴﺨﮫ ﺑﺪل ﻣﺎ ﺗﺒﻨﯿﮫ ﻣﻦ اﻟﺼﻔﺮ.
et Singleton Pattern
Sh
ﺑﯿﻀﻤﻦ إن ﻓﯿﮫ instanceواﺣﺪة ﺑﺲ ﻣﻦ اﻟﻜﻼس ﻣﻮﺟﻮدة ﻓﻲ اﻟﺒﺮﻧﺎﻣﺞ ﻛﻠﮫ.
_R
M
ﺑﯿﺘﻌﺎﻣﻞ ﻣﻊ ﻓﻜﺮة إﻧﻚ ﺑﺪل ﻣﺎ ﺗﻨﺸﺊ اﻟﻜﺎﺋﻨﺎت ) (Objectsﺑﺈﯾﺪك ﻓﻲ اﻟﻜﻮد ﺑﺎﺳﺘﺨﺪام newﺗﺪي اﻟﻤﮭﻤﺔ دي ﻟﺠﮭﺔ ﺗﺎﻧﯿﺔ اﺳﻤﮭﺎ Factory
اﻟﮭﺪف إﻧﻚ ﺗﻔﺼﻞ ﻋﻤﻠﯿﺔ اﻹﻧﺸﺎء ﻧﻔﺴﮭﺎ ﻋﻦ اﻟﻜﻮد اﻟﻠﻲ ﺑﯿﺴﺘﺨﺪم اﻟﻜﺎﺋﻨﺎت
ده ﺑﯿﺴﺎﻋﺪ ﺟﺪا ﻟﻤﺎ أﻧﻮاع اﻟﻜﺎﺋﻨﺎت اﻟﻠﻲ ﺑﺘﻨﺸﺌﮭﺎ ﺑﺘﺘﻐﯿﺮ ﺣﺴﺐ اﻟﻈﺮوف
ﻟﻮ ﻋﻨﺪك ﻛﻼس ﺑﯿﺘﻌﺎﻣﻞ ﻣﻊ أﻧﻮاع ﻣﺨﺘﻠﻔﺔ ﻣﻦ اﻟﻤﻨﺘﺠﺎت ) (Product classesوﻛﻞ ﻣﻨﺘﺞ ﻟﮫ طﺮﯾﻘﺔ إﻧﺸﺎء ﻣﺨﺘﻠﻔﺔ أو ﺷﺮوط ﻣﻌﯿﻨﺔ
ﯾﺒﻘﻰ ﺑﺪل ﻣﺎ اﻟﻜﻮد اﻟﺮﺋﯿﺴﻲ ﯾﺘﻌﺎﻣﻞ ﻣﻊ ﻛﻞ اﻟﺘﻔﺎﺻﯿﻞ دي ﺗﺪﯾﮭﺎ ﻟﻜﻼس ﻣﺴﺘﻘﻞ ﻣﮭﻤﺘﮫ اﻟﻮﺣﯿﺪة إﻧﮫ ﯾﻨﺸﺊ اﻟﻜﺎﺋﻦ اﻟﺼﺢ ﻋﻠﻰ ﺣﺴﺐ اﻟﻤﺪﺧﻼت
ﻣﺜﺎااال
إﻧﺖ ﻋﻨﺪك ﻧﻈﺎم E-Commerceﺑﯿﺤﺘﺎج ﯾﺘﻌﺎﻣﻞ ﻣﻊ أﻧﻮاع ﻣﺨﺘﻠﻔﺔ ﻣﻦ وﺳﺎﺋﻞ اﻟﺪﻓﻊ. AmericanExpress، MasterCard،Visa :
o
ﻛﻞ واﺣﺪة ﻟﯿﮭﺎ processing logicﺧﺎص ﺑﯿﮭﺎ )ﯾﻌﻨﻲ ﻣﻤﻜﻦ ﺗﺨﺘﻠﻒ ﻓﻲ اﻟﺮﺳﻮم أو ﺧﻄﻮات اﻟﺘﻨﻔﯿﺬ(.
et
Sh
_R
M
ﻓﻲ اﻟﺤﺎﻟﺔ دي ،ﺑﺪل ﻣﺎ ﻧﻜﺘﺐ ifأو switchﺟﻮه اﻟﻜﻮد اﻟﺮﺋﯿﺴﻲ وﻧﻌﻤﻞ ﺗﺸﻌﺐ ﻛﺒﯿﺮ
ﺑﻨﺴﺘﺨﺪم Factory Patternﻋﻠﺸﺎن ﻧﻌﺰل ﻣﺴﺆوﻟﯿﺔ إﻧﺸﺎء اﻟـ Payment Processorاﻟﻤﻨﺎﺳﺐ ﻓﻲ ﻣﻜﺎن واﺣﺪ.
اﻟﺘﻘﺴﯿﻢ
Interfaceأو Classأﺳﺎﺳﻲ ﯾﺤﺪد ﺷﻜﻞ أي PaymentProcessor
أﻧﺖ ھﻨﺎ ﺑﺘﻌﺰل ﻣﺴﺆوﻟﯿﺔ اﻹﻧﺸﺎء ﻓﻲ اﻟـ Factoryوﺑﺘﺨﻠﻲ اﻟﻜﻮد ﻧﻈﯿﻒ وﺳﮭﻞ اﻟﺘﻮﺳﻌﺔ.
Abstract Factory
ووظﯿﻔﺘﮫ اﻷﺳﺎﺳﯿﺔ ھﻲ ﺗﻮﻓﯿﺮ ﻣﺠﻤﻮﻋﺔ ﻣﻦ اﻟﻤﺼﺎﻧﻊ ) (Factoriesﻛﻞ ﻣﺼﻨﻊ ﻣﺴﺆول ﻋﻦ إﻧﺸﺎء ﻣﺠﻤﻮﻋﺔ ﻣﻦ اﻟﻜﺎﺋﻨﺎت اﻟﻤﺮﺗﺒﻄﺔ ﺑﺒﻌﺾ ) (related objectsﻣﻦ ﻏﯿﺮ ﻣﺎ اﻟﻜﻮد اﻟﻠﻲ ﺑﯿﺴﺘﺨﺪﻣﮭﻢ
ﯾﻌﺮف اﻟﻨﻮع اﻟﺤﻘﯿﻘﻲ ﻟﻜﻞ ﻛﺎﺋﻦ.
o
ﯾﻌﻨﻲ ﻟﻮ ﻋﻨﺪك ﺳﯿﺴﺘﻢ ﺑﯿﺘﻌﺎﻣﻞ ﻣﻊ أﻛﺜﺮ ﻣﻦ ﻧﻈﺎم ﺗﺸﻐﯿﻞ أو أﻛﺜﺮ ﻣﻦ Themeوﻋﺎﯾﺰ ﺗﻮﻟﺪ UI Elementsﻣﺨﺘﻠﻔﺔ ﺣﺴﺐ اﻟﺒﯿﺌﺔ ﺗﻘﺪر ﺗﺴﺘﺨﺪم Abstract Factoryﻋﻠﺸﺎن ﺗﻮﻟﺪ اﻟﻌﻨﺎﺻﺮ
Builder Pattern؟
ھﻮ Creational Design Patternھﺪﻓﮫ إﻧﮫ ﯾﻔﺼﻞ ﺑﯿﻦ "ﺧﻄﻮات إﻧﺸﺎء ﻛﺎﺋﻦ ﻣﻌﻘﺪ" و"اﻟﺘﻤﺜﯿﻞ اﻟﻨﮭﺎﺋﻲ ﻟﻠﻜﺎﺋﻦ".
ﯾﻌﻨﻲ ﻟﻤﺎ ﯾﻜﻮن ﻋﻨﺪك objectﻓﯿﮫ ﺗﻔﺎﺻﯿﻞ ﻛﺘﯿﺮ وﻣﻤﻜﻦ ﯾﺘﺒﻨﻲ ﺑﻌﺪة طﺮق )ﺑﻤﻌﻨﻰ إن ﺑﻌﺾ اﻟﺨﺼﺎﺋﺺ ﻣﻤﻜﻦ ﺗﺒﻘﻰ optionalأو (configurable
اﻟـ Builderﺑﯿﺴﺎﻋﺪك ﺗﺒﻨﻲ اﻟـ objectﺧﻄﻮة ﺑﺨﻄﻮة ،ﻣﻦ ﻏﯿﺮ ﻣﺎ ﯾﺤﺼﻞ ﺗﻌﻘﯿﺪ ﻓﻲ اﻟـ constructorأو ﺗﻜﺮار ﻓﻲ اﻟﻜﻮد.
ﻟﻤﺎ ﯾﻜﻮن اﻟـ objectﻓﯿﮫ ﻋﺪد ﻛﺒﯿﺮ ﻣﻦ اﻟﺨﺼﺎﺋﺺ أو اﻟﻘﯿﻢ اﻟﻠﻲ ﻣﻤﻜﻦ ﺗﺨﺘﻠﻒ ).(optional parameters
ﻟﻤﺎ ﯾﻜﻮن ﻋﻨﺪك ﻋﺪة طﺮق ﻣﺨﺘﻠﻔﺔ ﻟﺒﻨﺎء ﻧﻔﺲ اﻟـ .object
ﻟﻤﺎ ﯾﻜﻮن ﻓﻲ اﺧﺘﻼف ﻓﻲ ﺗﺮﺗﯿﺐ ﺗﻨﻔﯿﺬ ﺧﻄﻮات اﻹﻧﺸﺎء.
ﻟﻤﺎ ﻋﺎﯾﺰ ﺗﺨﻠﻲ اﻟـ object immutableﺑﻌﺪ ﻣﺎ ﯾﺘﺒﻨﻲ.
o
et
Sh
_R
M
اﻟـ ) Builderﺳﻮاء ﻛﺎن ﻛﻼس أو داﻟﺔ ﻓﻲ (JavaScriptدوره إﻧﮫ ﯾﺠﻤﻊ ﻛﻞ اﻟﻤﻌﻠﻤﺎت اﻟﻼزﻣﺔ ﻹﻧﺸﺎء اﻟﻜﺎﺋﻦ ﺧﻄﻮة ﺑﺨﻄﻮة
ﻋﺎدة ً ﺑﻨﻌﻤﻞ ﻣﯿﺜﻮد ﻟﻜﻞ ﻣﻌﻠﻤﺔ أو ﻣﺠﻤﻮﻋﺔ ﻣﻌﻠﻤﺎت ﻣﺘﺮاﺑﻄﺔ ﺑﺲ ﻣﻔﯿﺶ ﻗﺎﻋﺪة ﺻﻠﺒﺔ
اﻟﻤﺼﻤﻢ )اﻟـ (developerھﻮ اﻟﻠﻲ ﺑﯿﻘﺮر إزاي ﯾﺴﻤﻲ اﻟﻤﯿﺜﻮدز وإزاي ھﺘﺸﺘﻐﻞ اﻟﮭﺪف إﻧﻚ ﺗﺨﻠﻲ اﻟﻌﻤﻠﯿﺔ ﻣﺮﻧﺔ وواﺿﺤﺔ
اﻟﮭﺪف اﻷﺳﺎﺳﻲ ﻣﻦ اﻟـ Builder Patternھﻮ إﻧﻚ ﺗﻔﻜﻚ constructorﻣﻌﻘﺪ )اﻟﻠﻲ ﺑﯿﺎﺧﺪ ﻣﻌﻠﻤﺎت ﻛﺘﯿﺮ( إﻟﻰ ﺧﻄﻮات ﺻﻐﯿﺮة وواﺿﺤﺔ.
Builder constructor
ﻧﻈﺎم إﺷﻌﺎرات ) (Notificationsﻓﻲ ﺗﻄﺒﯿﻖ رﺳﺎﺋﻞ" ،ﺑﺤﯿﺚ ﯾﻜﻮن ﻓﯿﮫ ﻣﺮوﻧﺔ ﻓﻲ إﻋﺪاد ﻣﺤﺘﻮﯾﺎت اﻹﺷﻌﺎر زي اﻟﺮﺳﺎﻟﺔ ،اﻟﻤﺮﺳﻞ ،اﻟﺘﺎرﯾﺦ،
وﺧﺼﺎﺋﺺ إﺿﺎﻓﯿﺔ زي اﻟﻤﺮﻓﻘﺎت )(attachments
ﺗﻌﺮﯾﻒ اﻟﻤﺸﻜﻠﺔ:
إﺷﻌﺎر ) (Notificationﻣﻤﻜﻦ ﯾﺘﻜﻮن ﻣﻦ:
o
:attachmentﻣﺮﻓﻖ اﺧﺘﯿﺎري
ﻟﻮ ﻋﻤﻠﺖ Constructorﺑـ 5ﺑﺎراﻣﯿﺘﺮز ھﺘﺒﻘﻰ اﻟﺪﻧﯿﺎ ﻣﻠﺨﺒﻄﺔ ﺟﺪا ﺧﺼﻮﺻﺎ ﻟﻮ ﻋﺎﯾﺰ ﺗﺴﺘﺨﺪم ﺑﺎراﻣﯿﺘﺮز اﺧﺘﯿﺎرﯾﺔ ﺑﺲ.
Sh
_R
M
اﻟﻤﺮوﻧﺔ :ﻣﻤﻜﻦ ﺗﺒﻨﻲ إﺷﻌﺎر ﻓﯿﮫ ﺧﺎﺻﯿﺔ واﺣﺪة ﺑﺲ أو اﻟﻜﻞ ﻣﻦ ﻏﯿﺮ ﻣﺎ ﺗﻀﻄﺮ ﺗﻌﻤﻞ Constructorﺑﻌﺪد ﺿﺨﻢ ﻣﻦ اﻟﺒﺎراﻣﯿﺘﺮز.
) Immutabilityاﻟﻼ-ﺗﻐﯿﺮ( :اﻟﻜﺎﺋﻦ اﻟﻨﮭﺎﺋﻲ Notificationﺑﯿﺘﻢ إﻧﺸﺎؤه ﺟﺎھﺰ ،وﻣﺶ ﺑﻨﻌﺪّل ﻋﻠﯿﮫ ﺑﻌﺪ ﻛﺪه.
ﻗﺎﺑﻠﯿﺔ اﻟﺘﻮﺳﯿﻊ :ﻟﻮ زودت ﺧﺎﺻﯿﺔ ﺟﺪﯾﺪة )زي ﻧﻮع اﻹﺷﻌﺎر( ،ھﺘﺰودھﺎ ﺟﻮه اﻟـ Builderﺑﺲ ،ﻣﻦ ﻏﯿﺮ ﻣﺎ ّ
ﺗﺒﻮظ اﻟﻜﻮد اﻟﺘﺎﻧﻲ
ﻟﻜﻦ اﻟـ Builderﺑﯿﺮﻛﺰ ﻋﻠﻰ "إزاي ﺗﺒﻨﻲ اﻟﻜﺎﺋﻦ ﺧﻄﻮة ﺑﺨﻄﻮة" ﺧﺼﻮﺻﺎ ﻟﻮ اﻟﻜﺎﺋﻦ ﻣﻌﻘﺪ أو ﻓﯿﮫ ﺧﯿﺎرات ﻛﺘﯿﺮ
o
et
Sh
_R
M
ھﻮ ﻧﻤﻂ ﺗﺼﻤﯿﻢ ) (Design Patternﺑﯿﻀﻤﻦ إن ﻓﯿﮫ instanceواﺣﺪة ﺑﺲ ﻣﻦ ﻛﻼس أو ﻛﺎﺋﻦ ﻣﻌﯿﻦ ﻓﻲ اﻟﺘﻄﺒﯿﻖ ﻛﻠﮫ وإن أي ﻛﻮد ﻋﺎﯾﺰ ﯾﺴﺘﺨﺪم اﻟﻜﺎﺋﻦ ده ﯾﻮﺻﻞ ﻟﻨﻔﺲ اﻟـ instance
ﯾﻌﻨﻲ ﻟﻮ ﻋﻨﺪك ﻛﺎﺋﻦ زي ﻗﺎﻋﺪة ﺑﯿﺎﻧﺎت أو Loggerﺑﺪل ﻣﺎ ﺗﻨﺸﺊ instancesﺟﺪﯾﺪة ﻛﻞ ﻣﺮة ﺑﺘﺴﺘﺨﺪم ﻧﻔﺲ اﻟـ instanceﻋﺸﺎن ﺗﻮﻓﺮ اﻟﻤﻮارد وﺗﻀﻤﻦ إن ﻛﻞ اﻟﻜﻮد ﺑﯿﺘﻌﺎﻣﻞ ﻣﻊ ﻧﻔﺲ اﻟﺤﺎﻟﺔ
)(state
ﺗﻮﻓﯿﺮ اﻟﻤﻮارد :ﺑﺪل ﻣﺎ ﺗﻨﺸﺊ instancesﻛﺘﯿﺮ ﺑﻨﻔﺲ اﻟﻮظﯿﻔﺔ )زي اﺗﺼﺎل ﺑﻘﺎﻋﺪة ﺑﯿﺎﻧﺎت( ،ﺗﺴﺘﺨﺪم instanceواﺣﺪة
ﺗﺤﻜﻢ ﻣﺮﻛﺰي :ﺑﯿﺨﻠﯿﻚ ﺗﺘﺤﻜﻢ ﻓﻲ ﻧﻘﻄﺔ وﺻﻮل واﺣﺪة ) (single point of accessﻟﻠﻜﺎﺋﻦ.
ﺗﺠﻨﺐ اﻟﺘﻜﺮار :ﺑﯿﻤﻨﻊ إﻧﺸﺎء ﻧﺴﺦ ﻣﻜﺮرة ﻣﻦ ﻛﺎﺋﻨﺎت ﺛﻘﯿﻠﺔ زي اﺗﺼﺎﻻت اﻟﺸﺒﻜﺔ.
o
ﻧﺨﻠﻲ اﻟـ Constructor Privateأو Protectedﻋﻠﺸﺎن ﻣﺎﻧﺴﻤﺤﺶ ﻷي ﻛﻮد ﺧﺎرﺟﻲ ﯾﻨﺎدي newوﯾﻌﻤﻞ .Instance
ﻧﺨﺰن اﻟـ Instanceﺟﻮه اﻟﻜﻼس وﻧﺘﺄﻛﺪ إﻧﮭﺎ ﺑﺘﺘﻌﻤﻞ ﻣﺮة واﺣﺪة ﺑﺲ.
Sh
اﻟﻨﺎس ﺑﺘﺘﻠﺨﺒﻂ ﻓﻲ Singleton Patternﻓﻲ [Link]؟
ﺑﯿﺘﻠﺨﺒﻄﻮا ﻓﻲ اﻟـ Singleton Patternﻷﻧﮭﻢ ﺑﯿﻔﻜﺮوا إن ﺗﻄﺒﯿﻘﮫ ﻣﺤﺘﺎج ﺗﻌﻘﯿﺪ زي اﻟﻠﻲ ﻓﻲ اﻟﻠﻐﺎت اﻟﺘﻘﻠﯿﺪﯾﺔ زي Javaأو ،++C
ﻟﻜﻦ ﻓﻲ [Link]اﻟـ module systemﺑﯿﻮﻓﺮ طﺮﯾﻘﺔ طﺒﯿﻌﯿﺔ وﺳﮭﻠﺔ ﻟﺘﺤﻘﯿﻖ اﻟـ Singleton Patternﺑﺴﺒﺐ طﺮﯾﻘﺔ اﻟـ cachingﺑﺘﺎﻋﺘﮫ.
ﻟﻤﺎ ﺑﺘﻌﻤﻞ requireﻟـ [Link] moduleﺑﯿﺨﺰن ) (cacheاﻟـ moduleده ﻓﻜﻞ ﻣﺮة ﺑﺘﻌﻤﻞ requireﻟﻨﻔﺲ اﻟـ moduleﺑﯿﺮﺟﻊ ﻧﻔﺲ اﻟـ .instance
ﯾﻌﻨﻲ ﻟﻮ ﺻﺪرت instanceﻣﻦ moduleأي ﻛﻮد ﺑﯿﺴﺘﺨﺪم اﻟـ moduleده ھﯿﺎﺧﺪ ﻧﻔﺲ اﻟـ instanceوده ﺑﯿﺤﻘﻖ ھﺪف اﻟـ Singletonﻣﻦ ﻏﯿﺮ ﺗﻌﻘﯿﺪ
M
project/
├── app/
│ ├── [Link]
│ ├── node_modules/
│ │ ├── package-a/
│ │ │ ├── [Link]
│ │ │ ├── node_modules/
│ │ │ │ ├── mydb/
│ │ ├── package-b/
│ │ │ ├── [Link]
ﻟﻤﺎذا اﻟـ Singletonﺑﯿﻔﺸﻞ ھﻨﺎ؟
│ │ │ ├── node_modules/
│ │ │ │ ├── mydb/ اﻟـ Singleton Patternﺑﯿﻔﺘﺮض إن ﻓﯿﮫ instanceواﺣﺪة ﺑﺲ ﻓﻲ اﻟﺘﻄﺒﯿﻖ ﻛﻠﮫ .ﻟﻜﻦ ﻓﻲ اﻟﺴﯿﻨﺎرﯾﻮ ده:
├── [Link]
package-a/node_modules/mydb.ﻣﻦ mydbﺑﯿﺴﺘﺪﻋﻲ package-a
ﺑﺴﺒﺐ اﻟـ module resolution [Link]ﺑﯿﺤﻤﻞ ﻧﺴﺨﺘﯿﻦ ﻣﻨﻔﺼﻠﺘﯿﻦ ﻣﻦ mydbوﻛﻞ ﻧﺴﺨﺔ ﺑﺘﺼﺪر instanceﻣﺨﺘﻠﻔﺔ ﻣﻦ .Database
ده ﺑﯿﺨﻠﻲ getDbFromAوgetDbFromBﯾﺮﺟﻌﻮا instancesﻣﺨﺘﻠﻔﺔ وﺑﺎﻟﺘﺎﻟﻲ اﻟﺸﺮط اﻷﺳﺎﺳﻲ ﻟﻠـ instance) Singletonواﺣﺪة(
ﺑﯿﺘﻜﺴﺮ.
ھﻮ Creational Patternھﺪﻓﮫ اﻷﺳﺎﺳﻲ إﻧﻨﺎ ﻧﻨﺸﺊ ﻧﺴﺦ ﺟﺪﯾﺪة ﻣﻦ Objectﻣﻌﯿﻦ ﻋﻦ طﺮﯾﻖ ﻧﺴﺨﺔ ﻣﻮﺟﻮدة أﺻﻼ )(Prototype
ده ﺑﯿﻜﻮن ﻣﻔﯿﺪ ﺟﺪا ﻟﻤﺎ ﯾﻜﻮن إﻧﺸﺎء اﻟـ Objectﻣﻜﻠﻒ أو ﻓﯿﮫ إﻋﺪادات ﻛﺘﯿﺮة ﻣﻌﻘﺪة
ﻓﻲ JavaScriptاﻟـ Prototype Patternﻣﺪﻣﺞ ﻓﻲ اﻟﻠﻐﺔ ﻧﻔﺴﮭﺎ ﺑﺴﺒﺐ اﻟـ .prototypal inheritance
ﻛﻞ ﻛﺎﺋﻦ ﻓﻲ JavaScriptﻋﻨﺪه ) prototypeﺑﺘﻼﻗﯿﮫ ﻓﻲ __ __protoأو ([Link]وده ﺑﯿﺴﻤﺢ ﻟﻠﻜﺎﺋﻨﺎت ﺗﻮرث ﺧﺼﺎﺋﺺ وﻣﯿﺜﻮدز ﻣﻦ ﻛﺎﺋﻨﺎت
ﺗﺎﻧﯿﺔ.
اﻟـ Prototype Patternﺑﯿﺴﺘﻐﻞ اﻟﺨﺎﺻﯿﺔ دي ﻋﺸﺎن ﯾﻨﺸﺊ ﻛﺎﺋﻨﺎت ﺟﺪﯾﺪة ﻋﻦ طﺮﯾﻖ ﻧﺴﺦ prototypeﻣﻮﺟﻮد.
o
اﺳﺘﺨﺪام :Constructor Functionsﺑﻨﻌﻤﻞ داﻟﺔ constructorﻣﻊ prototypeﻣﺸﺘﺮك ﻟﻜﻞ اﻟـ .instances