Přeakcování/přeeventování vs. větvení – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Přeakcování/přeeventování vs. větvení – .NET – Fórum – Programujte.comPřeakcování/přeeventování vs. větvení – .NET – Fórum – Programujte.com

 

Matěj Andrle+1
Grafoman
8. 7. 2014   #1
-
0
-

Dobrý den,
jelikož dodržuji OOP tak abych spojil 3 vrstvy aplikace k sobě, jako vždy jsem použil akce. Z jádra volám nejobecnější akci, která se postupně nabaluje. A v poslední vrstvě sezná grafického vyjádření. Deklarace akce je daleko jednodušší, než-li deklarace eventu. Každopádně se musím zeptat - je lepší event? Ale především už nyní mám 6 akcí a nevím, zda v tom pokračovat. Potřebuji přidělit klávesám události (no nebyl by pěkný slovník), ovšem každá klávesa může ve spojení s modifikátorem dělat cosi zcela jiného. Tak by zde akce právě dost zjednodušila život. (větvil bych maximálně uvnitř akce pro test modifikátoru.) Je však lepší vícero větvit, než-li eventovat/akcovat?
Děkuji.

Nahlásit jako SPAM
IP: 78.136.165.–
p3can
~ Anonymní uživatel
312 příspěvků
8. 7. 2014   #2
-
0
-

jak spolu souvisi OOP a akce ? co je to ten pojem "akce". nevim jak souvisi "akce" s eventem a klavesami, kdyz jednim eventem de popsat cela klavesnice vcetne modifikatoru a plno dalsich veci.

je lepsi prikladat zdrojaky nez-li krasopisne popisovati problemy  .

Nahlásit jako SPAM
IP: 77.92.213.–
Matěj Andrle+1
Grafoman
8. 7. 2014   #3
-
0
-

Bože - co na tom nechápeš?

jelikož dodržuji OOP tak abych spojil 3 vrstvy aplikace k sobě, jako vždy jsem použil akce

Mám několik vrstev, které jsou méně a méně obecné - komunikace mezi nimi je prováděna přes Action. To znamená, že úplné jádro aplikace není na nic vázané - je to zcela OOP ojedinělý a všude integrovatelný objekt. Druhá vrstva sváže jádro na konkrétní platformu. A třetí vrstva spojí předchozí s konkrétním grafickým pojetím... Pročež jádro jen volá akce typu Draw, OnDdd... A postupně jsou naplňovány konkrétními kódy. Takovýto návrh umožňuje snadné předělání třeba z GTK+ na XNA... A obdobný přechod mi zabral nejdéle 2 minuty. Ptám se přeci zcela obecně - preferovat eventy před akcemi? Preferovat akce/eventy před větvením? Větvit pro klávesy, anebo mít slovník - s tím, že bude muset být pole akcí, jejichž indexy bude mít onen slovník...

Nahlásit jako SPAM
IP: 78.136.191.–
p3can
~ Anonymní uživatel
312 příspěvků
8. 7. 2014   #4
-
0
-

pojem 3 vrstva aplikace je taky takovy hezky "programatorsky obrat" ...

z popisu se nejspise snazis vytvorit nejakou multiplatformni aplikaci. doporucuji pouzit architekturu MVVM, ve ktere je mozne implementovat aplikace pro desktop/web/tablety/telefony. pokud se pouzije existujici MVVM framework tak je to uplna brnkacka. v MVVM se sdili vrstvy ViewModel a Model (vetsinou pomoci PCL), coz je vetsina bussines/aplikacniho kodu. platforme zavisle veci se dodavaji pomoci DependencyInjection. Vrstva View je vlastne "zakladni projekt" pro danou platformu. Obsahuje implementace Platforme závislých tříd + View třídy.

pokud ti z nejakeho duvodu nevyhovuje MVVM a z tveho skromneho popisu muzu pouze doporucit pouziti MVP nebo PM (ted sem stravil hodinu ctenim tech vzoru ale je v tom takovy zmatek ze fakt neni jasne co co dela, takze bych doporucil variantu, kdy ve View nic neni, secko je v Presenteru, Presenter vola View pres DI a View vyvolava akce na Presenteru primo).

    interface ICustomerView
    {
        void DrawCustomerList(object customersList);
        void DrawCustomerPhoto(int x, int y, object photodata);
    }

    class CustomerController
    {
        private ICustomerView view;
        private object customersList;
        
        public CustomerController(ICustomerView view)
        {
            this.view = view;
        }

        public void ShowCustomers()
        {
            //....
            view.DrawCustomerList(customersList);
            //....
        }

        public void SelectCustomer()
        {
            //....
            view.DrawCustomerList(10, 20, customersList[1]);
            //....
        }
    }

    class CustomerView : Form, ICustomerView
    {
        private CustomerController controller;
        public CustomerView()
        {
            controller = new CustomerController(this);
        }
        public void DrawCustomerList(object customersList)
        {
            throw new NotImplementedException();
        }

        public void DrawCustomerPhoto(int x, int y, object photodata)
        {
            throw new NotImplementedException();
        }

        public event Action Save;

        protected virtual void OnSave()
        {
            Action handler = Save;
            if (handler != null) handler();
        }

        public void OnClickShowCustomers()
        {
            controller.ShowCustomers();
        }
    }
Nahlásit jako SPAM
IP: 77.92.213.–
Matěj Andrle+1
Grafoman
8. 7. 2014   #5
-
0
-

