Frage

vorstellen, so etwas wie folgt aus:

import class B.*;


interface A supports A.testSum
{
   int sum( int a , int b ) access from B.calculator;

   testSum() { Assert(sum(1,1)==2); }

........


class B ...
{
  void calculator() {  A.sum(3,5); //ok }
  void someOtherMethod() { A.sum(0,3); //compile error }

Die Idee des „Trägers“ ist zweitrangig, aber relevant, da der Test in diesem Fall an die Schnittstelle gilt (so die Sprache zwischen einem Interface-Test unterscheiden würde, die alle Implementierungen passieren müssen und einen Implementierung Test, der spezifisch für das ist Umsetzung Gemeinen

aber die wichtige Idee, die ich hier vermitteln will, ist die Zugriffskontrolle Semantik; Beachten Sie, dass A.sum mit „Zugriff von“ Stichwort nur von der Methode B.calculator aufgerufen werden kann. Alles andere als der Kompilierung Fehler erkannt. Die Idee dabei ist architektonischen Zwänge in einer detaillierteren Art und Weise zu erzwingen. Wenn Sie nicht einen „Zugriff von“ oder einfach hinzugefügt „Zugang von *“ brachten hinzufügen würde es das Standardverhalten ermöglicht das Verfahren bedeutet, von überall aufgerufen werden. Was für eine Art von architektonischen Zwänge? Nun, die Art, die manuell durchgesetzt werden, wenn ein Schichtaufbau zu tun: Schicht A (niedrigste Ebene) aus Schicht B (Zwischenebene) verwendet, die wiederum von Schicht C (hohe Pegel) verwendet wird. Aber Schicht B ist aus der Schicht A nicht zugänglich ist, und die Schicht C ist nicht erreichbar von weder A oder B, aber es ist anders öffentlich (es könnte sein, was die Endbenutzer direkten Zugriff haben werden)

Frage: Kennen Sie eine Sprache (einschließlich Quelle-Source-Zwischensprachen), die die obige Semantik unterstützen? wenn diese Art von Semantik zusätzliche Punkte für die Diskussion sei kontraproduktiv, gefährlich oder einfach nur ermutigend schlechtes Design

Update: gibt es ein anderen wirklich wichtigen Anwendungsfall für diese Art von Einschränkung:

ereignisgesteuerte Programmierung: In der Regel ist das Problem mit Ereignis ist, dass Ereignisse neigen dazu, zu viel zu tun, und das Verständnis der Kette von Abhängigkeiten für Veranstaltungen kann tückisch

erhalten

so zum Beispiel, könnte man definieren, dass ein Event-Handler nur bestimmte Menge von sichtbaren Klassen haben es (oder umgekehrt, eine bestimmte Menge von Objekten nicht berühren kann) in Wechselwirkung treten kann

War es hilfreich?

Lösung

Java unterstützt etwas ziemlich die gleiche Sache.

Zu allererster Sichtbarkeit von Feldern und Methoden zur Laufzeit durchgesetzt werden, es für nicht privilegierten Code nicht möglich ist, dies zu umgehen.

Sie können auch Ihre eigenen Privilegien machen und sie auf bestimmte Teile des Codes gewähren. Zum Beispiel, eine Datei zu öffnen, den Code, der eine Datei Bedürfnisse FilePermission für diese Datei zugreifen möchte. Sie können jede Art von Genehmigung machen Sie aber wünschen, dann ist es möglich, eine Erlaubnis genannt SumPermission welche Calculator Kontrollen zu machen, bevor sie zusammengezählt, und gewähren sie nur zu, was Klassen, die Sie wollen. Schutz Domänen umspannen über Klassen, keine einzelne Methoden in den Klassen, weil eine ganze Klasse wird in der Regel aus einer Hand erhalten. Das Modell in der Tat geht tiefer, was Sie vorgeschlagen. Jede Klasse auf dem Stapel (einschließlich der Geschichte der Fäden Kreationen) eine Sicherheitsprüfung im Vorfeld muß die Erlaubnis hat, so dass, wenn einige nicht vertrauenswürdigen Code Code aufruft, die SumPermission hat, wird es die Sicherheitsüberprüfung fehlschlagen. Natürlich ist dies nur Standard, wenn Sie etwas tun, dass Bedürfnisse Berechtigungen Sie einen doPrivileged Block verwenden können, die bevorstehende Überprüfung sagen, nur Ihre Berechtigungen statt beide Ihre und Ihre Anrufer überprüfen.

Allerdings hat das aktuelle Standard-Sicherheitsschema in Java viele Einschränkungen. Zum einen kann nicht vertrauenswürdiger Code nicht die Berechtigungen zu unterteilen oder seine eigenen Berechtigungen für verschachtelten nicht vertrauenswürdigen Code definieren. Außerdem ist es ein Schmerz zum Schutz vor nicht vertrauenswürdigem Code blockiert.

Sie möchten überprüfen, E . Insbesondere folgt das Objekt Capability Modell. Es ist für beide Seiten nicht vertrauenswürdigen Code gemacht sicher zu interagieren, und hat Konstrukte Sprachniveau Deadlocks Probleme zu vermeiden.

Es ist durchaus möglich und machbar zwischen uns nicht vertrauenswürdigem Code in Java robustes Verhalten zu implementieren, aber E wird wahrscheinlich Ihre Arbeit viel leichter machen, und läuft auf der JVM, so sollten Sie dennoch in der Lage sein, Java-Bibliotheken und Büchereien von allen anderen Sprachen zu verwenden dass die JVM verwenden.

Andere Tipps

Das klingt ein bisschen wie ein Spezialfall des Objekt-Fähigkeit Modell . Vielleicht gibt es Sprachen, die diese in irgendeiner Art und Weise umzusetzen.

In ähnlicher Weise eine schnelle Google um für „Methode-Level-Security“ führte mich auf ein paar Dinge, die die Enterprise-Java-Community zu haben scheinen gekocht. Ich denke, dass spezialisierte diesen Ansatz nur Methode Beschimpfungen irgendwie sinnlos. Es sei denn, Sie einen sehr guten Grund, dies zu tun haben, ich denke, es ist wahrscheinlich eine schlechte Idee. Wenn Sie wirklich interessiert sind, aus irgendeinem Grund, es zu tun, dann wirklich das Modell sollte den Empfänger zu bekommen zu prüfen, ob der Aufruf Quelle ist in einigen gesetzt erlaubt.

Auf jeden Fall ist dies im Grunde bricht die meisten Programmiermodelle ziemlich schlecht. Sie würden viel besser dran, Voraussetzungen und Klasseninvarianten, um sicherzustellen, dass jeder Durchsetzung Methodenaufruf (von überall!) Sinnvoll ist oder gut erzogene. Wenn Sie es verwenden Methode Ordnung zu erzwingen, wird, dass kann mit invariant Prüfung (statisch oder zur Laufzeit) erreicht oder theoretische Modelle wie Schnittstelle Automata .

Das es tun kann in Ruby, wenn auch mit einer anderen Syntax. Nehmen Sie die folgenden:

module T
    def check
        raise unless self.is_a?(Ca)
        raise unless %r{in `good_func'} =~ caller.first #`
        true
    end
end

class Ca
    include T
    def good_func
        check
    end
    def bad_func
        check
    end
end

class Cb
    include T
    def good_func
        check
    end
    def bad_func
        check
    end
end

a = Ca.new
b = Cb.new

a.good_func
=> true
a.bad_func
=> (RuntimeError)

b.good_func
=> (RuntimeError)
b.bad_func
=> (RuntimeError)

Bei Verwendung des Moduls als Mix-in, self entspricht die Klasse, die includes das Modul. caller gibt die aktuelle Aufrufliste und caller.first bekommt man den ersten Eintrag auf der Aufrufliste (das heißt, die Funktion, dass diese eine genannt).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top