Observer Design Pattern - ماهو

3zcsمنذ 8 سنوات

بسم الله الرحمن الرحيم

بإذن الله ستكون هذه المقالة بداية لسلسلة من المقالات المتعلقة ب Design Patterns الأكثر أستخداما في بيئة Android.

ونستهل هذه السلسلة ب Observer Design Pattern أو ما يسمى ب Publish-Subscribe (Pub-Sub) Pattern.

في تعريف هذا Pattern في كتاب GoF :

اقتباس

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

ولتبسيط التعريف نقول :

عندما تريد تنبيه أو تحديث مجموعة objects عن حدوث تغيير في object أخر

 

جميل جداً, دعنا نضرب مثالاً قبل أن نبدأ.

- لدينا مدونة تنشر مقالات.

- قمت أنت بالأشتراك في قائمة تقوم بتنبيهك في حال صدرت أي مقالة.

- لم تعد مهتما بالمجال الذي تكتب هذه المدونة عنه, قمت بإلغاء الإشتراك منها.

- قام مجموعة من أصدقائك بالإشتراك وإلغاء الإشتراك.

 

المثال السابق هو ملخص لما للكود الذي سنقوم بكتابته في حال فهمك إياه فأنت قطعت شوط كبير في فهم هذا Design Pattern

.

بداية هذا هو UML الخاص بالكود الذي سنكتبه الان, سيتضح أكثر بعد كتابه الكود.

Screenshot from 2016-09-08 14-35-10.png

جميل الان لنبدأ في كتابة الكود

في البداية لدينا two interfaces الأول هو subjuct أو يمكنك أن تسميه puplisher والثاني observer أو يمكنك أن تسميه subscriber - إذا لم تكن تستخدم intrtfaces أثناء كتابتك لبرامجك فقد وضعت مرجع قد يفيدك في نهاية المقالة لمعرفة أهمية وأليه استخدام interfaces-


public interface Subject {
    void addObserver(Observer o);
    void removeObserver(Observer o);
    void notifyObservers();

    public void setUpdate(String article);
    public String getUpdate();
}

public interface Observer {
    void Update ();
}

ليس هناك الكثير من التفاصيل في إنشاء هذين interfaces لكن سنبدأ في التعليق عند مرحلة  implementation

دعنا نبدأ ب subjuct ونسوي له implementation في class Publisher


public class Publisher implements Subject{
    private List <Observer> observers ;
    String article;
    public Publisher() {
        observers = new ArrayList<>();
    }
    
    
    @Override
    public void addObserver(Observer o) {
        observers.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        observers.remove(o);
    }

    @Override
    public void notifyObservers() {
        for(Observer ob : observers)
            ob.Update();
    }

    @Override
    public String getUpdate() {
        return article;
    }

    @Override
    public void setUpdate(String article) {
        this.article = article ;
        notifyObservers();
    }
    
    
    
}

في البداية قمنا بإنشاء List نستطيع أن نسميها قائمة المشتركين في هذا class الذي أفترضنا أنه مدونة لنشر المقالات, ومتغير String والذي هو عبارة عن المقالة التي نريد تنبيه متابعينا حال صدورها.

لدينا ثلاث functions رئيسية لا يكاد يخلو Observer Design Pattern منها وهي :

     addObserver : ﻷضافة متابع جديد لهذا class أو كما يحلو لنا أن نسميه المدون
    removeObserver : لحذف متابع
     notifyObservers : لتنبيه المتابعين ونشر المقالة لهم ,وقد تختلف تصرفاتهم عندما يأتيهم التنبيه منهم يبدأ بقر ائتها  أو إهمالهما أو حفظها لديه لغرض معين أو غير ذلك.

لننتقل الان ل classes التي قامت بعمل implementation ل Observer وهم لا يختلفون كثيرا في implementation


public class Reader implements Observer{
    private String article ;
    private Subject sub ; 
    
    public Reader(Subject blog) {
        article = "" ;
        sub = blog ;
        sub.addObserver(this);
    }
    
    
    @Override
    public void Update() {
        article = sub.getUpdate();
        System.out.println("You :"+article);
    }
    
}

public class Reader implements Observer{
    private String article ;
    private Subject sub ; 
    
    public Reader(Subject blog) {
        article = "" ;
        sub = blog ;
        sub.addObserver(this);
    }
    
    
    @Override
    public void Update() {
        article = sub.getUpdate();
        System.out.println("You :"+article);
    }
    
}

class reader والذي افترضت حين بدأت بكتابة المقالة أنه أنت , وclass الأخر هو Friend والذي افترضت أنه صديقك
كما تلاحظون في كلا classes  قمنا بعمل Override ل update  تحضر المقالة و تقرأها, وفي داخل Constructor قمنا بإنشاء المتغيرات الخاصة بنا والانضمام إلى List المتابعين الخاصين بالمدونة


public class PupSub {

    public static void main(String[] args) {
        // TODO code application logic here
        Publisher pup = new Publisher();
        new Reader(pup);
        new Friend(pup);
        pup.setUpdate("Art1");
        pup.setUpdate("Art2");
        pup.setUpdate("Art3");
        
    }
    
}

في البداية قمنا بإنشاء قائمة المتابعين الخاصة بالمدونة وكانت فارغة قم أنشأنا متابع من Reader class والذي سبق وافترضنا أنه أنت, ثم Friend class والذي هو صديقك.

كلاكما متابع لهذه المدونة والمدون قد وضعكما في قائمته ويقوم بإخباركم عن كل جديد في هذه المدونة فور وصوله وأنتما تقومان بقراءة ما يأتيكما فور ما يأتي.

ثم نشر المدون ثلاث تدوينات عبر setUpdate التي تستدعي notifyObservers ثم تقوم هذه function باستدعاء Update الخاصة بكل class من المتابعين ويقومون بدورهم بتحديث

التدوينات التي لديهم عن طريق استداعاء getUpdate الخاصة بالمدون.

 

قد تجد صعوبة في فهم هذا Pattern وغيره في المرة الأولى وهذا طبيعي. عليك تطبيقة وفهم أجزاءه وبعد ذلك سيتضح لك.

وأخيرا, لماذا أستخدم Observer Design Pattern ؟

Observer Design Pattern يقلل من التداخل في الكود-Low Coupling- وهذا سيسهل عليك في حال رغبت في إضافة classes أو إزالتها, فجميع classes تعمل بشكل مستقل عن بعضها .

 

المراجع:

- http://informatic-ar.com/ال-coupling-وال-cohesion-في-تصميم-البرمجيات/

- https://sourcemaking.com/design_patterns/observer

- Head First Design Patterns

- البرمجة باستخدام Interfaces

كلمات دليلية:
2
إعجاب
6303
مشاهدات
0
مشاركة
0
متابع
متميز
محتوى رهيب

التعليقات (0)

لايوجد لديك حساب في عالم البرمجة؟

تحب تنضم لعالم البرمجة؟ وتنشئ عالمك الخاص، تنشر المقالات، الدورات، تشارك المبرمجين وتساعد الآخرين، اشترك الآن بخطوات يسيرة !