Zurück   Flashforum > Flash > ActionScript > Softwarearchitektur und Entwurfsmuster

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 03-11-2005, 19:32   #1 (permalink)
notzucht
 
Benutzerbild von shorty
 
Registriert seit: Nov 2003
Ort: Potsdam
Beiträge: 2.939
Grundsatzfrage: Konstructor & Werte der Klassenattribute

Kurz & Schmerzlos:

Einige attribute meiner klasse habe von vornherein einen default wert. Wo bzw. wie weise ich diese werte OOP gerecht zu, wenn sie nicht per Konstruktorparameter gesetzt werden? Hier mal 3 Beispiele (bitte ankreuzen)

A
PHP-Code:
class {
    
    private var 
x:String;
    
    function 
() {
        
'myString';
    }
    

B
PHP-Code:
class {
    
    private var 
x:String 'myString';
    
    function 
() {
    }
    

C
PHP-Code:
class {
    
    private var 
x:String;
    
    function 
() {
        
init();
    }
    
    private function 
init () : Void {
        
'myString';
    }
    

"ist geschmacksache" bringt mir nix, ich würde gerne wissen welche variante die deffinitiv richtige ist, bzw. die am wenigsten fehleranfällige & OOP gerechteste ist.

freue mich schon auf ne fachkundige antwort...

danke
shorty
__________________
.
Flex in a week | Viertel vor halb nach Vollmond | ^^°.°^^ | Waltz with Bashir
.

Geändert von shorty (04-11-2005 um 13:05 Uhr)
shorty ist offline   Mit Zitat antworten
Alt 03-11-2005, 20:38   #2 (permalink)
using namespace
 
Benutzerbild von artjom
 
Registriert seit: May 2002
Ort: Hamburg underground
Beiträge: 657
variante b ist die schnellste (performancemäsig), weil du ne variable deklarierst und ihr gleich einen wert zuweist.
stellt dich aber vor kleine probleme bei der vererbung:
Code:
class CTest extends CTest1{
	private var m="dieser string wird im konstruktor der oberklasse verändert";
	public function CTest() {
		super("....");
		trace("ctest:"+m);//aber in dieser klasse merkste nix von. m hat neuen wert
	}
}
-------
class CTest1{
	private var m;
	public function CTest1(pars) {
		m="variable verändert in Ctest1";
		trace("ctest1:"+m);
	}
}
variante a ist (nenn ich mal) die typischste, steht in allen lehrbüchern so.

variante c solltest du nur dann benutzen, wenn du ne klasse "reseten" willst. so dass du auch nach dem konstruktoraufruf die init funktion mal aufrufen kannst.

meine schlauen anworten mögen von besseren ergänzt oder ersetzt werden amen

gruß
__________________
artjom.com -|- Melom
Einen PC beschleunigen? Klar, mit 9,81 m/s^2!
artjom ist offline   Mit Zitat antworten
Alt 03-11-2005, 20:58   #3 (permalink)
notzucht
 
Benutzerbild von shorty
 
Registriert seit: Nov 2003
Ort: Potsdam
Beiträge: 2.939
Sehr gut, B ist also definitiv raus ...!

Verstößt die Wertezuweisung in Beispiele C gegen irgendwelche OOP regeln oder Grundsätze? Weil irgendwie scheint mir die möglichkeit diejenige zusein, dir mir am meisten eben jener offen hält ...

Die erklärung mit dem reset war genau das was mir dabei vorschwebte...

Danke artjom, danke!
__________________
.
Flex in a week | Viertel vor halb nach Vollmond | ^^°.°^^ | Waltz with Bashir
.
shorty ist offline   Mit Zitat antworten
Alt 03-11-2005, 21:32   #4 (permalink)
Entwickler
 
Registriert seit: Apr 2002
Ort: Edinburgh, UK
Beiträge: 301
ich würde sagen das keine deiner Vorschläge gegen OOP Grundsätze verstößt. Gerade Vorschlag B habe ich schon oft auch in anderen OOP Sprachen gesehen. Ist halt kurz und übersichtlich. Speziell in Flash/Flex kann das im Moment allerdings im Zusammenhang mit dem new Operator zu Problemen führen. Deshalb vorsicht bei z.B.:

private var meinObject:Object = new Object();

Gruss,
Alex
__________________
Open Source ActionScript Lib AnimationPackage
Alex U. ist offline   Mit Zitat antworten
Alt 03-11-2005, 21:56   #5 (permalink)
notzucht
 
Benutzerbild von shorty
 
Registriert seit: Nov 2003
Ort: Potsdam
Beiträge: 2.939
Super Alex,

dass nichts davon gegen irgendwelche Grundsätze verstößt ist gut zuwissen, aber variante B hat doch den entscheidenden Nachteil, das wenn ich wie artjom es beschreibt extende mir meine kompletten werte überschrieben werden könnten.

irgendwie finde ich variante B sehr fehleranfällig (geht das nur mir so?)

shorty

Danke Alex
__________________
.
Flex in a week | Viertel vor halb nach Vollmond | ^^°.°^^ | Waltz with Bashir
.

Geändert von shorty (03-11-2005 um 22:05 Uhr)
shorty ist offline   Mit Zitat antworten
Alt 03-11-2005, 22:45   #6 (permalink)
nerdig working
 
Benutzerbild von michael
 
Registriert seit: Jul 2001
Ort: Hamburg
Beiträge: 5.832
ich nehme eigentlich auch meistens variante A
B sorgt wie gesagt bei referenzobjekten nur für stress:
PHP-Code:
class {
    private var 
x:Array = [123];
    function 
B() {
    }
    function 
setter(arg) {
        
x[1] = arg;
    }
    function 
getter() {
        return 
x;
    }
}
------------------------
b1 = new B();
b1.setter(99);
trace(b1.getter()); //1,99,3
b2 = new B();
trace(b2.getter()); //1,99,3 
variante C auch mal gern, wenn wie schon gesagt ein zurücksetzen möglich sein soll oder ich mit __proto__ rumpanschen muss.
michael ist offline   Mit Zitat antworten
Alt 03-11-2005, 22:52   #7 (permalink)
Entwickler
 
Registriert seit: Apr 2002
Ort: Edinburgh, UK
Beiträge: 301
yep. Sehe ich auch so.
__________________
Open Source ActionScript Lib AnimationPackage
Alex U. ist offline   Mit Zitat antworten
Alt 03-11-2005, 23:32   #8 (permalink)
notzucht
 
Benutzerbild von shorty
 
Registriert seit: Nov 2003
Ort: Potsdam
Beiträge: 2.939
Ok, dann mach ich das jetzt fix, weil constructor heist ja auch nicht umsonst constructotr ...

A - nehm ich
B - macht stress & fliegt raus
C - nur wenn nötig, bzw. zusätzlich, falls ein reset o.ä. nötig ist

das is geil, so liebe ich das. besser gleich von anfang an richtig, als später wrong & stress ane backe.


shorty

ein danke geht natürlich auch an michael
__________________
.
Flex in a week | Viertel vor halb nach Vollmond | ^^°.°^^ | Waltz with Bashir
.
shorty ist offline   Mit Zitat antworten
Alt 04-11-2005, 09:28   #9 (permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
Danke an euch alle.
Ich habe den Thread mal unter [Wichtige Threads in OOP] unter Grundlagen verlinkt.

@Shorty: Danke für den Hinweis.

mfg. r
bokel ist offline   Mit Zitat antworten
Alt 04-11-2005, 10:04   #10 (permalink)
Flashaholic
 
Benutzerbild von atothek
 
Registriert seit: Feb 2003
Ort: Berlin
Beiträge: 1.459
So nun auch noch my 2 cents.
zum reseten implementiere ich immer eine extra
reset() methode das macht finde ich mehr sinn da beim init eventuell auch noch andere sachen gemacht werden als bei einem reinen reset.
eine init methode nutze immer dann wenn ich das initialisieren zu einem späteren zeitpunkt ausführen will aber das object schon erzeuge kann / will, zb. in preLoading situationen oder wenn man eine Bibliotheksobject mit einer klasse verknüpft etc.

mfg
alex
__________________
TVNEXT Solutions
atothek ist offline   Mit Zitat antworten
Alt 04-11-2005, 10:47   #11 (permalink)
muh
 
Benutzerbild von Janoscharlipp
 
Registriert seit: Apr 2002
Ort: Freiburg / Stuttgart
Beiträge: 4.338
Hab schon immer Variabte B verwendet, wusste aber nicht so genau warum … vielen Dank für den Thread.
__________________
»Carpe diem«, sagte der Graf. (Terry Pratchett: Ruhig Blut!)
Janoscharlipp ist offline   Mit Zitat antworten
Alt 04-11-2005, 12:51   #12 (permalink)
using namespace
 
Benutzerbild von artjom
 
Registriert seit: May 2002
Ort: Hamburg underground
Beiträge: 657
aus c++ ist aber bekannt, dass Instanzvariablen einer Klasse nur in Konstantenausdrücke zur Kompilierungszeit initialisiert werden dürfen.
also wäre das vorherige beispiel vom grundsatz her nicht wirklich richtig:
Code:
class B {
    private var x:Array = [1, 2, 3];//new Array() eine konstante?!
}
aber das mit dem array ist ne ausnahme.

gruß
__________________
artjom.com -|- Melom
Einen PC beschleunigen? Klar, mit 9,81 m/s^2!

Geändert von artjom (04-11-2005 um 12:53 Uhr)
artjom ist offline   Mit Zitat antworten
Alt 04-11-2005, 13:01   #13 (permalink)
notzucht
 
Benutzerbild von shorty
 
Registriert seit: Nov 2003
Ort: Potsdam
Beiträge: 2.939
Sehr schön, gleich drei [EDIT: 4] Korifeen auf einmal, das geht nun wirklich nur im FF.

@ ralf -

@ atothek - die erklärung für die benennung der Methoden reset(); und init(); ist toll, und wird, falls mal jemand anders in meinen code schauen muß eben jenen nun glücklicherweise nicht vor "unlösbare" probleme stellen. logic first - heist die devise. danke!

@ Janoscharlipp - das macht einen Knoten weniger & 5 minuten mehr zeit für ander dinge als debuggen, falls es dazu kommen sollte.

[EDIT]@ artjom - sorry, aber bei den Fachausdrücken verkrampft sich mein Gehirn für kurze zeit. Das Statement aus PostID #8 behält seine gültigkeit, richtig?!


shorty
__________________
.
Flex in a week | Viertel vor halb nach Vollmond | ^^°.°^^ | Waltz with Bashir
.

Geändert von shorty (04-11-2005 um 18:48 Uhr)
shorty ist offline   Mit Zitat antworten
Alt 07-11-2005, 07:46   #14 (permalink)
muh
 
Benutzerbild von Janoscharlipp
 
Registriert seit: Apr 2002
Ort: Freiburg / Stuttgart
Beiträge: 4.338
Ja, das gilt, oder du gehst noch ein bissel tiefer rein in die Materie, so dass du genau weißt, was welchen Effekt hat.
Die Sache ist ja die, dass AS 2.0 eigentlich nur ein Aufsatz auf AS 1 ist, alles was du schreibst wird wieder in AS 1 umgesetzt, AS 2.0 bietet lediglich einen einfacheren Zugang, und mehr Informationen beim Kompilieren (die Typen nämlich).

Ich mach mal im Folgenden ein Beispiel, das verdeutlicht, was das Problem bei den Instanzvariablen, welche in der Klasse mit einem Wert belegt werden, ist.
1. Beispiel, nur um dazustellen, was vor sich geht:
PHP-Code:
class Test extends Object
{
    public var 
myVar1 String "gaga";
    public var 
myVar2 String;
    public var 
myVar3 : Array = [123];
    public var 
myVar4 : Array;

