Czy da sie stworzyć właściwość która była by wspólna dla kilku obiektów róznych klas?

1

Powiedzmy że mamy klasy

Osoba
Przedmiot

i ich obiekty osoba, przedmiot

Czy możliwe jest stworzenie właściwości tych klas tak by były dzielone?
np gdyby

przedmiot.adres = coscosocs;

było tym samym co

osoba.adres = coscosocs;

tzn zeby właściwość "adres" w obiekcie osoba i przedmiot wskazywały na to samo miejsce w pamięci?
Bez wykorzystania "ref" oraz przesyłania parametrów?

P.S. Jaki jest najlepszy sposób na przesyłanie danych pomiędzy odległymi klasami?

Np obiekt "obiekt" tworzy obiekt "cos" ktory tworzy obiekt "innecos" i innecoś wykonuje jakas metode która zwracala by wartość bezpośrednio do "obiekt" bez przesyłania tej informacji przez "coś" ?

Myslałem o stworzeniu osobnego obiektu do którego wszystkie inne obiekty miały by dostęp i który przechowywał by wazne wartości, ale nie bardzo wiem jak sie za to zabrać żeby na każdym poziomie każdy obiekt miał dostęp do tego obiektu-kontenera

0

Musisz przede wszystkim dobrze przemyśleć sprawę zależności pomiędzy twoimi encjami. W teorii jest możliwe zrealizowanie zachowania, o którym mówisz - żeby pozornie niezależne obiekty współdzieliły właściwości - jednak jest to złe rozwiązanie, bo przede wszystkim nieintuicyjne. Dlaczego niby zmiana adresu jakiejś osoby miała by zmienić adres niepowiązanego z nią przedmiotu? Przecież nie mają ze sobą związku. A może jednak mają? To wyraź to w swoim modelu.

0

jeśli potrzebujesz czegoś tak dziwnego, to znaczy, że masz źle napisany kod. u podstaw programowania obiektowego leży wymaganie, żeby nic nie bazgrało obiektowi po jego danych poza nim samym. dlatego też używa się getterów i setterów (a niektórzy psioczą i na to) lub metod obiektu, które poproszą go o zmianę jego danych.

0

Ok to powiedzmy że mam solucje wykorzystująca wzorzec MvP i w widoku mam "konsole" czyli takiego textboxa do którego chciałbym wprowadzac informacje na temat tego "co się dzieje w głębi programu" na przykład "Wylosowana została liczba x" albo "Plik nie istnieje",
"Model" tworzy obiekt dane który potem tworzy obiekt osoba oraz obiekty klas aż sie robi ładna piramidka klas, jaki jest najlepszy sposób na to żeby obiekt stworzony gdzieś głębi (np Osoba) przesłała wiadomość raportującą swoje funkcjonowanie do prezentera aby ten mógł przesłac ją do widoku do textboxa?
Oczywiscie bez cofania sie z obiektu do obiektu przy pomocy parametrów i "ref"a bo wydaje mi sie ze to bardzo złe rozwiązanie :P

0

klasa Osoba nic nie przesyła, nie taka jest rola klasy tego typu. jeśli potrzebujesz coś wyświetlić, to presenter pobiera odpowiednią wartość z obiektu modelu i wpycha ją do view.
ref jest kompletnie zbędne, przecież obiekty mają pola i metody, mogą też rzucać zdarzeniami. ale jeśli zrobiłeś sobie zbyt duży stosik obiektów, to teraz przepychaj sobie dane/subscriberów zdarzenia zmiany tekstu przez wszystkie obiekty stojące po drodze...

0

