Sprache Eiffel
 
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern

Veränderung (letzte Änderung) (keine anderen Diffs, Normalansicht)

Verändert: 206c206
KategorieProgrammierSprache
KategorieProgrammierSprache KategorieStatischTypisiert

Eine der bedeutendsten OO-Sprachen. Nicht im Sinne eines häufigen Einsatzes in kommerziellen Projekten, sondern sie galt eine zeitlang als wegweisend und wird teilweise an Universitäten in Kursen als 1. Programmiersprache eingesetzt.

Ist mehr von Simula als von Smalltalk beeinflusst. (SpracheSimula, SpracheSmalltalk)


Diskussion

Es gibt nur zwei Arten von Programmiersprachen: Die, die niemand verwendet und die, über die alle jammern. Eiffel gehört bei dieser Einteilung der Programmiersprachen klar in die erste Kategorie.

Die Eigenschaft von Eiffel die ich heute in einer Mainstream-Sprache vermisst habe
Nur so neben bei: Sowas wuerde ich persoenlich ein bischen vorplanen, dann sind solche Kilmmzuege nicht mehr notwending.

Dies kann man in C++ mit friend erreichen. In Java kann man Klassen, die speziellen Zugriff auf eine andere Klasse brauchen als statische innere Klassen der anderen Klasse implementieren. Innere Klassen haben vollen Zugriff auf die umgebende Klasse. --gR

Das Problem bei Java ist, daß die inneren Klassen ein CompilerFeature? sind und von der Virtual Machine nicht unterstützt werden. Der Compiler ändert z.B. die Sichtbarkeit der Methoden der äußeren Klasse, auf die die innere Klasse zugreift, klammheimlich zu "package visible". Siehe http://www.cs.umd.edu/~pugh/java/#sic --PhilippMeier?

IN Java reicht es eigentlich schon eine Klasse nur als @class@ zu deklarieren, und schon haben alle weiteren Klassen im selben Package vollen Zugriff! Es ist zwar fuer mich ein etwas Fragwuerdiges Feature, aber bitte fuer diesen Fll kann man es sicher nutzen.
Aso ist der Kilmmzug mit den inneren Klassen fuer sowas gar nicht notwending :-)

Zudem möchte ich behaupten, dass eine testwürdige, aber nicht-öffentliche Methode ein CodeGeruch ist. Es ist ein Hinweis darauf, dass die Methode eigentlich in eine andere Klasse möchte. Siehe CodeGeruch/SchwerTestbarerCode -- IljaPreuß

Objekte als Nadelöhr
Hier das versprochene Beispiel das zeigt warum der Eiffel Weg wie in OOSC beschrieben nicht ausreicht. Ich habe ja schon in ObjectOrientedSoftwareConstruction angedeutet warum ich meine das in Eiffel Agents aufgenommen werden müssen. Als Beispiel soll das gleiche wir unter SCSH ermöglichen eine Abstraktion für die Bearbeitung von Dateien in Verzeichnissen.

class ACTION[G,H]
-- Im Prinzip nur eine Vorlage fuer eine Funktion mit zwei Parametern
-- nicht abstrakt da sie instantiiert werden soll 

feature
    run (init_from: G; init_to: H) is do end;
    
end -- class ACTION
Hier wird eine Schablone für eine Aktion angelegt. Davon abgeleitet für das Beispiel:
class PRINT_ACTION
-- Diese Klasse wurde von ACTION abgeleitet und zeigt,  wie 
-- haesslich es sein kann alles durch Objekte abbilden zu wollen.
inherit ACTION[STRING,STRING]
        redefine
            run
            -- In Eiffel sind standardmaessig alle Methoden oder 
            -- Funktionen zu ueberschreiben. Ganz im Gegensazt zu C++ 
            -- wo man mit virtual festlegen muss, welche Methoden zum 
            -- ueberschreiben gedacht sind.

        end;
feature
    run (init_from: STRING; init_to: STRING) is
        do
            io.put_string(init_from + " -> " + init_to);
            io.put_new_line;
        end; 

end -- class PRINT_ACTION
{PRINT ACTION}? ist eine Subklasse von ACTION und legt die eigentlich auszuführende Ausgabe fest. Wir benötigen eine weitere Klasse um die Transformation auf dem Dateinamen vornehmen zu können. Das ist zusammen:
class TRANSFORMER[G,H]
-- Eine Vorlage fuer eine Funktion die Objekte vom Type G nach H 
-- transformiert.

feature
    run (from_g : G): H is do end    
    
end -- class TRANSFORMER

class DOWNCASE_TRANSFORM

inherit     
    TRANSFORMER[STRING,STRING]
        redefine
            run   
        end;
feature
    run (i_from: STRING): STRING is 
        do
            Result := clone(i_from);
            Result.to_lower;
        end;
