2 Stimmen

Sollte ich C#-ähnliche Eigenschaft Handhabung in PHP verwenden?

Hallo SO-Gemeinschaft, ich habe hier gesehen: http://www.mustap.com/phpzone_post_203_setter-and-getter ein Argument für die Verwendung eine Art der Eigenschaftsbehandlung, wie sie in C# üblich ist: Wenn Sie in C# eine Klasse wie diese definieren können:

public class Person 
{
    private string _name;
    public string Name
    {
        get{ return _name; }
        set{ _name = value; }
    }
}

warum ist es dann klug oder nicht, eine ähnliche Eigenschaft in PHP wie diese zu definieren:

public class Person
{
    private var $name;    

    public function Name() 
    {
        if(func_num_args() == 0) {    return $this->name;  } 
        else {$this->name = func_get_arg(0);  }
    }
}

2 Stimmen

Eine Frage: Warum? Welchen Sinn hat das gegenüber der normalen Getter/Setter-Syntax ( getName() y setName($name) ), oder über die magischen Methoden (mit denen Sie $foo->name = 'bar'; echo $foo->name; )?

0 Stimmen

Irwin - Diese Syntax ist nicht das, was C# tut oder wie es aussieht. Schlechte Analogie.

6voto

Ocelot20 Punkte 10090

IMO sieht das in PHP nicht sauber aus. Es ist wie Sie versuchen, die C # Weg in PHP zu klemmen, weil Sie denken, es ist ein nettes Feature von C #.

Ich sehe es so: In PHP machen Sie eine einzelne Funktion weil sie zwei völlig unterschiedliche Dinge tun, was keinen Sinn ergibt. In C# hingegen ist es eine einzige Eigenschaft die als ein einziger Zugangspunkt für ein zu setzendes/abzurufendes Objekt konzipiert ist.

0 Stimmen

Genau mein Gedanke. Denken Sie lange und gründlich nach, bevor Sie versuchen, Funktionen von einer Sprache in eine andere zu portieren. PHP erledigt die Plackerei mit Getter/Settern über seine magischen Methoden. Vielleicht möchten Sie stattdessen einen Blick auf diese werfen.

2 Stimmen

Ja, es verstößt gegen die Alleinverantwortlicher Auftraggeber (für Routinen anstelle von Klassen).

0 Stimmen

Ich glaube in meinem Beitrag, dass diese Methode umgesetzt werden kann, solange man es richtig macht.

4voto

CaffGeek Punkte 21343

Sie verstoßen gegen die Prinzip der einzigen Verantwortung indem eine Funktion sowohl ein Getter als auch ein Setter ist.

In c# ist es nur syntaktischer Zucker, und wird in einen Getter und Setter umgewandelt, genau wie Sie es in PHP schreiben sollten.

In c# kann man das sogar noch weiter vereinfachen, indem man schreibt

public string Name { get; set; }

Und der Compiler generiert ein privates Backing-Feld und Ihre Getter- und Setter-Funktionen für Sie.

0 Stimmen

JQuery (eine hervorragende Software) macht das ständig. x.html(foo) setzt den Wert, x.html() zurück.

0 Stimmen

Es ist ein großartiges Stück Software, aber sie haben sich bewusst dafür entschieden, die SRP zu brechen, und nur durch die strikte Einhaltung ihres Standards kann dies gelingen. Alle/meisten Setter (Methoden, die mit einer Eingabe aufgerufen werden) geben ein jQuery-Objekt zurück, was eine verkettbare Schnittstelle ermöglicht. Und die Getter sind ohne Parameter...manchmal. Dinge wie .attr('name') ist ein Getter, und .attr('name', value) ist ein Setzer. Hier fängt es an, verwirrend zu werden. Da ihre Funktionen je nach den Parametern mehr als eine Sache tun, müssen die Nutzer der Bibliothek sie verstehen. Das könnte verwirrend sein.

2voto

NikiC Punkte 98746

