Forum Coders' city Strona Gwna Coders' city
Nasza pasja to programowanie!
 

 PomocPomoc   SzukajSzukaj   UytkownicyUytkownicy   GrupyGrupy  RejestracjaRejestracja 
Archiwum starego forum + teoria    RSS & Panel/SideBar
 ProfilProfil   Zaloguj si, by sprawdzi wiadomociZaloguj si, by sprawdzi wiadomoci   ZalogujZaloguj 

Potrzebuj szybkiej odpowiedzi na moje pytanie... Zasady

[C++] Obustronna asocjacja z UML



 
Odpowiedz do tematu    Forum Coders' city Strona Gwna -> C i C++
Zobacz poprzedni temat :: Zobacz nastpny temat  
Autor Wiadomo
Luke



Doczy: 17 Cze 2007
Posty: 1893
Skd: Szczecin

PostWysany: Nie Lis 13, 2016 9:46 pm  OP    Temat postu: [C++] Obustronna asocjacja z UML Odpowiedz z cytatem Pisownia

Dostaem zadanie napisania kodu, ktry odpowiadaby diagramowi klas oraz obiektw UML (w zaczniku).
Postanowiem zada pytanie, bo przypadek asocjacji, gdzie obiekty klas s wzajemnie nawigowalne wydaje mi si doegzotyczny (cho przykad jest raczej "yciowy").
Jak naley zamodelowa par klas z asocjacj z licznoci 1..* z obu stron?
W jaki sposb utrzymywa dwustronno nawigacji, zapobiegajc take problemom typu wycieki pamici?

Tutaj moja propozycja rozwizania.



bidirectional-association-c02c626f4c858f5709370222cdf4942237dc82a1.7z
 Opis:
rda przeniesione z GitHuba

Pobierz
 Nazwa pliku:  bidirectional-association-c02c626f4c858f5709370222cdf4942237dc82a1.7z
 Wielko pliku:  1.93 KB
 Pobierano:  40 raz(y)


Z8hg5Fb.png
 Opis:
Diagramy UML

Pobierz
 Nazwa pliku:  Z8hg5Fb.png
 Wielko pliku:  28.51 KB
 Pobierano:  46 raz(y)


_________________
Moje projekty | Tani hosting
Powrt do gry
Zobacz profil autora Wylij prywatn wiadomo Odwied stron autora
marcin_an



Doczy: 26 Maj 2005
Posty: 18822

PostWysany: Pon Lis 14, 2016 3:22 am      Temat postu: Odpowiedz z cytatem Pisownia

Najpierw zastanw si, czy na pewno potrzebujesz 1..* w obydwu klasach: Team oraz Player. Czy na przykad nie moesz jednak mie pustej druyny (dlaczego nie?). Albo czy gracz koniecznie musi mie co najmniej jedn druyn - bo gdyby tam byo, e ma dokadnie jedn druyn, to jeszcze zrozumiae, ale przy moliwoci powizania z wieloma druynami, co czyni t pierwsz takszczegln?

Jeli mimo wszystko nie da si unikn jedynek w asocjacji: obiekt reprezentujcy druyny oraz graczy jednoczenie, ktry co najwyej bdzie mia moliwo udostpniania ich na zewntrz. W ten sposb cay proces tworzenia powizazostaje wewntrz takiego obiektu i na zewntrz wychodz zawsze prawidowo powizane druyny i gracze. Schemat UML w zaczniku. Errata: metody w TeamsManager przyjmuj i zwracaj shared_ptr<Team> oraz shared_ptr<Player> zamiast, odpowiednio Team i Player (pomyk zauwayem po zrobieniu obrazka).

Alternatywnie, jeli nie chcesz tworzytakiego specjalnego obiektu: fabryka (metoda) i ukryty konstruktor tworzcy niedokoczony obiekt:
Kod:
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <cstdlib>
using namespace std;

class Player;
class Team;

class Player final
{
    friend class Team;
    
    private:
        string const name;
        vector<shared_ptr<Team>> teams;
        
        static shared_ptr<Player> makeWithoutTeam(string const& name)
        {
            return shared_ptr<Player>(new Player(name));
        }
        
        Player(string const& name)
            : name(name) {}
        
    public:
        Player(string const& name, shared_ptr<Team> firstTeam)
            : name(name), teams({firstTeam}) {}
        
        void addTeam(shared_ptr<Team> team)
        {
            teams.push_back(team);
        }
        
        string const& getName() const
        {
            return name;
        }
        
        template <class Callback>
            void onEachTeam(Callback callback) const
            {
                for (auto team: teams)
                {
                    callback(team);
                }
            }
};

class Team final : public enable_shared_from_this<Team>
{
    private:
        string const name;
        vector<shared_ptr<Player>> players;
            
