Frage

lesen Heute habe ich ein Buch und der Autor schrieb, dass in einem gut gestalteten Klasse die einzige Möglichkeit, den Zugriff auf Attribute ist durch eine dieser Klasse Methoden. Ist es ein weithin akzeptierter Gedanke? Warum ist es so wichtig, die Attribute zu verkapseln? Was könnte die Folgen nicht, es zu tun? Ich habe irgendwo gelesen, dass dies früher verbessert die Sicherheit oder so ähnlich. Jedes Beispiel in PHP oder Java wäre sehr hilfreich.

War es hilfreich?

Lösung

Ist es ein weithin akzeptierter Gedanke?

In der objektorientierten Welt, ja.

Warum ist es so wichtig, die Attribute zu verkapseln? Was sind die Folgen nicht zu tun, könnte es sein?

Objekte sollen zusammenhängende Einheiten sein, Daten und Verhalten enthalten, dass andere Objekte in einer kontrollierten Art und Weise über eine öffentliche Schnittstelle zugreifen können. Wenn eine Klasse seine Daten und das Verhalten nicht einkapseln, es hat nicht mehr die Kontrolle über die Daten zugegriffen werden und nicht ihre Verträge mit anderen Objekten durch die öffentliche Schnittstelle impliziert erfüllen.

Eines der großen Probleme dabei ist, dass, wenn eine Klasse intern geändert hat, die öffentliche Schnittstelle nicht ändern sollte. Auf diese Weise es nicht bricht keinen Code und andere Klassen weiter es nach wie vor verwendet wird.

Jedes Beispiel in PHP oder Java wäre sehr hilfreich sein.

Hier ist ein Java-Beispiel:

public class MyClass {
    // Should not be < 0
    public int importantValue;
    ...
    public void setImportantValue(int newValue) {
        if (newValue < 0) {
           throw new IllegalArgumentException("value cannot be < 0");
        }
    }
    ...
}

Das Problem hier ist, dass, weil ich nicht importantValue eingekapselt haben, indem sie private anstatt öffentlich, jeder kann kommen und umgehen den Scheck, den ich in der Setter setzen das Objekt zu verhindern, dass einen ungültigen Zustand. importantValue sollte nie weniger als 0, aber der Mangel an Kapselung macht es unmöglich, es zu verhindern, dass es zu sein.

Andere Tipps

Was die Folgen sein könnten nicht es zu tun?

Die ganze Idee hinter Kapselung ist, dass alles Wissen von irgendetwas auf die Klasse im Zusammenhang (mit Ausnahme seiner Schnittstelle) innerhalb der Klasse selbst ist. Zum Beispiel ermöglicht die direkte Zugriff auf Attribute setzt die Beweislast dafür, dass irgendwelche Zuordnungen gültig auf dem Code die Zuordnung zu tun. Wenn die Definition dessen, was gültige Änderungen ist, müssen Sie durchlaufen und Prüfung alles über die Klasse, um sicherzustellen, sie entsprechen. Einkapseln der Regel in einem „Setter“ Methode Mittel Sie es nur an einer Stelle ändern müssen, und jeder Anrufer etwas komisch versuchen, kann eine Ausnahme bei ihm im Gegenzug geworfen bekommen. Es gibt viele andere Dinge, die Sie könnten, wenn ein Attribut Änderungen zu tun, und ein Setter ist der Ort, es zu tun.

Unabhängig davon, ob die direkten Zugang für Attribute, die sie keine Regeln zu binden (zum Beispiel alles, was paßt in einer ganzen Zahl in Ordnung ist) ist ein gute Praxis ist fraglich. Ich nehme an, dass Getter und Setter ist eine gute Idee, aus Gründen der Konsistenz verwendet wird, das heißt, wissen Sie immer, dass Sie setFoo() nennen können das foo Attribut zu ändern, ohne zu sehen, die, ob Sie es direkt tun können. Sie ermöglichen ihm, auch zukunftssicher zu Ihrer Klasse so, dass, wenn Sie zusätzlichen Code auszuführen, der Ort, um es dort angezeigt wird.

Ich persönlich denke, die Getter und Setter zu verwenden ist plump aussehende. Ich würde viel lieber schreiben x.foo = 34 als x.setFoo(34) und freuen uns auf den Tag, wenn einige die Sprache für die Mitglieder mit dem Äquivalent von Datenbank-Trigger kommt, dass Sie den Code definieren lassen, dass Brände vor, nach oder anstelle einer Zuweisungen.

Meinungen auf, wie „gut OOD“ erreicht sind Groschen ein Dutzend, und auch sehr erfahrene Programmierer und Designer neigen dazu, über Design-Entscheidungen und Philosophien zu widersprechen. Dies könnte ein flamm Krieg Starter sein, wenn man die Leute über eine breite Sorten von Sprache Hintergrund und Paradigmen stellen.

