OOP - Kdy použít interface? – Offtopic – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

OOP - Kdy použít interface? – Offtopic – Fórum – Programujte.comOOP - Kdy použít interface? – Offtopic – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
BigBear0
Stálý člen
2. 7. 2013   #1
-
0
-

Ahojte, mám takový obecný problém v OOP. Vím, co je rozhraní, vím také, co by mělo rozhraní obsahovat a co tedy dělá, ale nějak nevím, kdy rozhraní (interface) typicky tvořit. Kdy se při programování (samozřejmě jen v objektově orientovaném paradigmatu) typicky tvoří tato "entita", ve kterých případech ji mám využít? Rád bych to pochopil pro praktické použití (jsem asi hrozný, protože už pár let programuji jen objektově, ale rozhraní jsem ještě nikdy nevytvořil a nevyužíval :-O ).

Děkuji, mějte se :-) .

Nahlásit jako SPAM
IP: 78.80.88.–
NECIN DRUHYM TO, CO NECHCES, ABY ONI CINILI TOBE!
KIIV
~ Moderátor
+43
God of flame
2. 7. 2013   #2
-
0
-

vyuzijes to hlavne pokud potrebujes stejne rozhrani u ruznych objektu (aby kazdy z nich mel toto rozhrani urcite definovane a mohl si nad nimi delat stejne operace pomoci tohoto rozhrani aniz bys musel kontrolovat co je to za objekt)

Nahlásit jako SPAM
IP: 62.216.147.–
Program vždy dělá to co naprogramujete, ne to co chcete...
BigBear0
Stálý člen
2. 7. 2013   #3
-
0
-

Což znamená, že chci-li například navrhnout nějaký textový editor s podporou vkládání obrázků, grafiky atd. (jen příklad) tak můžu napsat rozhraní ITransformation, kde budu mít "nameldováno", že každá třída implementující toto rozhraní musí implementovat metodu Move(...), Rotate(...), Scale(...) atd. a pak můžu vytvořit třídy např. Text, Image, Shape, které budou implementovat rozhraní ITransformation a tím vlastně sám sebe donutím (protože jinak na mě kompilátor / interpretr bude křičet) doprogramovat funkčnost posunutí, rotace a změny měřítka, je tak?

Je to tedy vlastně hlavně jakýsi "bezpečnostní" mechanizmus, kterým sám sebe (nebo kohokoliv jiného, kdo by chtěl dědit, atd.) donutím něco udělat, abych na to posléze nezapomněl, chápu to dobře?

Nahlásit jako SPAM
IP: 78.80.88.–
NECIN DRUHYM TO, CO NECHCES, ABY ONI CINILI TOBE!
KIIV
~ Moderátor
+43
God of flame
2. 7. 2013   #4
-
0
-

#3 BigBear
jop to je presne duvod, proc rozhrani mit.. v jave kdyz pouzijes rozhrani iterable tak taky musis 100% implementovat nekolik metod aby to pak slo prelozit

jinak na to co popisujes, je dobry taky proletet navrhove vzory... usetri ti to potencialne par problemu uz navrhem

Nahlásit jako SPAM
IP: 62.216.147.–
Program vždy dělá to co naprogramujete, ne to co chcete...
BigBear0
Stálý člen
2. 7. 2013   #5
-
0
-

Ok, super, mockrát děkuji. Na návrhové vzory koukám už kvůli škole, ale do práce se mi hodí také (sbírám zkušenosti a nic nejde najednou, ale postupně je snad všechny - nebo aspoň ty podstatné - pochopím a porozumím jim :-) ). Teď jsem zrovna začal v práci využívat Nette a ve své první aplikaci v tomto frameworku využiji observer kvůli událostem.

Ještě jednou dík.

Nahlásit jako SPAM
IP: 78.80.88.–
NECIN DRUHYM TO, CO NECHCES, ABY ONI CINILI TOBE!
BigBear0
Stálý člen
2. 7. 2013   #6
-
0
-

Tak mě tak napadá, není právě observer rozhraní?

Nahlásit jako SPAM
IP: 78.80.88.–
NECIN DRUHYM TO, CO NECHCES, ABY ONI CINILI TOBE!
KIIV
~ Moderátor
+43
God of flame
2. 7. 2013   #7
-
0
-

pokud pamatuju, tak observer je rozhrani pro posilani notifikaci o nejake akci... jako ze pomoci observeru se zaregistruje callback a pri akci nad objektem, ktera se toho tyka, se tendle callback spusti jako notifikace ze akce probehla...

Nahlásit jako SPAM
IP: 62.216.147.–
Program vždy dělá to co naprogramujete, ne to co chcete...
BigBear0
Stálý člen
3. 7. 2013   #8
-
0
-

