Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Code
  2. Design Patterns
Code

תבניות עיצוב: תבנית אדפטור (Adapter Design Pattern)

by
Difficulty:IntermediateLength:ShortLanguages:
This post is part of a series called Design Patterns in PHP.
Design Patterns: The Facade Pattern
Design Patterns: The Decorator Pattern

Hebrew (עברית) translation by Victor Sulema (you can also view the original English article)

במאמר שעבר, עברנו על אופן שימוש בתבנית חזית - "Facade Pattern", שיכולה לעזור לפשט תמיכה במערכת גדולה ומורכבת באמצעות מחלקת חזית אחת פשוטה.

במאמר זה אנחנו נמשיך את הדיון על תבניות עיצוב ונתמקד בתבנית אדפטור. ניתן להשתמש בתבנית הזו כשהקוד שלכם תלוי ב-API חיצוני או מחלקה חיצונית אחרת שנוטה להשתנות לעתים קרובות. התבנית הזאת נמצאת תחת קטגוריה "תבניות מבנה" מפני שהיא מלמדת אותנו איך הקוד בכלל ומחלקות בפרט צריכות להיות בנויות למטרת תחזוקה והרחבה נוחה.

אני רוצה להזכיר לכם שוב שתבניות עיצוב (Design Patterns) לא מוסיפות שום דבר חדש למחלקות הרגילות שלכם. במקום זה הן עוזרות לארגן מחלקות, לנהל התנהגותן ויצרתן.

הבעיה

בקוד לעיל אתם יכולים לראות שאנחנו משתמשים במחלקת Twitter לצורך שליחת ציוץ (tweet). אנחנו יוצרים אובייקט של Twitter API ישירות ושולחים ציוצים ל-Twitter. אתם יכולים לפגוש את פיסת קוד הזאת במקומות רבים ברשת. כמו שכבר ראיתם הקוד הזה משתמש בפונקציה $twitter->send('Posting on Twitter'); לצורך זה.

לפני זמן-מה Twitter שינו שם של פונקצית API מ-send ל-sendTweet. השינוי הזה מצביע על הבעיה של כל האנשים שנהגו להשתמש בפונקציה send. מה שנצטרך לעשות זה לשנות את כל הקריאות לפונקציה send ל-sendTweet. תתארו לעמצכם את כמות הזמן העצומה שנשקיע בתיקון קטן לעורך כל האפליקציה ובבדיקתו מחדש.

פתרון

אחד הפתרונות לבעיה המתאורת הוא שימוש בתבנית עיצוב אדפטור (Adapter Design Pattern).

מויקיפדיה:

יצירת שיתוף פעולה בין מחלקות על ידי המרה נכונה בין הממשק המתקבל לממשק המצופה.
In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used from another interface. It is often used to make existing classes work with others without modifying their source code.

במקרה זה אנחנו צריכים ליצור ממשק (interface) עוטף שיאפשר את זה. אנחנו לא נשנה דבר במחלקה חיצונית כי אין לנו שליטה עליה והיא עלולה להשתנות בכל רגע.

אז בואו ניכנס יותר פנימה לקוד ונראה תבנית אדפטור בפעולה:

חיקרו את הקוד לעיל ותוכלו להגיד שלא הכנסנו שינויים למחלקה ראשית Twitter. במקום זה יצרנו ממשק אחד לאדפטור שלנו ומחלקת אדפטור אחת ל-Tweeter.

אחרי כל זה יצרנו אבייקט של מחלקת אדפטור ולא של מחלקה ראשית Twitter. ביצירת אובייקט של מחלקת אדפטור אנחנו מעבירים לה אובייקט של מחלקה ראשית Twitter כארגומנט כך שלמחלקת אדפטור תהיה הפניה למחלקה ראשית והיא יכולה לקרוא למתודות של מחלקה ראשית Twitter.

ועכשיו נבהיר איך נוכל לממש את המתודה ישירות:

נדמיין מצב בו Twitter משנים את שם המתודה שלהם מ-send ל-sendTweet. אז מה שנשאר לנו לעשות זה להכניס שינויים ב-twitterAdapter. הביטו בקוד האדפטור המתוקן שכולל שינוי יחיד בלבד.

שינוי אחד והכל שוב הסתדר.

הוספת אדפטור חדש

בנקודה הזאת ראינו איך אנחנו יכולים לממש תבנית עיצוב אדפטור כדי להתגבר על התרחישים האמורים. עכשיו מאוד קל להוסיף מחלקה חדשה תלויה באדפטור קיים. נגיד שנעדכן סטטוס ב-Facebook מה-Facebook API עצמו.

ואז במקום להשתמש במחלקת Facebook ישירות נפעיל את אותה תבנית אדפטור שממשנו בשביל Tweeter.

כמו שאתם יכולים לראות אותם עקרונות באים לידי ביטוי. אתם מגדירים מתודה זמינה למחלקות צד ג' ואז, אם גורם חיצוני משנה את ה-API שלו, אתם פשוט מתקנים מחלקה תלויה מבלי לחשוף את הממשק החיצוני.

מסכנה

יישומים גדולים ומורכבים תמיד תלוים בספריות אחרות וAPI’s לכן אני מציע להשתמש באדפטור וכך להמנע מחוויות לא נעימות כשספריות צד ג' או API’s משנות את הקוד המקורי שלהם.

ניסיתי את מיטב יכולתיי להעביר לכם דוגמה מצד אחד פשוטה ומצד שני שימושית מאוד כדי להמחיש את תבנית עיצוב אדפטור. אבל אם יש לכם הערות נוספות או שאלות אל תהססו להסיפן בערות להלן.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.