można zrobić coś takiego...

    class Osoba
    {
        string adres_WTF
        {
            get
            {
                return przedmiot.adres;
            }
            set
            {
                przedmiot.adres = value;
            }
        }
0

Hmmm, możliwe ze czegos nie rozumiem albo źle przedstawiłem swój problem :P

Wszystko we wzorcu MvP
Powiedzmy że mamy maly algorytmik który na przykład generuje liste losowych imion i zapisuje ją do pliku, powiedzmy, że w trakcie tego algorytmu wystepują takie czynności jak sprawdzenie czy plik istnieje i jeśli nie to przesyłanie wiadomości do wcześniej wspomnianej "konsoli" która jest w widoku i pare obiektów "dalej". W trakcie swojego działania wysyła jeszcze pare innych wiadomości do konsoli, np jakies wybrane imiona. Konsola znajduje sie w widoku, algorytm w modelu zakopany w innych obiektach.

Jak zrobić żeby ten program wysyłał te wiadomości w trakcie działania tego algorytmu? W danym konkretnym momencie gdy jest ona aktualna, a nie gdy algorytm zakonczy swoje działanie?
Bo chyba z get i set musiał bym z obiektu ktory zainicjowal obiekt osoba wywolywac pobranie wiadomosci, która może być juz nie aktualna.

2
Vehumet napisał(a):

Jak zrobić żeby ten program wysyłał te wiadomości w trakcie działania tego algorytmu? W danym konkretnym momencie gdy jest ona aktualna, a nie gdy algorytm zakonczy swoje działanie?

W takim przypadku powinieneś użyć zdarzeń.

0

Dziekuje, poczytałem troche o delegatach, głównie chce je tak wykorzystywać by obiekty które sa nisko w hierarchii mogły używać metod obiektu który stworzył tamte obiekty
np obiektA stworzył obiektB i żeby obiektB wykonał metodę stworzona w obiekcieA

na ten moment zrobiłem to tak i działa

class Program
    {
        public static void WyswietlWiad(string msg)
        {
            Console.WriteLine(msg + ": Wiadomosc przesłana pomyślnie.");
        }

        private delegate void Delegata(string msg);
        private static  Delegata del;

        static void Main(string[] args)
        {
            del += WyswietlWiad;
            Controller con = new Controller(del);            
            Console.ReadLine();
        }
    }
class Controller
    {
        public Controller(Delegate del)
        {
            del.DynamicInvoke("lul");
        }
    }

Jednak mam przeczucie, że robie to od złej strony, mogłby mi ktoś przedstawić na prostym przykładzie jak poprawnie powinny byc wykorzystywani delegaci? Głównie wydaje mi sie ze w klasie Controller robie coś nie tak, mimo ze działa :P

0

delegaty to nie zdarzenia

0
ŁF napisał(a):

delegaty to nie zdarzenia
Ostatnio się nad tym zastanawiałem, i właściwie nie wiem, po co jest w C# słowo event.

Bo czym się właściwie różni

public event EventHandler Click;

od

public EventHandler Click;

?

2

event to taka właściwość, ale dla delegaty. Nikt spoza twojej klasy nie może na przykład go wywołać albo nadpisać jej. Możesz również dostarczyć własne metody add i remove.

0

Delegaty to coś boskiego :D Idealnie rozwiazały moj problem, oto jak go rozwiazalem :P

Moja solucja wykorzystuje wzorzec MvP, ale dodałem do niej projekt o nazwie ConDel (Controla Delegatów) do którego wszystkie częsci solucji oprócz widoku maja referencje.

namespace ConDel
{
    public delegate void Wiadomosc(string msg);

    public class Controller
    {
        
        private Wiadomosc _wiadomosc;

        public void Add(Wiadomosc wiadomosc)
        {
            _wiadomosc += wiadomosc;               
        }

        public void Wywolaj(string msg)
        {
            _wiadomosc(msg);
        }
    }
}

nastepnie w prezenterze utworzyłem obiekt klasy Controller _controller; i w konstruktorze prezentera dodałem do delegata metode updatujaca "Konsole widoku", a nastepnie przesłałem delegata dalej do modelu jako parametr metody zczytujacej delegata. (z jakiegos powodu nie mogłem dac delegata jako parametr w konstruktorze modelu, wywalalo mi bład zwiazany cos z referencja)

namespace Prezenter
{
    public class CPrezenter
    {
        private CModel _data;
        private IWidok _view;
        private Controller controller;       

        public CPrezenter(IWidok view) : this(view, new CModel())
        {}
        public CPrezenter(IWidok view, CModel data)
        {
            _view = view;
            _data = data;
            controller = new Controller();
            controller.Add(UpdateKonsole);
            _data.GetDelegate(controller);
        }

        public void UpdateKonsole(string msg)
        {
            _view.Message = msg;
        }
    }
}

Model tworzy obiekt osoba i przesyła controller dalej jako parametr konstruktora Osoba

namespace Model
{
    public class CModel
    {
        private Osoba osoba;
        private Controller _controller;
        public void GetDelegate(Controller controller)
        {
            _controller = controller;
            osoba = new Osoba(_controller);

                osoba.ZmienImie("Krzys");

        }
    }
}

Nastepnie obiekt klasy Osoba może w dowolnym momencie działania dowolnych algorytmów wywoływać metode aktualizowania konsoli która znajduje się w prezenterze, a konsola w widoku, to samo tyczy sie objektu klasy Model a także wszystkich innych obiektów które otrzymaja obiekt controller.

namespace Model
{

    class Osoba
    {
        private Controller _controller;

        private string imie;
        private string nazwisko;
        private int wiek;

        public Osoba(Controller controller)
        {
            _controller = controller;
        }

        public void ZmienImie(string zimie)
        {
            imie = zimie;
            _controller.Wywolaj("imie zostało zmienione na " + imie);
            imie = "karolek";
            _controller.Wywolaj("imie zostało zmienione na " + imie);
        }
            
    }
}

Moj "Widok" poniżej

namespace Widok
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, IWidok
    {
        CPrezenter prezenter;

        public MainWindow()
        {
            InitializeComponent();
            prezenter = new CPrezenter(this);
        }

        string IWidok.Message
        {
            get
            {
                return _tbkonsola.Text;
            }
            set
            {
                _tbkonsola.Text += value + Environment.NewLine;
            }
        }
    }
}

Wybaczcie, że tak wszystko wypisuje ale gdy tłumacze to lepiej mi to do głowy wchodzi i może sie to przyda komuś innemu jeszcze :P Albo przynajmniej zostane solidnie skrytykowany za łamanie zasad programowania obiektowego i poprawie swoje błedy xD

0
Vehumet napisał(a):

Delegaty to coś boskiego :D

A o wskaźnikach na funkcje słyszałeś? ;)

Dlaczego używasz DynamicInvoke?

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