    public function 
Test(text:String)
    {
        
myVar2 text;
        
myVar4 = [123];
    }

    public function 
toString(Void) : String
    
{
        return 
"[Test(myVar1=" myVar1 ", myVar2=" myVar2 ")]";
    }

Vor dem kompilieren wird diese AS2-Klasse in folgendes AS1 übersetzt:
PHP-Code:
// hiermit wird eine Klasse angelegt, was gleichzeitig dem Konstruktor entspricht.
function Test(text) {
    
this.myVar2 text;
    
this.myVar4 = [123];
};

// nun wird das Erben von Object umgesetzt:
Test.prototype = new Object();

// und hier werden die klassenspezifischen Variablen und Methoden angelegt:
Test.prototype.myVar1 "gaga";
Test.prototype.myVar2;
Test.prototype.myVar3 = [123];
Test.prototype.myVar4;

Test.prototype.toString = function() {
    return 
"[Test(myVar1=" this.myVar1 ", myVar2=" this.myVar2 ")]";
}; 
Letzteren Code kann man einfach in den 1. Frame eines leeren Flash-Dokuments kopieren, (auch in Flash MX) und nun ausprobieren:
PHP-Code:
// hier der letzte Code-Block

= new Test("bla");
= new Test("noch ein bla");

// Veränderungen in y vornehmen
y.myVar1 += " + ein Zusatz";
y.myVar2 += " + ein Zusatz";

trace("x.myVar1: " x.myVar1); // gaga
trace("x.myVar2: " x.myVar2); // bla

trace("y.myVar1: " y.myVar1); // gaga + Zusatz
trace("y.myVar2: " y.myVar2); // noch ein bla + Zusatz 
Die Ausgabe zeigt, dass wir myVar1 in y verändern konnten, ohne dass sich das auf x ausgewirkt hätte.
Bisher macht es also keinen Unterschied, ob die Variable in der Klasse, oder im Konstruktor geschrieben wird.
Im folgenden Beispiel ändert sich das aber jetzt:
PHP-Code:
// dies ist eine Fortführung des vorigen Code-Blocks

y.myVar3.splice(30"Zusatz");
y.myVar4.splice(30"Zusatz");

trace("x.myVar3: " x.myVar3); // 1, 2, 3, Zusatz (!!!!!!)
trace("x.myVar4: " x.myVar4); // 1, 2, 3

trace("y.myVar3: " y.myVar3); // 1, 2, 3, Zusatz
trace("y.myVar4: " y.myVar4); // 1, 2, 3, Zusatz 
Hier sieht man nun die Gefahr, wir haben nur die Variablen von y verwendet, aber die Variable myVar3 von x wurde auch geändert, da sie in der Klasse definiert wurde.

Das Problem ist, dass die Manipulation von primitiven Werten (String, Number, Boolean, ...) eigentlich ein Auslesen, Verrechnen, und dann neu Zuweisen ist. Beim neuzuweisen wird dann der Wert in das Objekt selbst geschrieben, nicht mehr in __proto__ (von wo er ausgelesen wurde).
Bei Eigenschaften, die nicht primitiven Datentypes sind (Objekte, Array, alles was die Instanz einer Klasse ist (also auch new String("abc")!!!)) wird das Objekt selbst verändert, da es an die verändernde Funktion als Referenz übergeben wird.

Mit einer Neuzuweisung wird die Referenz auf die __proto__-Eigenschaft mit einem eigenen Objekt überschrieben, deshalb hat sich x.myVar4 nicht verändert, es wurde im Konstruktor neu zugewiesen.

Dieses Verhalten ist ziemlich heimtückisch, und schwer zu debuggen, wenn man also Variablen gleich in der Klasse festlegen möchte, dann nur mit primitiven Datentypen, alles andere verursacht Caos.
Vielleicht könnten wir mal einen Namen für diese Variablen erfinden
__________________
»Carpe diem«, sagte der Graf. (Terry Pratchett: Ruhig Blut!)

Geändert von Janoscharlipp (07-11-2005 um 07:48 Uhr)
Janoscharlipp ist offline   Mit Zitat antworten
Alt 07-11-2005, 08:01   #15 (permalink)
notzucht
 
Benutzerbild von shorty
 
Registriert seit: Nov 2003
Ort: Potsdam
Beiträge: 2.939
wow...

Sehr schön Janoscharlipp, wirklich, also wirklich richtig sehr fein schön super toll gut!

Das muß ich jetzt erstmal verdauen und damit rumexperimentieren, damit es sitzt


Besten Dank!!!
__________________
.
Flex in a week | Viertel vor halb nach Vollmond | ^^°.°^^ | Waltz with Bashir
.
shorty ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an



Alle Zeitangaben in WEZ +1. Es ist jetzt 15:28 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2012 Marc Thiele