Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Implementować czy rozszerzać?
Forum PHP.pl > Forum > PHP > Object-oriented programming
starach
Czy są jakieś utarte reguły dotyczące wyboru jednej z tych dwóch metod ?
Mam klasę ( w sumie nie jedną ) która wymaga Iterator'a. Pytanie tylko czy mam zaimplementować interfejs iteratora czy rozszerzyć i nadpisać kilka metod. Nie wiem którą z opcji wybrać. Szukam jakiejś reguły którą mógłbym się kierować przy wyborze.
NuLL
Implmentacja bo szybsza - dziedziczenie jest strasznie powolne :]
mike
Dziedziczenie stosuj tam gdzie masz zamiar skorzystać z polimorfizmu.
starach
To lubię w tym forum. Konkretne i szybkie odpowiedzi smile.gif

To jeszcze prosiłbym o sprawdzenie moich wypocin.
  1. <?php
  2. class Class_Method_Collection implements Iterator
  3. {
  4.    /**
  5.      * For:
  6.      * $this->_items[0]['name'] = '<method name>'; | myMethod
  7.      * $this->_items[0]['return'] = '<variable type>'; | integer / string / etc.
  8.      * $this->_items[0]['params'][0]['name'] = '<param name>'; | my_variable
  9.      * $this->_items[0]['params'][0]['type'] = '<param type>'; | integer / string / etc.
  10.      * or
  11.      * $this->_items[0] = Class_Methods_Method
  12.      * @var array
  13.      */
  14.    protected $_items = array();
  15.    /**
  16.      * Iterator index
  17.      * @var integer
  18.      */
  19.    protected $_key = 0;
  20.    /**
  21.      * Identifiers stored in array
  22.      * @var array
  23.      */
  24.    protected $_keys;
  25.    /**
  26.      * Converts data from array to Class_Methods_Method object
  27.      * For:
  28.      * $method['name'] = '<method name>'; | myMethod
  29.      * $method['return'] = '<variable type>'; | integer / string / etc.
  30.      * $method['params'][0]['name'] = '<param name>'; | my_variable
  31.      * $method['params'][0]['type'] = '<param type>'; | integer / string / etc.
  32.      * @param array $method
  33.      */
  34.    public function array2method($method)
  35.    {
  36.        $method['return'] = isset($method['return']) ? $method['return'] 'void';
  37.        
  38.        $ob = InstanceGet('library.class.method', '', InstanceRETURN_INSTANCE);
  39.        $ob->setName($method['name']);
  40.        $ob->setReturn($method['return']);
  41.        foreach($method['params'] as $param)
  42.        {
  43.            $ob->setParam($param['name'], $param['type']);
  44.        }
  45.        return $ob;
  46.    }
  47.    /**
  48.      * Loads methods collection in array format as class items for further operations
  49.      * $this->_items[0]['name'] = '<method name>'; | myMethod
  50.      * $this->_items[0]['return'] = '<variable type>'; | integer / string / etc.
  51.      * $this->_items[0]['params'][0]['name'] = '<param name>'; | my_variable
  52.      * $this->_items[0]['params'][0]['type'] = '<param type>'; | integer / string / etc.
  53.      * or
  54.      * $this->_items[0] = Class_Methods_Method
  55.      * @param array $methods
  56.      */
  57.    public function load($methods)
  58.    {
  59.        if($this->validate($methods)) throw new Exception('Incorrect $methods format.');
  60.        $this->_keys = array_keys($methods);
  61.        $this->_items = $methods;
  62.    }
  63.    /**
  64.      * Compares format of $methods array with required by load() method
  65.      * @param array $methods
  66.      */
  67.    public function validate($methods)
  68.    {
  69.        $out = true;
  70.        foreach($methods as $method)
  71.        {
  72.            if(!isset($method['name']))
  73.            {
  74.                $out = false;    break;
  75.            } else
  76.            if(isset($method['params']))
  77.            {
  78.                foreach($method['params'] as $param)
  79.                {
  80.                    if(!isset($param['name']) || !isset($param['type']))
  81.                    {
  82.                        $out = false;    break;
  83.                    }
  84.                }
  85.            }
  86.            if(!$out) break;
  87.        }
  88.        return $out;
  89.    }
  90.    // ----------------- //
  91.    // SETTERS & GETTERS //
  92.    // ----------------- //
  93.    /**
  94.      * Returns item
  95.      * @param integer $key
  96.      * @return misc
  97.      */
  98.    public function getItem($key)
  99.    {
  100.        return isset($this->_keys[$key]) && isset($this->_items[$this->_keys[$key]]) ? $this->_items[$this->_keys[$key]] false;
  101.    }
  102.    /**
  103.      * Sets item
  104.      * @param integer $key
  105.      * @param misc $item
  106.      */
  107.    public function setItem($key, $item)
  108.    {
  109.        if(isset($this->_items[$key]))
  110.        {
  111.            $this->_items[$key] = $item;
  112.        }
  113.        else
  114.        {
  115.            $this->_keys[] = $key;
  116.            $this->_items[$key] = $item;
  117.        }
  118.    }
  119.    // ---------------- //
  120.    // ITERATOR METHODS //
  121.    // ---------------- //
  122.    /**
  123.      * Returns current item
  124.      * @return misc
  125.      */
  126.    public function current()
  127.    {
  128.        return $this->valid() ? $this->array2method($this->_items[$this->_keys[$this->_key]]) false;
  129.    }
  130.    /**
  131.      * Return key of current item or boolean false if item does not exists
  132.      */
  133.    public function key()
  134.    {
  135.        return $this->valid() ? $this->_keys[$this->_key] false;
  136.    }
  137.    /**
  138.      * Moves forward to next item
  139.      */
  140.    public function next()
  141.    {
  142.        $this->_key += 1;
  143.    }
  144.    /**
  145.      * Checks does current item exists
  146.      * @return boolean
  147.      */
  148.    public function valid()
  149.    {
  150.        return (isset($this->_keys[$this->_key]) && isset($this->_items[$this->_keys[$this->_key]]));
  151.    }
  152.    /**
  153.      * Rewinds Iterator to the first element
  154.      */
  155.    public function rewind()
  156.    {
  157.        $this->_key = 0;
  158.    }
  159. }
  160. ?>