Tak vás opět zdravím. Rád bych se teď zeptal na konkrétní dotaz. Jsem webový vývojář a programuji objektově, jak jsem psal výše (nebo se o to alespoň snažím). Web samozřejmě hodně souvisí s prací nad databázemi. Vytvářím tedy třídy implementující jednotlivé tabulky v databázi - resp. jeden řádek takové tabulky (tzn. jedna instance třídy = jeden řádek tabulky). Každá tato třída tedy obsahuje metody save() a delete() a sémanticky dělají totéž, tzn. uloží do databáze nový řádek, příp. updatuje stávající řádek a smaže řádek z databáze.

Měl bych napsat abstraktní třídu, která bude obsahovat tyto dvě metody určené k přepsání a všechny třídy reprezentující jednotlivé tabulky dědit od této třídy nebo bych měl právě napsat interface a každá moje třída bude pak implementovat tento interface? Vím, že v tom je tady asi malý rozdíl, ale co je "správně"?

Děkuji.

Nahlásit jako SPAM
IP: 78.80.88.–
NECIN DRUHYM TO, CO NECHCES, ABY ONI CINILI TOBE!
KIIV
~ Moderátor
+43
God of flame
3. 7. 2013   #9
-
0
-

no zalezi jak moc genericky to udelas... ale technicky vzato muzes mit interface, ktery nastavis v base tride... (nemusis nutne implementovat vsechno, staci jen to co je stoprocentne spolecne .. jako smazat podle primarniho klice a tak) 

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
BigBear0
Stálý člen
3. 7. 2013   #10
-
0
-

Děkuji za odpověď, asi teď budu vypadat hloupě, ale nepochopil jsem to :-(, mohl bys mi to, prosím, zkusit vysvětlit jinak (více dopodrobna, možná maličký příklad - stačí v pseudokódu).

Já nad tím uvažoval tak, že abstraktní třídu bych tvořil, kdybych tam chtěl přidat i nějaké sloty / atributy - pak je logické, že to nemůže být interface. Původně jsem tak zvažoval jakýsi slot "id", který by obsahoval primární klíč tabulky, problém ale je, že ne každá tabulka má jako primární klíč jeden sloupec - není to časté, ale i takové se mi občas podaří udělat ;-). V tomto případě bych byl spíše pro ten interface, kde by byly, jak jsi říkal, metody "smazat dle primárního klíče", "uložit všechna data", ale jestli se nemýlím, tak v interface nemohu metody definovat, takže bych si nemohl "předprogramovat" žádný kousek kódu...

Teď mě tak napadá, to by se dalo automatizovat, ne? Kdybych si vytvořil abstraktní třídu, mohla by vypadat nějak takto (pseudokód): 

abstract class DbTableRowObject
{
    protected string tableName		// název tabulky
    protected array tableColumns        // seznam sloupců tabulky
    protected array primaryKeys         // seznam sloupců tvořících primární klíč

    __construct()
    {
        foreach (getDbColumns(tableName) as column => data) {
            this->column = data->value           // vytvoří atribut třídy
            // potomek může mít i další atributy, takže je nutné uložit někam, které atributy se budou ukládat do databáze
            this->tableColumns.push(column)

            if (data->key == 'PRI') {
              this->primaryKeys.push(column)     // uloží sloupce tvořící primární klíč
            }
        }
    }

    public delete()
    {
        // projde primární klíče a vytvoří klauzuli WHERE
        where = ''
        foreach (this->primaryKeys as attribute) {
            concat(where, ' AND ', key, ' = "', this->attribute, '"')
        }

        if (where == '') {
            throw Exception('There is no primary key specified')
        }

        return Db::getHandler()->where(where)->delete(this->tableName)
    }

    // kontroluje povinné položky - většinou budou tato data přidávána a upravována přes HTML formulář
    protected checkMandatories()
    {
        return true;		// žádné povinné položky
    }

    public save()
    {
        this.checkMandatories()

        // všechny hodnoty už musí být nastaveny, takže z nich vytvoříme pole s údaji do databáze
        data = array()
        foreach (this->tableColumns as attribute) {
            data.push(attribute, this->attribute)
        }

        // jestliže jsou specifikovány (inicializovány) všechny sloupce primárního klíče, budeme updatovat, jinak insertovat
        if (primaryKeySpecified()) {
            // projde primární klíče a vytvoří klauzuli WHERE - stejné, jak u delete, ale to je teď jedno
            where = ''
            foreach (this->primaryKeys as column) {
                concat(where, ' AND ', key, ' = "', this->column, '"')
            }

            return Db::getHandler()->where(where)->update(data)
        } else {
            return Db::getHandler()->insert(data)
        }
    }
}

Myslíš, že je to takto ok nebo to je nějak obecně špatné řešení? V tomto případě bych samozřejmě vůbec neřešil interface, ale použil bych tuto abstraktní třídu, ze které bych dědil, co říkáš/te?

Ještě jednou dík.

Nahlásit jako SPAM
IP: 78.80.88.–
NECIN DRUHYM TO, CO NECHCES, ABY ONI CINILI TOBE!
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, 3 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ý