Wpis z mikrobloga

#symfony2 #oop

Mam takie usługi:
SendSMS
Prepaid

SendSMS->send() powinna wywołać Prepaid->charge(). Jeśli charge() się nie uda (bo nie ma środków na koncie) to SMS ma nie zostać wysłany.

Mogę to zrobić tak, że do SendSMS dodam zależność Prepaid i będzie działać. Ale co by na to powiedzieli koszerni programiści #php za 15k?

Zastanawiam czy nie lepiej zrobić eventa PrepaidChargeEvent (dispatchowałbym go w SendSMS) i listenera PrepaidListener który będzie wywoływał Prepaid->charge(). A jak z poziomu SendSMS->send() wiedzieć czy można wysyłać? W Prepaid->charge() robić exception jeśli brak kasy na koncie. Wtedy w SendSMS->send() zrobić try .. catch na tym dispatchowaniu i wysyłać lub nie.

Dobrze myślę z tym drugim sposobem? Czy można to lepiej zrobić?
  • 8
Możesz udekorować klasę wysyłającą smsy tak, żeby była świadoma stanu konta. I zrobić metodę send(), któ©a najpierw sprawdzi czy usera stać na SMSa (ew. zrobi blokadę środków), potem go wyśle, a dopiero potem zrobi charge(). Inaczej możesz obciążyć konto za niewykonaną usługę, zakładam że wysyłanie SMSa może się nie udać nie tylko z powodu braku środków na koncie.

To o tyle fajne, że potem bez grzebania w tych klasach będziesz mógł zrobić
@Harry19911: ja bym zrobił klasę PrepaidSendSms która ma wstrzyknięte te dwie klasy, i ona odpowiada za wysłanie i pobranie środków z konta

skąd wiesz czy później nie będziesz potrzebował wysłac sma z jakichś punktów, albo rozliczał smsy na koniec okresu itd. itd. więc po co od razu robić klasę SendSMS taką ciężką

of course pewnie klasa SendSMS może dispatcheować jakieś eventy ale raczej powinno to służyć do jakiegoś general loga wysłanych
@Harry19911: Plus dla @Jaslanin za dobre rozwiązanie – kompozycja. Masz jeden wyspecjalizowany obiekt do wysyłania SMSów, masz drugi wyspecjalizowany obiekt do płatności – zrób trzeci, który połączy te dwa zadania.

Twoje rozwiązanie – z wstrzykiwaniem obiektu płatności do wysyłacza SMSów – też uznałbym za akceptowalne, ALE pod warunkiem, że sygnaturę zależności uzależnisz od interface'u: tzn proponowałbym, żeby SendSms (BTW, czemu nie SmsSender?) dostawał w konstruktorze obiekt spełniający interface SmsSendAuthorizer->auhorize($this, $orWhateverYouNeed)