2014-12-09 16 views
6

Ich habe Zweifel über den Entwurf eines Systems zur Verwaltung von Artikeln eines Geschäfts mit OOP. Ich habe die abstrakte Klasse Produkt erstellt, die die Attribute $ name und $ price haben wird. Später habe ich die Klasse Smartphone geschaffen, die das Produkt erweitert. Smartphone hat die Attribute $ brand und $ os. Später habe ich die Klasse Computer erstellt, die das Produkt erweitert und die Attribute $ cpuFrequency und $ ram hat. Nun, wenn ich zum Beispiel ein Objekt erstellen möchte, das dem Nexus 5 entspricht, was muss ich tun? Betrachten wir zum Beispiel, dass dieses ObjektPHP OOP-Klassen von Speichermuster

$name = "Nexus 5" 
$price = "250" 
$brand = "LG" 
$os="Android" 
$cpuFrequency "2.0" 
$ram = "2". 

Hier ist ein Beispiel von Klassen haben wird.

abstract class Product { 
    private $name; 
    private $price; 
    //more methods 
} 

class Smartphone extends Product{ 
    private $brand; 
    private $os;  
} 

class Computer extends Product { 
    private $cpuFrequency; 
    private $ram; 
} 

Auch in Betracht gezogen, dass es Computer ohne $ os und Smartphone ohne $ RAM geben kann. nur ein Beispiel: D

P.S. Ich weiß, dass Smartphone ein Computer ist. Ich habe ein schlechtes Beispiel gemacht. Bitte denken Sie an Telefon und Computer. Telefon hat $ Nummer und $ Operator. Jetzt möchte ich ein Smartphone erstellen, das gleichzeitig Telefon und Computer ist.

Vielen Dank für alle und sorry nochmal für mein Englisch

+3

Sie gehen mit zig verschiedenen Klassen am Ende, die sich völlig unbrauchbar/wartbaren ist. ein Smartphone ** IST ** ein Computer, der einfach nur telefonieren kann. genau wie ein Laptop ist ein Computer, der zufällig tragbar ist und seinen Bildschirm/Festplatte eingebaut hat. –

+0

Sie könnten das Produkt und seine Spezifikation aufteilen. Dadurch können Sie für jeden neuen Typ keine Unterklasse erstellen. – Rangad

+0

Sie sollten 'Produkt' eine Schnittstelle machen, dann implementieren Sie es. ein 'Smartphone' sollte eine' Phone'-Klasse erweitern und eine 'Computer'-Schnittstelle implementieren –

Antwort

1

Sie könnten versuchen, eine ProductProperties-Klasse wie folgt:

class ProductProperties 
{ 
    private properties = array(); 

    public function getProperties() 
    { 
     return this->properties; 
    } 

    public function addProperty($id, $value) 
    { 
     this->properties[$id] = $value; 
    } 

    public function getProperty($id) 
    { 
     return this->properties[$id]; 
    } 
} 

abstract class Product 
{ 
    private $properties; 
    //more methods 

    public function __construct(ProductProperties $properties) 
    { 
     $this->properties = $properties; 
    } 
} 

Sie könnten ein Objekt der Klasse ProductProperties einem der Ihr Produkt und lassen Sie es alle Eigenschaften bezogene Aufgaben bearbeiten übergeben.Dies würde zu einem flexibleren Design führen, so dass Sie keine Unterklasse benötigen, nur weil ein Produkt andere Eigenschaften hat. Denken Sie daran, dass das Unterklassifizieren nur dazu dient, Verhalten zu ändern oder hinzuzufügen.

+1

Ich fing an, eine Antwort zu schreiben, und dann tauchte diese auf, also musste ich meine editieren und hier eine Anerkennung geben: D - das ist in der Praxis der beste Weg, dies zu tun, besonders wenn man die ProductProperties-> addProperty zuordnet eine Datenbank mit einem ORM – Jonathan

+0

@ Jonathan das ist genau die Art, wie ich es in vielen meiner Projekte verwendet habe – Edgar

+0

Nur letzte Sache. Warum muss ich eine Klasse erstellen, die nur ein Array als Attribut hat? Warum kann ich dieses Attribut (das Array) nicht direkt in die Klasse Product einfügen? Aber danke für alle, Sie sind sehr erschöpfend. – user4304554

0

Wie schon andere gesagt haben, können zu viele Klassen machen verwirrend.

Die Idee ist, eine Klasse zu erstellen, die viele verschiedene Szenarien abdecken kann, ohne zu viel Arbeit.

Zum Beispiel könnten Sie eine Klasse Pet haben. Ein Hund ist ein Haustier, und so kann eine Schlange ... Dies bedeutet nicht, dass Sie eine FourLegged oder Nolegs Klasse machen sollten.

Ähnlich wie Ihre Produkte, haben Sie möglicherweise eine product Klasse, die Dinge für alle Produkte gemeinsam hält. Vielleicht möchten Sie sogar eine Unterklasse namens electronics haben, die alles von Telefonen bis zu Computern abdecken kann.

Sie können ein productType Attribut, das sagt, welche Art von Elektronik es ist (z. B. Telefon), aber letztlich wird es nicht zu viel Variation zwischen einzelnen Elektronik: TV, Smartphones und Computer haben beide Bildschirmspezifikationen, ein Smartphone und Computer haben RAM, CPUs usw.

+0