end -- class DOWNCASE_TRANSFORM;  
Im SCSH Beispiel handelt es sich um eine Funktion transformer. Hier muß ich dafür eine eigene Klassenhierarchie bilden um es in dieser Vorlage enden zu lassen:
class TEMPLATE 

creation 
    make

feature
    make (init_directory: STRING; 
          init_action: ACTION[STRING,STRING]; 
          init_transform: TRANSFORMER [STRING,STRING]) is
        do
            directory := init_directory;
            action := init_action;
            transform := init_transform;
        end;
                       
        -- ommitting possibilties for reattaching things
    run is
    	local
    		dir: DIRECTORY;
        do
        	create dir.make_open_read(directory);
        	dir.start;
        	from dir.readentry
        	until
        		dir.lastentry = Void
        	loop
        		if (not equal(dir.lastentry, ".") and then
        		    not equal (dir.lastentry, "..")) then
        				action.run(dir.lastentry, transform.run(dir.lastentry));
      			end
        		dir.readentry;
        	end
        end;
feature {NONE}
    directory : STRING;
    action: ACTION[STRING,STRING];
    transform: TRANSFORMER[STRING,STRING];
    
end -- class TEMPLATE
Hierbei handelt es sich um eine "fast" so flexible Schablone wie in SCSH. Wir itereieren über ein Directory. Alle von ACTION und TRANSFORMER abgeleiteten Klassen können in dieser Schablone verwandt werden. Und damit wurde der Algorithmus verpackt.

Insgesamt können wir nun folgendes Programm erstellen:
class
	ROOT_CLASS

creation
	make

feature -- Initialization

	make is
		local
		   template : TEMPLATE;
		   directory : STRING;
    		   action : ACTION[STRING,STRING];
		   transform : TRANSFORMER[STRING,STRING];
		do
		   directory := "/tmp/test";
		   create {PRINT_ACTION} action;
		   create {DOWNCASE_TRANSFORM} transform;
		   create template.make(directory, action, transform);
		   template.run;
		end
end -- class ROOT_CLASS

Was machen wir hier? Wir legen das Verzeichnis fest, indem gearbeitet werden soll. Dann legen wir ein Objekt der Klasse ACTION an. Hier ist zu beachten, daß man in Eiffel Vorgänger Objekten Nachfolger zuordnen kann. Im Beispiel erzeigen wir ein Objekt vom Type {PRINT ACTION}? weisen es aber einem Objekt der Klasse Vorgänger zu, über polymorphe Aufrufe wird dann die "korrekte" Aktion aufgerufen. Das gleiche machen wir für ein Objekt der Klasse Transformer. Da wir den Algorithmus in TEMPLATE eingeschlossen haben. Fügen wir nun die benötigten Element zusammen und dann wird der eigentiche Algorithmus ausgeführt.

Mit folgenden Dateien (t1 T1.html T2.html T3) in /tmp/test ergibt sich folgende Ausgabe:

 T3 -> t3
 t1 -> t1
 T1.html -> t1.html
 T2.html -> t2.html

Das ganze mit der SCSH Lösung
(operate-on "/tmp/test" (lambda (f1 f2) (format #t "~a -> ~a~%" f1 f2))
              string-downcase "*")
ergibt ebenfalls:
 T1.html -> t1.html
 T2.html -> t2.html
 T3 -> t3
 t1 -> t1

Dieses Beispiel wurde von mir in comp.lang.eiffel vorgestellt und es ist tatsächlich der nötige Weg zu einer Lösung in Eiffel wie es in OOSC beschrieben wurde. Es gibt noch einige Abkürzungen aber das Grundschema ist das Gleiche. Man muß eine Objekthierarchie aufbauen und an der "richtigen" Stelle einklinken. Und hat dann immer noch nicht die Flexibilität einer Lösung mit einer Sprache die Funktionen als erste Klasse Objekt behandelt.

In Ruby oder Smalltalk könnte man mit Blöcken eine weitaus elegantere Lösung erstellen und in Eiffel natürlich durch den Gebrauch von Agenten. Wie sich die Eiffel Lösung dadurch vereinfachen lässt, werde ich hier auch einmal vorstellen.

Ich bin wohl nicht der einzige dem diese Sachen nicht gut erscheinen. In der Tat gibt es auch ein Buch das sich genau mit Erweituerungen von Eiffel um Funktionsobjekt handelt. Titel des Buches: "A Functional Pattern System for Object-Oriented Design"; Verlag Dr Kovac; ISBN 3-86064-770-9

Ich hoffe dieser etwas längere Ausflug hat Euch dennoch gut unterhalten ;-)


siehe auch EiffelResourcen BertrandMeyer ObjectOrientedSoftwareConstruction
KategorieProgrammierSprache KategorieStatischTypisiert
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Text dieser Seite ändern (zuletzt geändert: 17. März 2005 12:59 (diff))
Suchbegriff: gesucht wird
im Titel
im Text