#4 p3can
Snažím se především dodržovat OOP. No co snažím - dodržuji OOP paradigma. (oddělení grafiky od logiky, obecnost objektů (každý objekt lze použít kdekoliv jinde) atd.) Děkuji za nápady, každopádně bych chtěl vědět jak stavět. Totiž - jak píši, chci se vyhnout větvení, ale zase spousta dynamického kódu nemusí být zrovna ideální... Leč při spojování vrstev se stejně akci/eventu nemohu vyhnout - jinak bych ty vrstvy neoddělil. Navíc mi to umožňuje vláknit - neboť nic na ničem není přímo závislé...

Nahlásit jako SPAM
IP: 78.136.191.–
p3can
~ Anonymní uživatel
312 příspěvků
8. 7. 2014   #6
-
0
-

jako tady ten "hybrydni nepojmenovany vzor" co sem napsal nevyzaduje "zadne" eventy ani Action (callbacky). kdyz si das do Presenteru referenci na View (pres interface) tak to mas oddelene a muzes interagovat naprimo, zatimco ve View si das Primo referenci na Presenter, takze opet mas primou interakci a tridy jsou relativne oddelene. Pokud vim tak snad ani nejde udelat takove oddeleni aby skutecne doslo k "nezavyslosti" cele vrstvy View nebo cele vrstvy Presenter. Dycky ma nekdo zavislost na nekom.

ale tva otazka jestli misto event/actions pouzivat if me nejak porad neni jasna jak to presne spolu souvisi?

Nahlásit jako SPAM
IP: 77.92.213.–
Matěj Andrle+1
Grafoman
8. 7. 2014   #7
-
0
-

#6 p3can
Mám možnost použít složitou sít slovníku, pole akcí a akcí samotných - kteroužto se vyhnu větvení. Nebude ale tolik dynamického kódu spíše na škodu? Potřebuji pro každou klávesu přiřazenou ke směru (proto se hodí slovník - uživatel si může snadno přiřadit index akce ke klávese) dělat různé akce pro různé modifikátory. Současně switchuji. Má to ale ten problém, že když se v daném směru nedá jít dál, charakter stojí. Onou dynamikou bych mohl testovat, zda další stisklá klávesa náhodou neukazuje na volné místo, kam by se mohlo pokračovat. (změna směru na křižovatce) Byla by to však práce s velice dynamickými daty a s tím nemám dobré zkušenosti - CPU. Především nechci aplikovat začátečnické složité spletence. Tak jsem se nehnul 2 dny z místa a snažím se vymyslet co nejlehčí model, který zajistí dostatečnou dynamiku - za málo peněz hodně muziky. Klávesy nyní jen mění proměnnou směr, modifikátory pak akci - to dosazuji do pole akcí. Do složitosti chybí již jen slovník klávesa -> index akce. To se mi ani za mák nelíbí - musí to jít efektivněji... Současné řešení nehodlám ani omylem ukazovat - proto neukazuji... :)

Nahlásit jako SPAM
IP: 78.136.191.–
p3can
~ Anonymní uživatel
312 příspěvků
9. 7. 2014   #8
-
0
-

pokud se ma neco pohybovat ve 2d osvedcili se me vektory pohybu namapovane primo na klavesy. zas pojem "dynamicky kod" co to je ? xD

podle me staci toto

    public class FormView : Form
    {
        private FormPresenter presenter;
        public FormView()
        {
            presenter = new FormPresenter();
            KeyDown += FormView_KeyDown;
        }

        void FormView_KeyDown(object sender, KeyEventArgs e)
        {
            presenter.DoAction(new KeyStroke(e));
        }


    }


    public class FormPresenter
    {
        private Dictionary<KeyStroke, Action> Actions { get; set; }
        public FormPresenter()
        {
            Actions = new Dictionary<KeyStroke, Action>()
            {
                {new KeyStroke(Keys.W), () => MoveTo(new Size(0, -1))},
                {new KeyStroke(Keys.A), () => MoveTo(new Size(-1, 0))},
                {new KeyStroke(Keys.S), () => MoveTo(new Size(0, 1))},
                {new KeyStroke(Keys.D), () => MoveTo(new Size(1, 0))},
                {new KeyStroke(Keys.Space), () => Shot()},

            };
        }

        private Point ActualPosition { get; set; }
        public void Shot()
        { }
        public void MoveTo(Size vector)
        {
            var newpos = Point.Add(ActualPosition, vector);
            if (newpos.X < 0 || newpos.X > 100 || newpos.Y < 0 || newpos.Y > 100)
                return;

            ActualPosition = newpos;
        }

        public void DoAction(KeyStroke key)
        {
            if (Actions.ContainsKey(key))
                Actions[key]();
        }
    }

    public class KeyStroke : IEquatable<KeyStroke>
    {
        public bool IsCTRL { get; private set; }
        public bool IsALT { get; private set; }
        public Keys Key { get; private set; }

        public KeyStroke(Keys key, bool isCtrl=false, bool isAlt=false)
        {
            IsCTRL = isCtrl;
            IsALT = isAlt;
            Key = key;
        }

        public KeyStroke(KeyEventArgs e)
        {
            IsCTRL = e.Control;
            IsALT = e.Alt;
            Key = e.KeyCode;
        }

        public bool Equals(KeyStroke other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return IsCTRL.Equals(other.IsCTRL) && IsALT.Equals(other.IsALT) && Key == other.Key;
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != this.GetType()) return false;
            return Equals((KeyStroke) obj);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                int hashCode = IsCTRL.GetHashCode();
                hashCode = (hashCode*397) ^ IsALT.GetHashCode();
                hashCode = (hashCode*397) ^ (int) Key;
                return hashCode;
            }
        }

        public static bool operator ==(KeyStroke left, KeyStroke right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(KeyStroke left, KeyStroke right)
        {
            return !Equals(left, right);
        }
    }
Nahlásit jako SPAM
IP: 77.92.213.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 22 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý