Seite 1 von 1

Sollte man hier schon das Observer-Pattern verwenden...?

Verfasst: Samstag 13. August 2011, 19:43
von mutetella
Hallo,

wie würdet ihr vorgehen?

So...

Code: Alles auswählen

class Timeframe(object):
    def __init__(self, years, months, days):
        self.years = years
        self.months = months
        self.days = days

class Picker(object):
    def __init__(self):
        self.picked = []

    def pick(self, item):
        do_it = self.picked.remove if \
            item in self.picked else self.picked.append
        do_it(item)

    def __iter__(self):
        for item in self.picked:
            yield item

    def __len__(self):
        return len(self.picked)

Code: Alles auswählen

>>> y = Picker()
>>> m = Picker()
>>> d = Picker()
>>> t = Timeframe(y, m, d)
>>> y.pick(2011)
>>> t.years
[2011]
... oder so ...

Code: Alles auswählen

class Timeframe(object):
    def __init__(self):
        self.years = None
        self.months = None
        self.days = None

    def update(self, years=None, months=None, days=None):
        if years:
            self.years = years
        if months:
            self.months = months
        if days:
            self.days = days

class Picker(object):
    def __init__(self):
        self.picked = []

    def pick(self, item):
        do_it = self.picked.remove if \
            item in self.picked else self.picked.append
        do_it(item)
        self.notify(self)

    def set_notifier(self, notifier):
        self.notify = notifier

    def __iter__(self):
        for item in self.picked:
            yield item

    def __len__(self):
        return len(self.picked)

Code: Alles auswählen

>>> y = Picker()
>>> m = Picker()
>>> d = Picker()
>>> t = Timeframe()
>>> y.set_notifier(t.update)
>>> m.set_notifier(t.update)
>>> d.set_notifier(t.update)
>>> y.pick(2011)
>>> t.years
[2011]
Ist die erste Variante insofern in Ordnung, dass hier Timeframe() quasi 'unter der Hand' aktuell gehalten wird oder sollte, wie in meiner zweiten Variante ein 'Schmalspur-Observer-Pattern' verwendet werden?

mutetella

Re: Sollte man hier schon das Observer-Pattern verwenden...?

Verfasst: Samstag 13. August 2011, 20:01
von snafu
Wieso implementierst du mit `Picker()` das nach, was ein `set()` bereits kann?

Re: Sollte man hier schon das Observer-Pattern verwenden...?

Verfasst: Samstag 13. August 2011, 22:22
von mutetella
@snafu:
Aus 3 Gründen:
- Weil Picker() letztlich noch ein paar weitere Aufgaben, wie z. B. das Bereitstellen einer collection anzuzeigender Elemente, hat.
- Items, die bereits in 'picked' vorhanden sind, nicht nur kein weiteres Mal vorkommen sollen, sondern nach einer erneuten Auswahl wieder entfernt werden müssen. Dazu müsste ich dann auch bei einem set() eine Weiche einbauen, womit der Aufwand derselbe wie bei einer Liste ist.
- 'picked' während seiner weiteren Verwendung sortiert werden muss. Spätestens dann müsste ich eine Liste oder ein Tuple daraus machen.

Ich habe in meinen beiden Beispielen nur eine Kurzform von Timeframe() und Picker() abgebildet, weil es mir erstmal um die Frage geht, ob Picker-Exemplare ihre Veränderungen explizit mitteilen sollen oder man sich das dadurch sparen 'darf', wenn die Picker-Exemplare als Timeframe-Attribute gesetzt sind.

mutetella

Re: Sollte man hier schon das Observer-Pattern verwenden...?

Verfasst: Sonntag 14. August 2011, 10:40
von snafu
Ich weiß zwar nicht, was der tiefere Sinn sein soll, würde aber zu Beispiel 1 neigen und dann allerdings ein `t.years.pick(2011)` nutzen, weil das wesentlich klarer sein dürfte. Du kannst übrigens trotzdem ableiten, wenn auch nicht von einem `set()`. Ungetestet, weil ich weg muss:

Code: Alles auswählen

class Picker(list):
    def pick(self, elem):
        do_action = self.remove if (elem in self) else self.append
        do_action(elem)

Re: Sollte man hier schon das Observer-Pattern verwenden...?

Verfasst: Sonntag 14. August 2011, 12:08
von jbs
Was ist denn durch

Code: Alles auswählen

do_it = self.picked.remove if \
            item in self.picked else self.picked.append
        do_it(item)
gegenüber

Code: Alles auswählen

if item in self.picked:
    self.picked.remove(item)
else:
    self.picked.append(item)
gewonnen?

Re: Sollte man hier schon das Observer-Pattern verwenden...?

Verfasst: Sonntag 14. August 2011, 14:38
von mutetella
@snafu:
Ok, von 'list' abzuleiten macht Sinn.
Einen tieferen Sinn verfolgt das nicht wirklich, die Frage für mich ist, ab wann es angebracht ist, dass Objekt A bei einer Änderung ein Objekt B explizit darüber unterrichtet, auch oder obwohl sich Objekt A bereits als Attribut in Objekt B befindet und Objekt B deshalb nicht zwingendermaßen unterrichtet werden müsste.
Der Aufruf 't.years.pick(2011)' beantwortet mir da schon mal einiges. Ich war so auf die beiden Objekte 'timeframe' und 'picker' und ihre Verbindung miteinander konzentriert, dass ich die Kurve nicht bekommen hab'. Danke für den Hinweis, den ich eigentlich nicht mehr brauchen sollte... :oops:

@jbs:
Überhaupt nichts. Ich bin schon fast zwanghaft in solche Spielereien vernarrt... :wink:
Aber Du hast natürlich Recht, ich werde das ändern...

mutetella