Zastanawiam się czy nie lepiej wydzielić część iteracyjną do klasy abstrakcyjnej z abstrakcyjną metodą current(), bo będę chciał ten mechanizm zastosować w około 20 klasach.
Sedziwoj
Dlaczego masz:
  1. <?php
  2. /*
  3.     * $this->_items[0]['name'] = '<method name>'; | myMethod
  4.     * $this->_items[0]['return'] = '<variable type>'; | integer / string / etc.
  5.     * $this->_items[0]['params'][0]['name'] = '<param name>'; | my_variable
  6.     * $this->_items[0]['params'][0]['type'] = '<param type>'; | integer / string / etc.
  7.     */
  8. ?>

Przecież wygodniej mieć obiekt. Do tego iterator powinien przechowywać tylko jeden typ elementów. Bo inaczej nie wiadomo co się dzieje, że PHP umożliwia różne dziwne rzeczy, nie znaczy że trzeba z tego korzystać.
starach
Bo to jest kolekcja a pojedynczy element zwracam już jako obiekt.

Jak w takim razie powinno to wyglądać poprawnie ?
jarek_bolo
OT: Czy Ty celowo pomijasz dwukropek w Ternary Operatorze ? Czy może robisz tak ze względu na kolorowanie składni na forum, albo bez tego dwukropka też działa?
Np. tutaj:
  1. <?php
  2. /**
  3.     * Return key of current item or boolean false if item does not exists
  4.     */
  5.   public function key()
  6.   {
  7.       return $this->valid() ? $this->_keys[$this->_key] false;
  8.   }
  9. ?>
Crozin
@jarek_bolo: BBCode forum coś się posypało i usuwa dwukropki.
mike
~jarek_bolo. ~Crozin a nie wiem czy wiecie ale w PHP5.3 będzie skrócona wersja tego operatora:
  1. <?php
  2.  
  3. (warunek logiczny) ? instrukcje_na_true;
  4.  
  5. ?>
Crozin
@mike: przyznam się, że myślałem, że już 5.2.3 to wprowadzili smile.gif
eai
@mike: a jeżeli warunek logiczny nie będzie spełniony to jaką wartość nam zwróci? NULL?
dr_bonzo
@NuLL:
Cytat
Implmentacja bo szybsza - dziedziczenie jest strasznie powolne :]

Eeee? Mozesz to wyjasnic?

@mike
Cytat
Dziedziczenie stosuj tam gdzie masz zamiar skorzystać z polimorfizmu.

Eh? a z interfejsem to nie da sie wykonac polimorfizmu?

java:
Kod
interface ICostam {}
class CostamImpl_1 implements ICostam{}
class CostamImpl_2 implements ICostam{}
...
ICostam cos = new CostamImpl_1();
cos = CostamImpl_2();



smile.gif
mike
Cytat(dr_bonzo @ 22.10.2008, 13:20:05 ) *
Eh? a z interfejsem to nie da sie wykonac polimorfizmu?
Zabiłeś mnie.
Nie sądziłem, że Ci to napisze ale ... poczytaj sobie o polimorfiźmie to pogadamy tongue.gif
To co pokazałeś to nie do końca jest polimorfizm.
dr_bonzo
@mike: dalej nie czaje czemu niby polimorfizm [w programowaniu obiektowym] da sie zrobic tylko z uzyciem dziedziczenia.

moj kod powinien raczej wygladac:

Kod
interface ICostam { public function do(); }
class CostamImpl_1 implements ICostam{ ...do()}
class CostamImpl_2 implements ICostam{..do()}
...
ICostam cos = new CostamImpl_1();
cos.do();

cos = CostamImpl_2();
cos.do();


Bo interfejsy to wlasciwie puste klasy abstrakcyjne i pozwalajace na wykonanie wielodziedziczenia (extends + implements) == mamy dziedziczenie, wiec w czym problem?
markac
Polimorfizm możemy osiągnąć poprzez dziedzicznie, a także przez implementację interfejsu.
chlebik
Ja tylko umieszcze cytat. Reszte flame'a z checia poczytam smile.gif

Cytat
Polimorfizm jest trzecim podstawowym skladnikiem jezyka programowania zorientowanego obiektowo - zaraz po abstakcji danych i dziedziczeniu.

Dostarcza on kolejną metodę separacji interfejsu od implementacji, oddzielania co od jak.


Bruce Eckel, Thinking in Java ed. 4, s. 241.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.