Klasa abstrakcyjna impementujaca interface

Odpowiedz Nowy wątek
2020-06-26 20:07

Rejestracja: 2 lata temu

Ostatnio: 1 tydzień temu

0

Czesc wszystkim to moj pierwszy post tutaj i chcialem zapytac co myslicie o takim modelu klas.

Problem : Impelemntacja klasy Wallet

  1. zapewniajac łatwa rozszerzalność na subklasy,
  2. Wykorzystujacą pewne zbiory metod ktore beda dzielone i innymi niepowiazanymi klasami
  3. mozliwość zapisania wrzucenia takiej encji przez EF do sql server

W aplikacji używam C# i Cora.

Pomysł na zamodelowanie:

interface ITransactionable
{
void DoTransaction();
}

abstract class BaseWallet : ITransactionable
{
// jakies pola
abstract void DoTransaction();
}

class ConcreteWallet :BaseWallet
{
void DoTransaction()
       {
     // jakas implementacja
     }
}

Ma to dla was sens czy troche z d**y taka konstrukcja?

Dzieki za pomoc

Sam jestem ciekawy opinii ekspertów, mi się wydaje że bez sensu dziedziczyć klasą abstrakcyjną po interfejsie - pavarotti 2020-06-26 20:15
Stosuje to bo chce w innynym miejscu iterowac przez obiekty implemenujace ten interface (nie tylko subklasy BaseWallet) a nie chce w kazdej subklasie dodawac tych interfajsow i narazac sie na zapomnienie o tym. Dzieki za opinie - Empek 2020-06-26 20:25

Pozostało 580 znaków

2020-06-26 21:02

Rejestracja: 4 lata temu

Ostatnio: 8 minut temu

Lokalizacja: UK

1

Moim zdaniem to trochę bez sensu, bo tam gdzie faktycznie będziesz musiał przyjąć coś abstrakcyjnego w postaci interfejsu to i tak nie będziesz korzystał z klasy bazowej tylko właśnie przyjmował obiekt typu ITransactionable. Argument za tym że gdzieś można zapomnieć implementować interfejs do mnie nie przemawia. Przy silnym typowaniu nawet jeśli zapomnisz to nie będziesz mógł tego użyć tam gdzie będziesz chciał, a więc już sobie przypomnisz ze trzeba implementować ten interfejs.

No chyba że w ogóle spodziewasz się że każdy typ dziedziczący po BaseWallet będzie musiał obsługiwać transakcje. Wtedy użycie interfejsu będzie niepotrzebne i wystarczy odwoływać się do abstskcyjnej klasy bazowej.

Ogólnie o interfejsach należy myśleć wtedy kiedy mamy na pierwszy rzut oka niepowiązane ze sobą klasy, nie dzielące wspólnej logiki (brak klasy bazowej), a które muszą zapewnić jakąś funkcjonalność która dla każdego typu logicznie jest taka sama. Taka sama w sensie że opis procesu jest ten sam (np. "wykonaj transakcje") ale różnią się szczegółami implementacyjnymi.


Na każdy złożony problem istnieje rozwiązanie które jest proste, szybkie i błędne.

Pozostało 580 znaków

2020-06-26 21:30

Rejestracja: 2 lata temu

Ostatnio: 1 tydzień temu

0

Mam 2 typy obiektow ktore powinny móc wykonac DoTransaction() : Order i Wallet i wszystkie ich subklasy. Chciałem wykorzystac klase abstrakcyjna zeby enkapsulowac pola sub klas do jednej z nich i nie musić ich przepisywac a interfejsy zeby w momencie zakonczenia sesji tranzakcyjnej (zdarzenie biznesowe) przeiterowac przez wszystkie obiekty Order i Wallet i ich subklasy i wykonac metode DoTransaction() w różnych wariantach implementacji.

Ale Twoim zdaniem Avenus lepiej bedzie nie komplikowac i ewentualnie zrobic 2 iteracjie przez obiekty typu Order i Wallet, a wymusić implementacjie DoTransaction przez abstrakcyjne nad klasy? Dobrze zrozumialem ?

Pozostało 580 znaków

2020-06-26 22:40

Rejestracja: 4 lata temu

Ostatnio: 8 minut temu

Lokalizacja: UK

No nie do końca. Teraz kiedy rzuciłeś więcej światła na to jak wygląda Twój kod to użycie interfejsu na klasie abstrakcyjnej nabiera większego sensu. W pewnym sensie masz dwa poziomy abstrakcji, ponieważ masz niepowiązane ze sobą klasy abstrakcyjne, po których dziedziczą inne klasy, i te klasy muszą zapewnić jakiś wspólny kontrakt- wykonanie transakcji. W związku z tym wydaje mi się że podany przez Ciebie kod jest OK.

Chociaż odnośnie samego OOP i dziedziczenia- warto mieć na uwadze że sam fakt tego iż mamy kilka klas które posiadają podzbiór tych samych właściwości niekoniecznie musi oznaczać że powinno się używać klasy bazowej i dziedziczenia. To tak naprawdę kwestia sporna, i można by polemizować że skoro klasa bazowa nie dostarcza żadnego wspólnego zachowania (ang. behaviour) to dziedziczenie niekoniecznie ma sens. No ale jeśli wszystkie klasy dziedziczące będą dzieliły te same właściwości, to również można polemizować że warto zastosować dziedziczenie w tym przypadku. Decyzja należy do Ciebie.