Beim Lesen der Frage würde ich annehmen, dass der Op weiß, wie man Objekte erzeugt. Nach meinem Verständnis geht es bei dieser Frage um das Design seiner Anwendung. – Rangad

+0

Danke. Ich habe Rubin im Gehirn. Ich habe die Frage noch einmal gelesen und Sie haben Recht. Ich werde meine Antwort bearbeiten. – Anthony

2

Normalerweise sollten Sie Konstruktoren zu Ihren Klassen in irgendeiner Weise schreiben, dass "Kind" -Klasse die Superklasse initialisiert, um alles konsistent zu halten.

abstract class Product { 
    private $name; 
    private $price; 
    //more methods 

    public __construct($name, $price){ 
     $this->name = $name; 
     $this->price =$price; 
    } 
} 

class Smartphone extends Product{ 
    private $brand; 
    private $os; 
    // default value to $os: like that, we can create a Smartphone whitout an os 
    public __construct($name, $price, $brand, $os = null){ 
     parent::__construct($name, $price); 
     $this->brand = $brand; 
     $this->os =$os; 
    } 
} 

class Computer extends Product { 
    private $cpuFrequency; 
    private $ram; 
    // default value to $ram: with this, we can create a Computer whiout ram 
    public __construct($name, $price, $frequency, $ram = null){ 
     parent::__construct($name, $price); 
     $this->frequency = $frequency; 
     $this->ram =$ram; 
    } 

} 

Dann einen Computer erstellen, können Sie tun, für

$computer = new Computer('notBuiltToWindows', 560 , 2.0, 4); 

oder das Nexus in Ihrem Beispiel zu erstellen:

$nexus = new Smartphone($name, $price, $frequency, $ram); 

und ein erstellen Smartphone ohne einen Widder

$nexus = new Smartphone($name, $price, $frequency); 
0

Die Art, wie wir es bei der Arbeit zu tun ist eine Kombination aus den meisten der oben genannten Antworten:

1) Sie haben eine Produktklasse/Objekt - das ist die allgemeinen Dinge enthält, die jedes Produkt hat - einen Namen, ein Beschreibung, einige Bilder usw.

2) Sie haben eine Unterklasse, die die Produktattribute (eine Produktattributklasse) enthält - z Größe, Gewicht (nicht alle Produkte sind physisch, also nicht alle haben Größen oder Gewichte), Preis, Anzahl_von_Ram_Slots, CupFrequency.

Die Attribute können benutzerdefiniert werden, indem ein ORM verwendet wird, das die Attribute der Datenbank zuordnet. Dies bringt das Beste aus beiden Welten, da php nicht in der Lage ist, mehrfache Vererbung zu machen - technisch gesehen ist ein Smartphone sowohl ein Computer als auch ein Telefon, aber indem es den obigen Weg macht, spielt es keine Rolle, da jeder ein Produkt ist und eine Reihe von benutzerdefinierten Attributen.

Im Wesentlichen ist dies die gleiche Antwort wie @ Edgar Implementierung

0

Auf der obersten Ebene wir Konzepte zu erstellen, nicht greifbare Dinge. Dinge, die in der Theorie sind und umgesetzt werden müssen, um greifbar zu sein.

// make product an interface, or in other words a concept. its not tangible, 
// but instead its just a concept thus making it an interface 
interface Product { 
    public function getName(); 
    public function getPrice(); 
    public function getBrand(); 
} 

// A computer is also a concept, thats implemented by many devices like a laptop, 
// SMARTPHONE, desktop, calculator, etc... 
interface Computer { 
    public function getRam(); 
    public function getFrequency(); 
    public function getOS(); 
} 

Die Telefon-Logik:

// We can implement the concept of a Product here 
// the phone is also a concept, implemented by home phones, 
// telephones and mobile phones so we make it abstract 
abstract class Phone implements Product { 
    private $name;   
    private $price; 
    private $brand; 

    function __construct ($name, $price, $brand) { 
     $this->name = $name; 
     $this->price = $price; 
     $this->brand = $brand; 
    } 

    public function getName() { 
     return $this->name; 
    } 

    public function getPrice() { 
     return $this->price; 
    } 

    public function getBrand() { 
     return $this->brand; 
    } 
} 

Das Smartphone Logik:

// Smartphone is another concept implemented by many devices like a Nexus 5, 
// what makes this concept different from a Phone is that it doubles as a computer. 
// so we extend the concept of a phone by implement the concept of a computer 
// making the Phone 'smart' 
abstract class Smartphone extends Phone implements Computer { 
    private $os; 
    private $frequency; 
    private $ram; 

    public function __construct ($name, $price, $brand, $os, $frequency, $ram) { 
      parent::__construct($name, $price, $brand); 

      $this->os  = $os; 
      $this->frequency = $frequency; 
      $this->ram  = $ram; 
    } 

    public function getRam() { 
     return $this->ram; 
    } 
    public function getFrequency() { 
     return $this->frequency; 
    } 
    public function getOS() { 
     return $this->os; 
    } 
} 

Endlich haben wir ein fertiges Konzept, etwas machbar/greifbar. Das Nexus-Produkt.

// A Nexus implements the concept of a Smartphone. 
// so now the Nexus is a Smartphone, Computer, Phone and a Product 
class Nexus extends Smartphone { 
     public function __construct ($version) { 
      parent::__construct('Nexus '.$version, 250, 'LG', 'Android', '2.0', 2); 
     } 
} 

Verwendung:

// all we do is specify the version of nexus we are using 
    $nexus5 = new Nexus(5);