Und ja, in der Theorie sind Theorie und Praxis die gleiche, so Sprachwahl nicht hoch Level-Design sehr viel beeinflussen sollte. Aber in der Praxis sie tun, und gute und schlechte Dinge passieren, weil das.

Lassen Sie mich hinzufügen: Es hängt davon ab, ob. Encapsulation (in einer Neben Sprache) gibt Ihnen eine gewisse Kontrolle darüber, wie Sie Klassen verwendet werden, so dass Sie können Menschen sagen: Das ist die API, und Sie müssen diese verwenden. In anderen Sprachen (zB Python) die Differenz zwischen offiziellen API und informellen (Änderungen vorbehalten) Schnittstellen ist durch Namenskonvention nur ( nach allem, wir sind alle Erwachsenen hier zustimmenden)

Die Einkapselung ist kein Sicherheitsmerkmal.

Ein anderer Gedanke, darüber nachzudenken,

Encapsulation mit Accessoren bietet auch viel besser Wartbarkeit in der Zukunft. In Feanors Antwort oben, funktioniert es große Sicherheitskontrollen (vorausgesetzt, Ihr instvar privat) zu erzwingen, aber es kann noch viel weiter reichende benifits hat.

Sie sich das folgende Szenario:
1) Sie Ihren Antrag ausfüllen und verteilen sie an einem gewissen Gruppe von Benutzern (intern, extern, was auch immer).
2) BigCustomerA nähert sich Ihr Team und will eine Audit-Trail zu dem Produkt gegeben.

Wenn jeder der Zugriffsmethoden in ihrem Code verwendet, wird dies fast trivial zu implementieren. So etwas wie so:

MyApi Version 1.0

public class MyClass {
    private int importantValue;
    ...
    public void setImportantValue(int newValue) {
        if (newValue < 0) {
           throw new IllegalArgumentException("value cannot be < 0");
        }
        importantValue = newValue;
    }
    ...
}


MyApi V1.1 (jetzt mit Audit-Trails)

public class MyClass {
    private int importantValue;
    ...
    public void setImportantValue(int newValue) {
        if (newValue < 0) {
           throw new IllegalArgumentException("value cannot be < 0");
        }
        this.addAuditTrail("importantValue", importantValue, newValue);
        importantValue = newValue;
    }
    ...
}

Bestehende Nutzer der API keine Änderungen an ihren Code machen und die neue Funktion (Audit Trail) ist jetzt verfügbar.
Ohne Verkapselung Accessoren Sich mit einem großen Migrationsaufwand gegenüber.


Wenn zum ersten Mal Codierung, wird es wie eine Menge Arbeit zu sein scheint. Seine viel schneller Art. class.varName = something vs class.setVarName(something); aber wenn jeder den einfachen Weg nahm, für BigCustomerA der Feature-Anfrage ein großer Aufwand wäre bezahlt

In Objekt Oriente Programmierung gibt es ein Prinzip, das als bekannt ist (http://en.wikipedia.org/wiki/Open/closed_principle): POC -> Das Prinzip der offenen und geschlossenen . Dieses Prinzip bleibt für: ein gut Klasse Design sollte für Erweiterbarkeit (Vererbung), aber geschlossen für eine Änderung der internen Mitglieder (Kapselung) geöffnet werden. Es bedeutet, dass Sie nicht in der Lage sein könnte, um den Zustand eines Objekts zu ändern, ohne über sie zu kümmern.

So, neue Sprachen nur ändern interne Variablen (Felder) durch Eigenschaften (Getter und Setter-Methoden in C ++ oder Java). In C kompilieren # Eigenschaften Methoden in MSIL.

C #:

int _myproperty = 0;
public int MyProperty
{
    get { return _myproperty; }
    set { if (_someVarieble = someConstantValue) { _myproperty = value; } else { _myproperty = _someOtherValue; }  }    
}

C ++ / Java:

int _myproperty = 0;
public void setMyProperty(int value) 
{
  if (value = someConstantValue) { _myproperty = value; } else { _myproperty = _someOtherValue; }
}
public int getMyProperty() 
{
    return _myproperty;
}

Nehmen Sie Thesen Ideen (von Head First C # ):

  • Denken Sie über Möglichkeiten, die Felder missbraucht werden. Was kann schief gehen, wenn sie nicht richtig eingestellt sind.
  • Ist alles in der Klasse der Öffentlichkeit? Verbringen Sie einige Zeit darüber nachzudenken, Kapselung.
  • Welche Felder erfordern die Verarbeitung oder Berechnung? Sie sind erstklassige Kandidaten.
  • Nur machen Felder und Methoden öffentlich, wenn Sie benötigen. Wenn Sie keinen Grund zu erklären, etwas Öffentlichkeit haben, nicht.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top