שלום לכולם, חברי הפורום!
הבנתי ביסודיות (נראה לי) את הדפוס
Command
ואני רוצה לנסות לדבר על זה "במילים שלי".
בהתבסס על ויקיפדיה נוכל לגלות שמטרתה
ליצור מבנה בו המחלקה השולחת והמחלקה המקבלת אינן תלויות ישירות זו בזו. ארגון התקשרות חזרה למחלקה הכוללת את מחלקת השולח . באופן עקרוני זה כתוב בצורה ברורה ונכונה, אבל זה בתיאוריה. איך לעשות את זה? כאן מתחילות הבעיות, כי... התיאור כבר לא כל כך ברור ומובן מאליו. לכן, הבנתי את זה, החלטתי לספר לך איך הבנתי את זה, אולי זה יהיה שימושי למישהו: בהתבסס על תיאור המטרה של הדפוס הזה, אשלב את התיאור עם הקוד כדי שיהיה ברור יותר, כי באותה ויקיפדיה הכלילו את זה לשפות רבות ולכן התיאור מופרד מהדוגמה. ישנם ארבעה מונחים בדפוס הזה, בואו ניקח אותם כמובן מאליו לעת עתה: פקודות (
command
), מקבל פקודות (
receiver
), מתקשר לפקודה (
invoker
), ולקוח (
client
). אקח דוגמה מאותה ויקיפדיה, היא די נסבלת.
המשימה היא כיתה
Light
שיכולה לעשות שני דברים: להדליק את האור ולכבות אותו. מבחינת הדפוס זה יהיה "מקלט פקודה (
receiver
)"
public class Light{
public Light(){ }
public void turnOn(){
System.out.println("The light is on");
}
public void turnOff(){
System.out.println("The light is off");
}
}
בואו ניצור ממשק עם שיטה אחת
execute()
שתבצע ואשר נקראת במונחים של תבנית ה"פקודה (
command
)"
public interface Command{
void execute();
}
יש צורך לכלול את הביצוע של מיומנויות בכיתה
Light
. לשם כך, ניצור מחלקות שיטמיעו את הממשק
TurnOnLightCommand
ואשר יקבלו אובייקט מחלקה בבנאי . וכל אחד מהם יבצע רק פעולה אחת. אחד יקרא לשיטה , והשני יקרא .
TurnOffLightCommand
Command
Light
turnOn()
turnOff()
public class TurnOnLightCommand implements Command{
private Light theLight;
public TurnOnLightCommand(Light light){
this.theLight=light;
}
public void execute(){
theLight.turnOn();
}
}
public class TurnOffLightCommand implements Command{
private Light theLight;
public TurnOffLightCommand(Light light){
this.theLight=light;
}
public void execute(){
theLight.turnOff();
}
}
עכשיו הגיע הזמן ליצור אובייקט שמקבל את שיטות האובייקט המובלעות הללו
Light
. מבחינת התבנית, הוא נקרא מתקשר הפקודה (מעורר). בואו נקרא לזה
Switch
וניתן לו לקבל משתנים בקונסטרוקטור
Command
שישמשו בשיטות שנוצרו
flipUp()
ו
flipDown()
.
public class Switch {
private Command flipUpCommand;
private Command flipDownCommand;
public Switch(Command flipUpCommand,Command flipDownCommand){
this.flipUpCommand=flipUpCommand;
this.flipDownCommand=flipDownCommand;
}
public void flipUp(){
flipUpCommand.execute();
}
public void flipDown(){
flipDownCommand.execute();
}
}
וכמובן, ניצור כיתה שתשתמש בהם כדי להבין מה קורה באופן כללי. זה ייקרא השיטה העיקרית, שבה כל הפעולה תתבצע:
public class TestCommand{
public static void main(String[] args){
Light l=new Light();
Command switchUp=new TurnOnLightCommand(l);
Command switchDown=new TurnOffLightCommand(l);
Switch s=new Switch(switchUp,switchDown);
s.flipUp();
s.flipDown();
}
}
הפלט יהיה הבא:
"The light is on"
"The light is off"
איפה זה מיושם?
המטרה ברורה מה ולמה זה צריך, כלומר: במצב שבו צריך להפריד ביצוע ספציפי זה מאוד נוח. כך שהשימוש בפונקציות מסוימות אינו תלוי ביישום ספציפי וניתן לשנות אותו מבלי לפגוע במערכת. משהו כזה...) תכתוב את ההערות שלך, בוא נדון, אולי אפשר לעשות משהו יותר פשוט ולספר טוב יותר, אנחנו נערוך הכל במידת הצורך) כדי שלמי שקורא בפעם הראשונה זה יהיה כמה שיותר ברור. ובכן, מי שאוהב את המאמר שם עליו "+" :) זה חשוב לי) עם הזמן, אני רוצה לכתוב עוד על
Builder
,
Singleton
ואחרים.
ראה גם מאמרים אחרים שלי:
GO TO FULL VERSION