Wenn Sie eine zusätzliche Überprüfung des zu setzenden Wertes durchführen müssen, können Sie entweder getFoo y setFoo Methoden oder noch besser Überladen von Eigenschaften . Letzteres wird dem Benutzer das Gefühl geben, dass er die Eigenschaften selbst bestimmen kann. (Letzteres ist, was Sie in C# tun. Nur, dass es nur eine Methode pro Klasse gibt, nicht viele.)

0 Stimmen

+1, ich würde auch erwähnen, dass die Überladung nur Eigenschaften emuliert, aber nicht ersetzt sie. Es gibt keine echte Unterstützung für Eigenschaften in PHP (noch).

2voto

RobertPitt Punkte 55763

Es ist zum Beispiel klug:

class Settings
{
    private $data = array();

    public function __call($key,$arguments = array())
    {
        return !count($arguments)) ? $this->data[$key] : $this->data[$key] = $arguments[0];
    }
}

Dann tun

$Settings = new Settings();
$Settings->name('hello');
$Settings->foo('bar');

Dies hat nun zu einer unbegrenzt Menge anonymer Funktionen, die zur Verwendung bereit sind, würde dies in der Regel mit 2 Methoden aufgebaut werden, __get y __set Auf diese Weise können Sie eine Trennung für Methoden und Variablen definieren, zum Beispiel wie folgt

class Settings
{
    private $data = array();

    public function __set($key,$val)
    {
        $this->data[$key] = $val;
    }
    public function __get($key)
    {
        return $this->data[$key];
    }
}

Dies würde es Ihnen ermöglichen, Variablen wie folgt zu setzen:

$Settings->foo = 'bar';

Sie können aber noch ein wenig weiter gehen und ein variables Registrierungssystem erstellen:

Sie können also im Grunde die obige Klasse von Settings a VariableStorage und gehen Sie wie folgt vor:

class User extends VariableStorage{}
class Profile extends VariableStorage{}

Und so verwenden:

$Profile = new Profile('Robert','Pitt',USER_PRIV_ADMIN);
$Profile->id = 56;
$Profile->userdata = $Database->GetUserData($Profile); //Reads $Profile->id

So müssen Sie die Methoden nur einmal definieren, und solange Sie Ihre Vererbungsstruktur nach einem guten Design aufbauen, kann sie sehr gut funktionieren.

0 Stimmen

Ok, Sie haben eine Implementierung einer "Eigenschaftstasche" (fügen Sie Eigenschaften mit jede Name). Ein nützliches Konzept. Ich denke, es ist erwähnenswert, dass dies erweitert werden könnte, um eine spezifisch Satz von Eigenschaftsnamen, indem man eine Unterklasse mit einem privaten statischen Feld hat, das ein Array von gültigen Eigenschaftsnamen ist, und prüft, ob Name in diesem Array ist - um jeden anderen Eigenschaftsnamen abzulehnen.

0voto

Jeff Tillwick Punkte 41

Ich persönlich verwende ein ähnliches Muster in meinem PHP. Ich denke, es ist sauber und ziemlich nützlich.

private $name;
public function name($name = null)
{
    if ($name === null) return $this->name;
    $this->name = $name;
}

Sie können dies sogar tun, um eine Art von Sicherheit zu erzwingen:

private $name;
public function name(string $name = null)
{
    if ($name === null) return $this->name;
    $this->name = $name;
}

Sie können auch das Setzen/Holen einer Referenz anstelle einer Kopie erzwingen:

private $name;
public function &name(string &$name = null)
{
    if ($name === null) return $this->name;
    $this->name = &$name;
}

Dies ist ein vollwertiges PHP und ahmt C# recht gut nach.

Auch die Prinzip der einzigen Verantwortung Staaten:

Das Prinzip der einzigen Verantwortung ist ein Grundsatz der Computerprogrammierung, der besagt, dass jedes Modul oder jede Klasse die Verantwortung für einen einzigen Teil der von der Software bereitgestellten Funktionalität haben sollte, und dass diese Verantwortung vollständig von der Klasse gekapselt sein sollte.

Dies verstößt also nicht gegen das Prinzip der einzigen Verantwortung, da es sich lediglich um eine Klassenmethode handelt, die dazu dient, eine Klassenvariable zu erhalten/zu setzen.

Der einzige Nachteil dabei ist, dass Sie in der Instanz Ihrer Klasse Funktionen aufrufen müssen, um Mitgliedsvariablen zu erhalten/zu setzen, anstatt echte Eigenschaften. Sie könnten dieses Entwurfsmuster mit PHPs __get und __set mischen, aber das würde nur mehr Overhead bedeuten.

0 Stimmen

Kleines Manko: die verwirrende Bedienung $name als Parametername. Ein besserer Name ist $value .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X