php.de

Zurück   php.de > Webentwicklung > PHP Einsteiger > PHP Tipps 2009

 
 
LinkBack Themen-Optionen Thema bewerten
Alt 09.08.2009, 11:54  
Neuer Benutzer
 
Registriert seit: 25.08.2008
Beiträge: 19
PHP-Kenntnisse:
Anfänger
grizu befindet sich auf einem aufstrebenden Ast
Standard Decorator-Pattern

Hallo!

Ich versuche mich gerade am Decorator-Pattern, hab mir als kleine Aufgabe gestellt, das Java-IO-System etwas nachzubasteln, natürlich minimalst.

Ich hab jetzt bisher drei Klassen: StringReader, FileReader und XMLReader. XMLReader ist der eigentliche Decorator.

Ich wollte eigentlich nur fragen, ob ihr da etwas drüberschauen könntet? Was könnte man besser machen, und wie könnte man das ganze noch erweitern? Es wäre ja echt cool, wenn da ein kleines verwendbares package draus wird.
Ich find das Pattern grad irrsinnig geil

Ich poste mal meine Klassen.

IReader:
PHP-Code:
interface IReader
{
    public function 
readLine ();
    public function 
readChar ();
    public function 
rewind ();
    public function 
read ();

Reader:
PHP-Code:
abstract class Reader implements IReader
{
    
    protected 
$_lineCounter 0;
    protected 
$_charCounter 0;
    
    
    public function 
read ()
    {
    }
    
    public function 
readLine ()
    {
    }
    
    public function 
readChar ()
    {
    }
    
    public function 
rewind ()
    {
        
$this->_lineCounter 0;
        
$this->_charCounter 0;
    }

StringReader:
PHP-Code:
class StringReader extends Reader
{
    
    private 
$_string;

    
    public function 
__construct ($string)
    {
        
$this->_string $string;
    }

    public function 
read ()
    {
        return 
$this->_string;
    }
    
    public function 
readLine ()
    {
        
$lines split ("\n"$this->_string);
        
$line $lines[$this->_lineCounter];
        
        
$this->_lineCounter ++;
        
        return 
$line;
    }
    
    public function 
readChar ()
    {
        
$char substr($this->_string$this->_charCounter1);
        
        
$this->_charCounter ++;
        
        return 
$char;
    }

FileReader:
PHP-Code:
class FileReader extends Reader
{
    
    private 
$_file;
    private 
$_content;

    
    public function 
__construct ($file)
    {
        
$this->_file $file;
    }

    public function 
read ()
    {
        return (
$this->_content file_get_contents ($this->_file));
    }
    
    public function 
readLine ()
    {
        if (
is_null($this->_content))
            
$this->read ();
        
        
$lines split ("\n"$this->_content);
        
$line $lines[$this->_lineCounter];
        
        
$this->_lineCounter ++;
        
        return 
$line;
    }
    
    public function 
readChar ()
    {
        if (
is_null($this->_content))
            
$this->read ();
            
        
$char substr($this->_content$this->_charCounter1);
        
        
$this->_charCounter ++;
        
        return 
$char;
    }

XMLReader:
PHP-Code:
class XMLReader extends Reader
{
    
    private 
$_reader;

    
    public function 
__construct (Reader $reader)
    {
        
$this->_reader $reader;
    }

    public function 
read ()
    {
        return 
$this->_reader->read();
    }
    
    public function 
readLine ()
    {
        return 
$this->_reader->readLine();
    }
    
    public function 
readChar ()
    {
        return 
$this->_reader->readChar();
    }
    
    public function 
rewind ()
    {
        
$this->_reader->rewind ();
    }
    
