Hei pitkästä aikaa kaikki rakkaat foorumilaiset,
tuota, tuota.. teen tällä hetkellä tapahtumapalvelusta versiota 2. Tarkoitus olisi rakentaa tämä web-palvelu luokkien ja olioiden varaan ja upottaa WP:n sisään.
Paljon on jo tehty. Oma teema, lapsiteema sekä plugin. Mutta haluaisin kysyä yleistä arviota kautta mielipidettä teiltä miten edetä. Eli yritän saada tällaisia asioita luokiksi. Kuka perii ja mitä? Jne.
---
Taulut:
- tapahtuma
- työntekijä
- varaus
- ryhmä
- tarve
- kuva
Tehtävät:
- tietokantayhteys
- ylläpito-osio
- julkinen puoli
- käyttäjä
- työntekijä
- tapahtumat
- käyttäjäprofiili
jne.
----
Sekavaa, ehkä... nyt on tällainen global $wpdb; olio, joka on ikään kuin pääluokka. Siitä periytän luokan, jonka alla olisi taulujen mukaan nimettyjä luokkia. Ongelmana on se että kannattaako olla esim. näin:
class wpdb (tietokantayhteys)
class general extends wpdb (erilaisia yleisfunktioita)
class tables extends general extends wpdb (tapahtumat, työntekijät, varaukset jne.)
- Eli se mitä yritän selvittää, onko järkevää muodostaa tällainen pyramidi rakenne. VAI... tällainen
pääluokka
luokka1
luokka2
luokka3
perusluokat perivät omissa tiedostoissaan pääluokan ominaisuuden (tietokantayhteys). Ongelmana ja haasteena on WordPress, joka parhaimmillaan on uskomaton, mutta pahimmillaan aika vaativa ympäristö. Kun aktivoin pluginin tapahtuu asioita, se on ok. Mutta sitten miten rakentaa luokat kun käsitteitä niin paljon. Luokista tulee aika isoja vaikka yritän niitä pilkkoa.
Tapahtumat
- hae kaikki tapahtumat (admin, julkinen, omat työvuorot)
- muokkaa tapahtumaa
- poista tapahtuma
- tee tapahtuma
Työntekijä
- uusi
- muokkaa
- poista
- varaukset
- tunnista
- profiili
Käyttäjä
- sisäänkirjautuminen WP
- sisäänkirjautuminen admin
- tunnistus
- oma profiili asetukset
- oma kuva + tiedot
Sitten vielä Tarve, Ryhmä, Varaukset, Kuvat jne. Eli kyse tapahtumapalvelusta, joka tarjoaa mahdollisuuden varata työvuoroja netissä (työntekijät). Asiakkaille sitten muuta, kiitos huomiosta, pahoittelut sekavuudestani.
---
Lyhyesti vielä tuosta luokkahierargiasta: Eli kun minulla on luokkaA jonka ominaisuudet perii luokkaB sitten kuvioihin astuvat luokat C D E ...
- Niin voivatko nyt A ja B olla yliluokkia ja C D E alaluokkia. Yksinkertaisesti näin vai pitäisikö puhua, isovanhemmista, vanhemmista, lapsista jne.
---
Toinen lisäkysymys, voinko muodostaa php-sivuilla aina jonkin ylläolevista luokista uudelleen 'new' komennolla? Vai onko jotenkin järkevää että tällainen uusi olio/luokka muodostettaisiin jossain yhdessä tiedostossa yhden kerran? Tällä hetkellä homma toimii esim. näin:
<?php $tapahtuma = new TapahtumaOlioLuokka; $tapahtumaTaulu = $tapahtuma->hae_tapahtuma_taulukko(); echo $tapahtumaTaulu; ?>
Koodaan WP:n standardien mukaan, mutta ylläolevan mallin tyylisesti.
Kysymyksesi alue on todella laaja ja erillaisia tapojahan on yhtä paljon, kuin tekijöitä, mutta voisin muutaman mielestäni hyödyllisen linkin antaa, sekä omia mielipiteitä kyseisistä asioista. En osaa myöskään sanoa kuinka neuvoni soveltuvat WP:n käytön kanssa, koska en tunne kyseistä ympäristöä (enkä muitakaan PHP-frameworkeja).
Aikaisemmassa keskustelussa The Alchemist antoi sinulle yhdenlaisen tavan kyseisten "modeleiden" toteuttamiseen. Toivottavasti sinulla on kyseinen paketti tallessa, koska linkki tuntuu huonosti toimivan. Jos ei niin voin kyllä pyydettäessä sen vielä nettiin ympätä. Koko ketju muutenkin liippaa tosi läheltä kysymystäsi niin suosittelen kahlaamaan sitä uudelleen lävitse.
Toinen tapa voisi olla seuraavanlainen (How should a model be structured in MVC?), johon Stack overflow -sivustolla törmäsin ja jota itse lähtisin käyttämään. Itselläni ei tosin ole kovin vankkaa kokemusta näissä asioissa.
Sitten tuohon luokka pulmaasi.
Minkälaisista "yleisfunktioista" kyseisessä class general extends wpdb (erilaisia yleisfunktioita) luokassa olisi kyseessä? Eikö kyseisiä "yleisfunktioita" voisi laittaa vaikka omaan tiedostoon kuvaavan nimiavaruuden taakse seuraavan kömpelön esimerkin tapaan?
<?php // wpdbfunktiot.php namespace wpdb; function validateEmail($email) { if (empty($email)) { return false; } return true; }
<?php // UserDomainObject.php namespace DomainObject; require_once 'wpdbfunktiot.php'; class UserDomainObject { public $username, $email; public function __construct($username, $email) { $this->username = $username; if (\wpdb\validateEmail($email)) { $this->email = $email; } else { throw new Exception; } } public function __toString() { return $this->username . ' ' . $this->email; } }
<?php // Käyttö require_once 'UserDomainObject.php'; $user1 = new DomainObject\UserDomainObject('user1', 'email'); echo $user1; // user1 email $user2 = new DomainObject\UserDomainObject('user2', ''); echo $user2; // Uncaught exception
Käytä perintää sillon kun sille on tarvetta.
<?php // AbstractDataMapper.php namespace DataMapper; abstract class AbstractDataMapper { protected $db; public function __construct($db) { $this->db = $db; } /** * Tänne esim. The Alchemistin koodissa olevan getOne() yms. geneeriset funktiot. */ }
<?php // UserDataMapper.php namespace DataMapper; require 'AbstractDataMapper.php'; require 'UserDomainObject.php'; class UserDataMapper extends AbstractDataMapper { public function __construct($db) { parent::__construct($db); } public function getUsers() { // DB queries etc. $this->db->prepare('...'); $users = array( new \DomainObject\UserDomainObject('user1', 'email1'), new \DomainObject\UserDomainObject('user2', 'email2') ); return $users; } }
Tuosta perinnässä käytettävästä nimeämisestä Wikipedia antaa useita esimerkkejä, jotka varmaan vapaasti suomennettuna olisivat juuri nuo lapsi tai aliluokka jne.
Toiseen lisäkysymykseen vastauksena antaisin, että teet vain yhden tuon kaltaisia olioita, jota käytät sitten paikoissa missä tarvitsee. Yksi tapa olisi myös tehdä "factory", jossa muodostetaan aina kyseiset luokat ja pidetään kirjaa mistä luokista olio on jo olemassa. Näin ollen, kun jokin luokka tarvitsee useampia "modeleita" niin voit heittää kyseiselle luokalle parametrina vain tuon "factoryn" niiden 36 eri olion sijasta. Luokan sisällä vain "rakennat factorylla" luokkasi kaipaamat oliot, jolloin "factory" tarkistaa löytyykö kyseisestä oliosta jo ilmentymää muistista vai luodaanko uusi ilmentymä.
<?php namespace Factory; class DataMapperFactory { private $db; private $cache; public function __construct($db) { $this->db = $db; } public function build($class) { if (!isset($this->cache[$class])) { $this->cache[$class] = new $class($this->db); } return $this->cache[$class]; } }
Koodiesimerkit ovat todella vajavaisia, mutta jospa ne antaisivat jonkinlaisen kuvan miten kyseisiä asioita voisi tehdä.
Hmm.. kiitos. Luulen että olet hieman pidemmällä kuin minä olio-ohjelmoinnissa. Nyt järjestys tällainen:
1.) Oma WordPress Plugin aktivoidaan
- luokka plugin tekee tarvittavat alkuvalmistelut mm. kutsuu yhden kerran yhden metodin sisällä kaikkia muita luokkia (luokkakirjasto-kansio).
Wordpressissä on tärkeää käyttää koukkuja (Hook) oikeassa paikassa. Vaiheessa 2. päästään paremmin käsiksi Luokkahierargiaan, jossa ylimpänä on tietokantayhteys:
- WPDB-olio (yhteys, asetukset, wp-virheilmoitukset)
- Main-olio perii ominaisuudet ja lisää muutaman yleisfunktion (mm. hae kaikki tieto halutusta taulusta)
- Tapahtuma- Työntekijä- Ylläpito- oliot perivät yliluokkien opit ja lisäävät niihin omia erikoisuuksia, jotka kuuluvat nimi-viitekehyksen pariin? Näin ollen kun koodaan.. voin miettiä "Hmm.. tarvitsen käyttäjän etunimen ja sukunimen.. ja mikäköhän luokka mahtaa vastata tätä tehtävää" Aivan Worker-olio, joten luon sen siellä missä olen.
Toki ehkä hassua että yhdessä tiedostossa olen kerran joutunut luomaan 4 eri oliota. Toisaalta olioita on mukava käyttää ja pidän siitä että saan pieniä luokkia. Vaikkakin Ylläpito-olio on liian suuri jo yli 700 riviä. Muut 30-100.
Ehkä on vain järkevää jakaa asioita olioiksi. Esimerkiksi koko ylläpito-osio on yksi iso olio. Sen sijaan kaikki varaamiseen liittyvä löytyy Varaus-oliosta siis yksi php-tiedosto. Ja koska periminen on tehty 2 erässä kannattaa nuo yläluokat pitää mahdollisimman pieninä.
Netbeansin ihanuus on se että kun luon olion ja kirjoitan esim. "Varaus->" niin heti tuon nuolen jälkeen tulee liuta olion ominaisuuksia. Hyvin nimetyt metodit kertovat kaiken oleellisen. Osaa käyttää oliota vaikken muista tarkasti mitä metodi tekee. No.. nyt jatkan MVC-mallin omaksumista. Hyvin sujuu ja taidot parantuneet, vaikkakin HC PHP-koodaus taso jää ikuisesti saavuttamatta.
Olet ymmärtänyt perinnän idean täysin väärin. Jos luokka Työntekijä periytyy luokasta Tietokantayhteys, se tarkoittaa, että jokainen Työntekijä on myös Tietokantayhteys ja että ohjelmassasi on yhtä monta Tietokantayhteyttä kuin Työntekijääkin. Siinä ei ole mitään järkeä.
Sorry, huonosti selitetty. Eli olen nimennyt luokat yksikköinä:
Työntekijä
Tapahtuma
Varaus
Nämä luokat edustavat kaikkia metodeja jotka kuuluvat nimen alle. Esim. Työntekijä-luokka-olio:
- palauta käyttäjän tiedot
- palauta työntekijän tiedot
- lisää uusi työntekijä
- palauta työntekijät taulukko
Tällä logiikalla tiedän aina minkä olion synnyttää kun tarvitsen esim. Tapahtuman varausten määrän. (Varaukset on tässä merkitsevä) siispä synnytän Varaus-olion joka kutsuu luokkansa metodia "hae varausten määrä" luokan metodi palauttaa tämän muuttujassa, jolloin se on mukavasti käytössä koodissa. Jos esim vertaan lukua tai tulostaan sen tai molemmat pariin kertaan.
Tykkään muutenkin palautetta asioita (return)
minäkin pidän asioiden palauttelusta
samip, koska sinulla näyttää olevan aikaa tuollaisiin kommentteihin, niin olisi kiva kuulla millainen kehitysympäristö sinulla on. Aloitin uuden topiicin tästä. (MACBOOK PRO RETINA)
latenleffahylly kirjoitti:
Sorry, huonosti selitetty. Eli olen nimennyt luokat yksikköinä:
Työntekijä
Tapahtuma
Varaus
Näillähän ei ole mitään tekemistä sen kanssa mihin data on tallennettu. wpdb-olion kautta voit käyttää tietokantaa periaatteessa aivan kuten PDO-rajapintaa, joskin tähän kylkeen on kehitetty muutamia apumetodeita helpottamaan koodarin urakkaa. Palauttavat muun muassa valmiita stdClass olioita.
PDO:n vakiometoditkin voivat palauttaa stdClass-olioita, ei siinä ole mitään ihmeellistä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.