Na każdy złożony problem istnieje rozwiązanie które jest proste, szybkie i błędne.
edytowany 1x, ostatnio: Aventus, 2020-06-26 22:44
Dzieki wielkie Aventus, jeszcze ze dwa razy to wszytko przemysle. Mozesz polecić jakies materiały o OOP czy raczej lecisz z praktyki? - Empek 2020-06-26 22:56
Nie ma za co :) I tak, lecę z praktyki więc niestety nie mam materiałów do polecenia oprócz klasyka czyli "A behavioral notion of subtyping". Ale ostrzegam że to bardzo akademicki materiał. https://www.cs.cmu.edu/~wing/publications/LiskovWing94.pdf - Aventus 2020-06-26 23:39

Pozostało 580 znaków

2020-06-28 01:56
Moderator

Rejestracja: 12 lat temu

Ostatnio: 3 minuty temu

Lokalizacja: Wrocław

1

@Empek - Ty chcesz, aby te obiekty się same do bazy danych zapisywały? Ja bym to przemyślał, bo active record nawet z nazwy nie brzmi jak dobry pomysł.


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."

Pozostało 580 znaków

2020-06-28 08:53

Rejestracja: 2 lata temu

Ostatnio: 1 tydzień temu

0

@somekind - z grubsza taki jest plan. Nie doszedlem jeszcze do tego wzorca w swoim zdobywaniu wiedzy ale brzmi jak Active Record. Takze cos nowego, Dzieki!
Myślałem ze wszyscy jada na ORM'mach i tak robią? Jakie sa sensowne alternatywy ?

Edit:
Chociaż sie zastanawiam czy na pewno. Moja solucja wyglada w taki sposob:

Class Library : Zawiera klasy domenowe w tym Wallet.
Web API dokonuje operacji zmiany stanu i zapisu do bazy na podstawie requestu z Web appki
Web apka tez zmienia stan obiektu ale go nie zapisuje tylko uaktualnia widok i wysyla request do API.

edytowany 1x, ostatnio: Empek, 2020-06-28 09:22

Pozostało 580 znaków

2020-06-28 14:31
Moderator

Rejestracja: 12 lat temu

Ostatnio: 3 minuty temu

Lokalizacja: Wrocław

0
Empek napisał(a):

@somekind - z grubsza taki jest plan. Nie doszedlem jeszcze do tego wzorca w swoim zdobywaniu wiedzy ale brzmi jak Active Record. Takze cos nowego, Dzieki!
Myślałem ze wszyscy jada na ORM'mach i tak robią? Jakie sa sensowne alternatywy ?

No jak dla mnie, to prawie wszystkie inne, ta jest najbardziej bezsensowna.

Chociaż sie zastanawiam czy na pewno. Moja solucja wyglada w taki sposob:

Class Library : Zawiera klasy domenowe w tym Wallet.
Web API dokonuje operacji zmiany stanu i zapisu do bazy na podstawie requestu z Web appki
Web apka tez zmienia stan obiektu ale go nie zapisuje tylko uaktualnia widok i wysyla request do API.

Skoro to Web API zapisuje do bazy, to czemu DoTransaction jest w Wallet?


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."

Pozostało 580 znaków

2020-06-28 15:10

Rejestracja: 4 lata temu

Ostatnio: 8 minut temu

Lokalizacja: UK

0

To DoTransaction odpowiada za zapisanie do bazy danych? Ja myślałem że chodzi o wykonanie transakcji płatniczej, czyli jakiejś logiki biznesowej...


Na każdy złożony problem istnieje rozwiązanie które jest proste, szybkie i błędne.
No ja nie wiem, jak widzę takie coś, to mi się z bazodanową transakcją kojarzy. Być może to moja nadinterpretacja, zaczekajmy na odpowiedź autora. - somekind 2020-06-28 19:40

Pozostało 580 znaków

2020-06-28 20:43

Rejestracja: 2 lata temu

Ostatnio: 1 tydzień temu

0

@somekind : No jak dla mnie, to prawie wszystkie inne, ta jest najbardziej bezsensowna.

mozesz minie odeslac do jakiego źródla albo rzucic jakąś nazwa?

@Aventus - DoTransaction bylo tylko uproszczona nazwa na potrzeby zamodelowania tego w tym wątku.

Metody nazywa BuyAsset (AssetDto asset) i SellAsset(AssetDto asset).
Nie ma nic wspólnego z baza (sorry za słabe nazwnictwo). Metoda triggeruje proces walidacji tranzakcji i wysyła requesta do systemu tranzakcyjnego w servisie WCF.

Nie chciałem zeby to zamotało istotę rozwiazania.

Mając na uwadze wasze uwagi chyba zrezygnuje z jedmego poziomu abstrakcji i Od razu bede operował na normalnej klasie ze wszystkimi metodami zaimplementowanymi ze slowem kluczowym virtual i interfajsem ITransactionable a podklasy beda od niej dziedziczyły.

edytowany 1x, ostatnio: Empek, 2020-06-28 20:53

Pozostało 580 znaków

2020-06-28 21:21
Moderator

Rejestracja: 12 lat temu

Ostatnio: 3 minuty temu

Lokalizacja: Wrocław

1
Empek napisał(a):

@somekind : No jak dla mnie, to prawie wszystkie inne, ta jest najbardziej bezsensowna.

mozesz minie odeslac do jakiego źródla albo rzucic jakąś nazwa?

W sensie wzorców projektowych związanych z przechowywaniem danych?
To np.: Table Data Gateway, Data Mapper, Object Relational Mapping, Unit of Work

Metody nazywa BuyAsset (AssetDto asset) i SellAsset(AssetDto asset).
Nie ma nic wspólnego z baza (sorry za słabe nazwnictwo). Metoda triggeruje proces walidacji tranzakcji i wysyła requesta do systemu tranzakcyjnego w servisie WCF.

Nie chciałem zeby to zamotało istotę rozwiazania.

No ok, czyli to jednak biznesowa transakcja, więc to nie active record.


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."
Dzieki, wczytam sie w ten temat. - Empek 2020-06-28 21:58

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0