    public function 
readXML ()
    {
        return new 
SimpleXMLElement($this->_reader->read());
    }

Also ich glaub, das Prinzip hab ich gecheckt. Die XML-Klasse gehört natürlich noch ausgebaut. Ist das Interface und die abstrakte Klasse sinnvoll definiert? Welche Klassen könnte man noch einbauen (ArrayReader?) ?

Danke!

lg
grizu
grizu ist offline  
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 09.08.2009, 14:28  
Benutzer
 
Registriert seit: 07.08.2009
Beiträge: 31
PHP-Kenntnisse:
Fortgeschritten
nikic befindet sich auf einem aufstrebenden Ast
Standard

Hm, ich hab nur mal ne Frage zur Funktionsweise (nutze Java nicht):

Wenn ich jetzt einen Text habe:
"Hallo Welt
Moin moin
Ende"
Und ich sage jetzt:
PHP-Code:
$string = new StringRead("Hallo Welt
Moin moin
Ende"
);
$string->ReadLine();
$string->ReadChar(); 
Was ist die gewünschte Ausgabe?
So wie sie jetzt ist, also:
"Hallo WeltH"
oder soll sie eher
"Hallo Welt
"
oder gar
"Hallo WeltM"
sein?
nikic ist offline  
Alt 09.08.2009, 20:23  
Neuer Benutzer
 
Registriert seit: 25.08.2008
Beiträge: 19
PHP-Kenntnisse:
Anfänger
grizu befindet sich auf einem aufstrebenden Ast
Standard

Da hast natürlich recht, da stimmt was noch nicht ganz Sollte natürlich "Hallo Welt M" rauskommen.
Exceptions wären auch noch nett, der XMLReader kann auch noch nix, zu tun ist noch genug...
Die Klassen können ja generell nicht viel, mir gings einfach um das Pattern.
grizu ist offline  
Alt 09.08.2009, 21:36  
yab
Erfahrener Benutzer
 
Registriert seit: 05.04.2009
Beiträge: 291
PHP-Kenntnisse:
Anfänger
yab befindet sich auf einem aufstrebenden Ast
Standard

Mit dem Decorator-Pattern ist es möglich, einem Objekt zur Laufzeit dynamisch Funktionalität hinzuzufügen und es setzt auch nicht auf Vererbung. Also bist du mit deiner Implementierung schonmal am Thema vorbei

Unabhängig vom Pattern ist mir an deinem Beispiel aufgefallen, dass du das Interface in deiner abstrakten Klasse bereits mittels leerer Methoden vollständig implementierst. Die Vorzüge, dass der PHP-Parser bei vergessenen Interface-Methoden in den abgeleiteten Klassen "meckert" ist somit auch dahin.
yab ist offline  
Alt 10.08.2009, 13:11  
Neuer Benutzer
 
Registriert seit: 25.08.2008
Beiträge: 19
PHP-Kenntnisse:
Anfänger
grizu befindet sich auf einem aufstrebenden Ast
Standard

Hm...

Am Pattern vorbei? Aber der XMLReader macht ja genau das: er erweitert den Stringreader btw. Filereader um die Funktionalität, aus einem String ein XML-Objekt zurückzugeben. Die Vererbung von Reader soll ja nur sicherstellen, dass jeder Reader, egal ob XML, String, File, Array, etc. die Methoden besitzt. Wärs sinnvoll, für den Decorator eine eigene Superklasse bzw. Interface zu machen?

Das mit dem Interface und der abstrakten Klasse, stimmt. Also einfach nur das Interface bzw. eine rein abstrakte Klasse verwenden?
grizu ist offline  
Alt 11.08.2009, 10:28  
Neuer Benutzer
 
Registriert seit: 25.08.2008
Beiträge: 19
PHP-Kenntnisse:
Anfänger
grizu befindet sich auf einem aufstrebenden Ast
Standard

Jetzt hab ich noch eine konkrete Frage zum Thema Interfaces und abstrakte Klassen, passt auch zu dem Beispiel.

Warum kann ich in einer abstrakten Klasse, die ein Interface implementiert, die Methoden aus dem Interface nicht als abstrakt deklarieren? Das würde doch Sinn machen: Ich hab ein Interface, das die Schnittstelle vorgibt. In meiner abstrakten Klasse, die eine Superklasse für mehrere konkrete Klassen sein soll, möchte ich zwar schon einige Implementierungen vornehmen (Konstruktor, einige Variablen), aber die Interface-Methoden trotzdem abstrakt lassen.

-> Fatal Error: Can't inherit abstract function ...

Warum geht das nicht?
grizu ist offline  
Alt 11.08.2009, 11:26  
Erfahrener Benutzer
 
Registriert seit: 28.05.2008
Beiträge: 2.094
PHP-Kenntnisse:
Fortgeschritten
rudygotya ist einfach richtig nettrudygotya ist einfach richtig nettrudygotya ist einfach richtig nettrudygotya ist einfach richtig nettrudygotya ist einfach richtig nett
Standard

Einfaches Beispiel:
Du hast 3 verschiedene Benutzertypen.
Angenommen, du bist dir nicht ganz sicher, ob du einer Klasse user ein Interface oder einige Methoden mitgeben möchtest.

Falls du für bereits schon gelöste gemeinsame Probleme gemeinsam verwendete Methoden entwickelt hast, die du für die 3 Klassen einsetzen möchtest, dann gibst du diese in der abstrakten Klasse mit und vererbst von dieser.
Habe ich dann noch ähnliche - aber dennoch unterschiedliche - Schnittstellen, gebe ich leere abstracte Methoden mit. Da diese sich wiederum in den Kindklassen unterscheiden werden.

Im Endeffekt wird damit deine abstrakte Klasse zum erweiterten Interface. Daher kannst du in einem "erweiterten Interface" kein Interface implementieren.
__________________
++++ Wieder einer ins Netz gegangen: Phishers Fritz zufrieden ++++
Blog
rudygotya ist gerade online  
Alt 11.08.2009, 12:13  
Neuer Benutzer
 
Registriert seit: 25.08.2008
Beiträge: 19
PHP-Kenntnisse:
Anfänger
grizu befindet sich auf einem aufstrebenden Ast
Standard

Hi, danke für deine Antwort.

Zitat:
Im Endeffekt wird damit deine abstrakte Klasse zum erweiterten Interface. Daher kannst du in einem "erweiterten Interface" kein Interface implementieren.
Also erweitertes Interface einfach in dem Sinn, dass bestimmte Methoden bereits implementiert werden können? Wie soll ich das sagen - ein Mittelding zwischen Interface und Klasse?


- Aber es ergibt sich irgendwie schon aus dem Namen: Ich kann keine Interface-Methode abstrakt implementieren - abstrakt implementieren geht halt einfach nicht.
Ich wollte einfach erreichen, dass meine Superklasse bereits sich selbst und das Interface vorgibt. Aber wenn ich will, dass meine erbenden Klassen das Interface implementieren, muss ich das in den Kindklassen selbst machen.

Ich hoffe, das hab ich jetzt richtig verstanden
grizu ist offline  
Alt 11.08.2009, 12:32  
Erfahrener Benutzer
 
Registriert seit: 28.05.2008
Beiträge: 2.094
PHP-Kenntnisse:
Fortgeschritten
rudygotya ist einfach richtig nettrudygotya ist einfach richtig nettrudygotya ist einfach richtig nettrudygotya ist einfach richtig nettrudygotya ist einfach richtig nett
Standard

Es bleibt ja eine Klasse. Der wichtigste Grundgedanke dahinter ist der, dass du von einer abstrakten Klasse kein Objekt erzeugen kannst.
Um auf das vorherige Beispiel zurückzugreifen:
Sie enthält eben nur gemeinsame Methoden, würde aber zur Laufzeit kein vollwertiges User-Objekt darstellen.

Ich würde entweder ein interface schreiben ODER eine abstrakte Klasse definieren, aber nicht beides mischen. Weiß auch nicht, ob das geht, macht auch keinen Sinn.

Zitat:
Ich wollte einfach erreichen, dass meine Superklasse bereits sich selbst und das Interface vorgibt.
Genau das macht eine abstrakte Klasse mit abstrakten Methoden.
__________________
++++ Wieder einer ins Netz gegangen: Phishers Fritz zufrieden ++++
Blog
rudygotya ist gerade online  
Alt 11.08.2009, 13:24  
Neuer Benutzer
 
Registriert seit: 25.08.2008
Beiträge: 19
PHP-Kenntnisse:
Anfänger
grizu befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von rudygotya Beitrag anzeigen

Ich würde entweder ein interface schreiben ODER eine abstrakte Klasse definieren, aber nicht beides mischen. Weiß auch nicht, ob das geht, macht auch keinen Sinn.
Stimmt ja, beides macht wirklich keinen Sinn. Das hab ich nämlich vorgehabt...
Und in einem anderen Fall, zb. implementiert meine User-Klasse das Interface "Serializable", wäre es ja kein Problem, diese Methode bereits in der abstrakten Klasse zu implementieren. Aber eben, eine abstrakte Klasse kann eine Interface-Methode nicht als abstrakt deklarieren und so quasi das Interface weitervererben, sie muss die Methode implementieren.
grizu ist offline  
 


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
decorator pattern, php decorator pattern, decorator pattern php, php pattern decorator, decorator php, decorator-pattern, php can\'t inherit abstract function, xmlreader decorator, java io reader muster pattern, decorator pattern reader, decorator patterns, php decorator, java decorator pattern, decorator pattern beispiel, beispiel decorator pattern php, parser php decorator, decoration pattern php, decorator pattern german, decorator pattern java deutsch, abstract decorator pattern php

Alle Zeitangaben in WEZ +2. Es ist jetzt 19:44 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum