سؤال

أنا أستخدم واجهة الفئة / المراقب المرصودة في Java لتنفيذ نمط المراقب. تتطلب واجهة Observer الكتابة فوق طريقة التحديث (يمكن ملاحظتها O ، كائن Arg).

المشكلة هي أنني أراقب عددًا لا بأس به من الفصول الدراسية ، وقد أصبحت طريقة التحديث () كبيرة جدًا:

public class Foo implements Observer {
    ....

    public void update(Observable o, Object param) {
        if (o instanceof A) {
            // large chunk of code
            ...
        } else if (o instanceof B) {
            // large chunk of code
            ...
        }
            ...
        } else if (o instanceof H) {
            ...
        }
    }

}

من أجل تقسيم الطريقة ، أفكر في تمديد واجهة المراقب مع واجهة eg aobserver ، واجهة bobserver .. والتي تتطلب الكتابة فوق onaupdate ، onBupdate .. على التوالي. ستجعل هذه الطريقة أيضًا من السهل تحديد الملاحظات التي تراقبها الفصل بناءً على الواجهات التي تنفذها.

class Foo implements AObserver, BObserver {
    ....

    public void onAUpdate(Observable o, Object param) {
        if (o instanceof A) {
        // large chunk of code
        ...
    }

    public void onBUpdate(Observable o, Object param) {
        if (o instanceof B) {
        // large chunk of code
        ...
    }
}

المشكلة هي أنه إذا ورثت المراقب ، فلا يزال يتعين علي تنفيذ طريقة التحديث (). لا يمكنني إعادة تسميته إلى Onaupdate أو اسم آخر من اختياري.

اي نصيحه؟ شكرًا.

هل كانت مفيدة؟

المحلول

هنا قمت بترميز تطبيق RAW باستخدام نمط Observer و Dissitor. يمكنك أن تأخذ هذا كفكرة لتعزيزه وملء أينما ترى بعض الثقوب.

public interface IObserver extends Observer {
    public void add(AbstractObservable observable, IObserverVisitor visitor);
    public void remove(AbstractObservable observable);
    public void removeAll();
}

public class Observer implements IObserver {

    Map<AbstractObservable, IObserverVisitor> observableMap =
            new HashMap<AbstractObservable, IObserverVisitor>();

    public void add(AbstractObservable observable, IObserverVisitor visitor) {
        observableMap.put(observable, visitor);
    }

    public void remove(AbstractObservable observable) {
        observableMap.remove(observable);
    }

    public void removeAll() {
        observableMap.clear();
    }

    public void update(Observable o, Object arg) {
        observableMap.get(o).visit(this, o, arg);
    }

}

public class AbstractObservable extends Observable{

    public synchronized void addObserver(IObserver o, IObserverVisitor visitor) {
        o.add(this, visitor);
        super.addObserver(o);
    }

    public synchronized void deleteObservers(IObserver o) {
        o.removeAll();
        super.deleteObservers();
    }

    public synchronized void deleteObserver(IObserver o) {
        o.remove(this);
        super.deleteObserver(o);
    }

    @Override
    public synchronized void deleteObserver(Observer o) {
        throw new UnsupportedOperationException();
    }

    @Override
    public synchronized void addObserver(Observer o) {
        throw new UnsupportedOperationException();
    }

    @Override
    public synchronized void deleteObservers() {
        throw new UnsupportedOperationException();
    }

    @Override
    public synchronized int countObservers() {
        return super.countObservers();
    }

    @Override
    public synchronized boolean hasChanged() {
        return super.hasChanged();
    }

    @Override
    public void notifyObservers() {
        super.notifyObservers();
    }

    @Override
    public void notifyObservers(Object arg) {
        super.notifyObservers(arg);
    }

    @Override
    protected synchronized void clearChanged() {
        super.clearChanged();
    }

    @Override
    protected synchronized void setChanged() {
        super.setChanged();
    }

}

public class Observable1 extends AbstractObservable {
    public void changeSomething() {
      setChanged();
      notifyObservers();
    }
}

public class Observable2 extends AbstractObservable {
    public void changeSomething() {
      setChanged();
      notifyObservers();
    }
}

public interface IObserverVisitor {
    void visit(IObserver obsrvr, Observable obsrvable, Object o);
}

public class ObserverVisitor1 implements IObserverVisitor{

    public void visit(IObserver obsrvr, Observable obsrvable, Object o) {
        System.out.println("updated one");
    }

}

public class ObserverVisitor2 implements IObserverVisitor{

    public void visit(IObserver obsrvr, Observable obsrvable, Object o) {
        System.out.println("updated two");
    }
}

public class ObserverTest {

    @Test
    public void testAnything() {
        Observable1 obsrvable1 = new Observable1();
        Observable2 obsrvable2 = new Observable2();

        Observer obsrvr = new Observer();
        obsrvable1.addObserver(obsrvr, new ObserverVisitor1());
        obsrvable2.addObserver(obsrvr, new ObserverVisitor2());

        obsrvable1.changeSomething();
        obsrvable2.changeSomething();
    }

}

أتمنى ألا تضيع. قون

نصائح أخرى

سأقترح إنشاء واجهة UpdateHandler للقيام بمعالجة أي كتلة رمز معينة. يمكن التعامل مع كل حالة مع خريطة.

عينة الكود يتبع:

// Interface to implement for each case
public interface UpdateHandler {
    public void update(Observable source, Object data) ;
}

أضف حقل مثيل إلى الفصل الرئيسي الخاص بك على النحو التالي:

private Map<Class<?>, UpdateHandler> handlers = new HashMap<Class<?>, Update Handler>();

إنشاء طريقة لتهيئة المعالجات

protected void initializeHandler() {
    handler.put(Integer.class, new IntegerUpdateHandler());
    handler.put(String.class, new StringUpdateHandler());
    ...
}

ستجد طريقة التحديثات ببساطة المعالج المناسب وإرسال المكالمة

public void update(Observable source, Object data)
{
    UpdateHandler handler = handlers.get(data.getClass()) ;
    if (handler == null) 
    {
        // use a default handler ? throw an exception ? your choice ;)
    } else {
        handler.update(source, data) ;
    }
}

سيسمح لك هذا التنفيذ بإضافة معالج جديد حسب الحاجة مع الحد الأدنى من التغييرات.

يمكن إجراء تطبيق آخر محتمل في العمل السابق ، مجرد إجراء من 3 خطوة.

1) تغيير إعلان مجال المعالجات.

Map<Class<?>, Class<? extends UpdateHandler>> handlers ;

2) تغيير طريقة التهيئة

handlers.put(Integer.class, IntegerInputHandler.class);

3) قم بتغيير طريقة التحديث الرئيسية لإنشاء مثيل جديد لتطبيق updateHandler المتوفر.

UpdateHandler handlerInstance = null ;
Class<? extends UpdateHandler> handler = null ;
handler = handlers.get(data.getClass()) ;
...
handlerInstance = handler.newInstance() ;
handlerInstance.update(source, data) ;

انقل قطع الكود في كل حالة إلى الأساليب المسماة بشكل مناسب.

public void update(Observable o, Object param) {
    if (o instanceof A) {
         onAUpdate(o, param);
    }

    if (o instanceof B) {
         onBUpdate(o, param);
    }
}

public void onAUpdate(Observable o, Object param) {

    // large chunk of code
}

public void onABUpdate(Observable o, Object param) {

    // large chunk of code
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top