    public:
        static shared_ptr<Team> newWithPlayer(string const& teamName,
          string const& playerName)
        {
            shared_ptr<Player> unfinishedPlayer
              = Player::makeWithoutTeam(playerName);
            shared_ptr<Team> out
              = make_shared<Team>(teamName, unfinishedPlayer);
            unfinishedPlayer->teams.push_back(out);
            return out;
        }
        
        Team(string const& name, shared_ptr<Player> firstPlayer)
            : name(name), players({firstPlayer}) {}
        
        shared_ptr<Player> addNewPlayer(string const& playerName)
        {
            shared_ptr<Player> unfinishedPlayer
              = Player::makeWithoutTeam(playerName);
            players.push_back(unfinishedPlayer);
            unfinishedPlayer->teams.push_back(shared_from_this());
            return unfinishedPlayer;
        }
        
        string const& getName() const
        {
            return name;
        }
        
        template <class Callback>
            void onEachPlayer(Callback callback) const
            {
                for (auto player: players)
                {
                    callback(player);
                }
            }
};

static void printTeam(shared_ptr<Team> team)
{
    cout << "Team: " << team->getName() << '\n';
    team->onEachPlayer([](shared_ptr<Player> player) {
        cout << " - " << player->getName() << '\n';
    });
}

int main()
{
    shared_ptr<Team> fooTeam = Team::newWithPlayer("Team Foo", "Foo Fooinsky");
    shared_ptr<Team> barTeam = Team::newWithPlayer("Team Boo", "Boo Bookovich");
    
    fooTeam->addNewPlayer("Ivan Fooinsky");
    barTeam->addNewPlayer("Baara Baarska");
    
    printTeam(fooTeam);
    printTeam(barTeam);
    
    return EXIT_SUCCESS;
}

Zaprzyjanienie nie amie tutaj enkapsulacji, bo powizania z jedynk po obydwu stronach zawsze tworz twr bdcy de facto pojedynczym bytem, ktry z jaki powodw zosta rozdzielony w implementacji na dwa elementy. Te elementy bd jednak ze sob cile i nierozerwalnie zwizane, i bd w sobie nawzajem grzebay. Warto tylko ustali, e jeden jest nadrzdny i stara siw nim umieszcza kod odwoujcy si do prywatnych elementw drugiego - to przynajmniej do pewnego stopnia chroni przed pomykami przy programowaniu, bo wszystkie ryzykowne operacje s w jednej klasie.

Dalej: zwr uwag na kolejno wywoywania metod i uniknicie uywania publicznych metod do manipulacji obiektem - to sdwie krytyczne sprawy. Pierwsza: zawsze najpierw konstruktor tworzcy niedokoczony obiekt, potem jego dokoczenie i dopiero cokolwiek innego, i zawsze statyczna metoda robica toperacj, a nie prby atania obiektw w konstruktorze. W przeciwnym przypadku ryzykujesz wyciek this. Tutaj akurat obydwie klasy s finalne, wszystko dziaa w jednym wtku i bez odwoa do innych metod, wic ujdzie*, ale gdyby nie to - kopoty murowane. Druga: publiczne metody zawsze maj prawo zaoy, e obiekt jest w prawidowym stanie; natomiast tutaj ewidentnie podczas tworzenia w nim nie jest, wic uycie publicznej metody przed zagwarantowaniem owego stanu nie jest najlepszym pomysem.

____
* Chocia smrd potencjalnych problemw unosi siw powietrzu.



manager.png
 Opis:

Pobierz
 Nazwa pliku:  manager.png
 Wielko pliku:  5.88 KB
 Pobierano:  35 raz(y)

Powrt do gry
Zobacz profil autora Wylij prywatn wiadomo
Luke



Doczy: 17 Cze 2007
Posty: 1893
Skd: Szczecin

PostWysany: Pon Lis 14, 2016 10:24 am  OP    Temat postu: Odpowiedz z cytatem Pisownia

Dzikuj za rozjanienie sprawy. Licznoci 1..* byy umylnie, jako element zadania, wic nie mona ich zlikwidowa.
Mylaem wczeniej nad zaprzyjanieniem, wic to rozwizanie bardziej mnie przekonuje.

_________________
Moje projekty | Tani hosting
Powrt do gry
Zobacz profil autora Wylij prywatn wiadomo Odwied stron autora
Wywietl posty z ostatnich:   
Odpowiedz do tematu    Forum Coders' city Strona Gwna -> C i C++ Wszystkie czasy w strefie CET (Europa)

Strona 1 z 1

 
Skocz do:  
Moesz pisa nowe tematy
Moesz odpowiada w tematach
Nie moesz zmienia swoich postw
Nie moesz usuwa swoich postw
Nie moesz gosowa w ankietach
Moesz dodawa zaczniki na tym forum
Moesz pobiera pliki z tego forum




Debug: strone wygenerowano w 0.21168 sekund, zapytan = 13
contact

| Darmowe programy i porady Jelcyna | Tansze zakupy w Helionie | MS Office Blog |