• FFK10 - 13. bis 16. April 2010 in Köln
  • Unterstützt das Flashforum!
  • Adobe User Group
Zurück   Flashforum > Flash > ActionScript > Softwarearchitektur und Entwurfsmuster

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 02-04-2003, 18:20   #1 (Permalink)
hOk
Neuer User
 
Benutzerbild von hOk
 
Registriert seit: Jun 2001
Ort: berlin
Beiträge: 829
Post traceMessages

Hi Leute,

des öfteren will man ja wissen welche Methoden eines Objektes
in welcher Reihenfolge aufgerufen werden. Mir ist gerade aufge-
fallen, dass man dieses ganz einfach lösen kann, in dem man die
Orginalmethode überschreibt und innerhalb der neuen Methode
einen trace macht und dann die Orginalmethode aufruft.

In anderen Sprachen wie Java, C++ oder PHP wäre das wohl nicht
so einfach, da soll nochmal jemand behaupten Actionscript wäre
keine mächtige Sprache...:-)
ActionScript:
  1. traceMessages = function (obj) {
  2.     for (var p in obj) {
  3.         if (typeof obj[p] != 'function') continue;
  4.         var tmp = obj[p];
  5.         obj[p] = function() {
  6.             trace('call-of> ' + arguments.callee.__methodName);
  7.             arguments.callee.__originalMethod.apply(this, arguments);
  8.         }
  9.         obj[p].__methodName = p;
  10.         obj[p].__originalMethod = tmp;
  11.     }
  12.     return '';
  13. }
  14.  
  15. // Test:
  16. Kaefer = function () {}
  17. Kaefer.prototype.init = function (pStrName, pIntAge) {
  18.     this.strName = pStrName;
  19.     this.intAge = pIntAge;
  20. }
  21. Kaefer.prototype.traceProperties = function () {
  22.     trace(this.strName + '(' + this.intAge + ')');
  23. }
  24.  
  25. objPaule = new Kaefer();
  26.  
  27. traceMessages(objPaule); // <--
  28.  
  29. objPaule.init('Paule', '23');
  30. objPaule.traceProperties();
  31.  
  32. // Output:
  33. //
  34. // call-of> init
  35. // call-of> traceProperties
  36. // Paule(23)
  37.  
nette Grüße, Holger
__________________
gobogo
hOk ist offline   Mit Zitat antworten
Alt 02-04-2003, 18:47   #2 (Permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
Hi Holger,
coole Idee,
da spart man sich doch einen Haufen Schreibarbeit.

Hier ist noch eine etwas andere Version,
die die jeweils zuletzt zugwiesene Methode traced.
Dann kann man selektieren, was man tracen will und was nicht, ohne dass man den Namen angeben muss.

ActionScript:
  1. traceLastMessages = function (obj) {
  2.     for (var p in obj) {
  3.         if (typeof obj[p] != 'function') {
  4.         } else {
  5.             var tmp = obj[p];
  6.             obj[p] = function () { trace('call-of> ' + arguments.callee.__methodName);arguments.callee.__originalMethod.apply(this, arguments);};
  7.             obj[p].__methodName = p;
  8.             obj[p].__originalMethod = tmp;
  9.         }
  10.         return;
  11.     }
  12. };
  13.  
  14. // Test:
  15. Kaefer = function () {
  16. };
  17. Kaefer.prototype.init = function(pStrName, pIntAge) {
  18.     this.strName = pStrName;
  19.     this.intAge = pIntAge;
  20. };
  21. traceLastMessages(Kaefer.prototype);
  22.  
  23. Kaefer.prototype.traceProperties = function() {
  24.     trace(this.strName + '(' + this.intAge + ')');
  25. };
  26.  
  27. traceLastMessages(Kaefer.prototype);
  28.  
  29. objPaule = new Kaefer();
  30. // <--
  31. objPaule.init('Paule', '23');
  32. objPaule.traceProperties();
  33. // Output:
  34. //
  35. // call-of> init
  36. // call-of> traceProperties
  37. // Paule(23)
  38.  

Vielen Dank für die gute Idee,
mfg r.
bokel ist offline   Mit Zitat antworten
Alt 02-04-2003, 19:01   #3 (Permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
Hehe,
und wo wir schonmal dabei sind,
hier ist noch eine Version, die mit resolve arbeitet:

ActionScript:
  1. traceMessages = function (obj) {
  2.     for (var p in obj) {
  3.         obj["_" + p] = obj[p];
  4.         delete obj[p];
  5.     }
  6. };
  7.  
  8. // Test:
  9. Kaefer = function () {
  10. };
  11. Kaefer.prototype.init = function(pStrName, pIntAge) {
  12.     this.strName = pStrName;
  13.     this.intAge = pIntAge;
  14. };
  15. //traceLastMessages(Kaefer.prototype);
  16. Kaefer.prototype.traceProperties = function() {
  17.     trace(this.strName + '(' + this.intAge + ')');
  18. };
  19.  
  20. Kaefer.prototype._resolve = function(name){
  21.     trace("resolve " + arguments);
  22.     return this["_" + name];
  23. }
  24.  
  25. traceMessages(Kaefer.prototype);
  26.  
  27.  
  28. //traceLastMessages(Kaefer.prototype);
  29.  
  30. objPaule = new Kaefer();
  31. // <--
  32. objPaule.init('Paule', '23');
  33. objPaule.traceProperties();
  34. // Output:
  35. //
  36. // call-of> init
  37. // call-of> traceProperties
  38. // Paule(23)
  39.  

mfg r.
bokel ist offline   Mit Zitat antworten
Alt 02-04-2003, 19:26   #4 (Permalink)
hOk
Neuer User
 
Benutzerbild von hOk
 
Registriert seit: Jun 2001
Ort: berlin
Beiträge: 829
Hehe, die __resolve würde ich aber dafür nicht
verschwenden, aber genial ist es auf alle Fälle...;-)
Hier nochmal mit Arguments und OnlyLastMethod-
Flag.
Kann man es nicht mit irgendeinem ASNative schaffen
an den Text der Funktion ranzukommen?
In Javascript ist das ja das normale toString-Verhalten
einer Funktion.
Wäre halt Klasse wenn man die erwarteten Argumente-
Bezeichner mit ausgeben könnte.
*grübel*
ActionScript:
  1. trace(String(traceMessages = function (pObj, pBlnLastMethodOnly) {
  2.     for (var p in pObj) {
  3.         if (typeof pObj[p] != 'function') continue;
  4.         var tmp = pObj[p];
  5.         pObj[p] = function() {
  6.             trace('call-of> ' + arguments.callee.__methodName + '(' + arguments.join(', ') + ')');
  7.             arguments.callee.__originalMethod.apply(this, arguments);
  8.         }
  9.         pObj[p].__methodName = p;
  10.         pObj[p].__originalMethod = tmp;
  11.         if (pBlnLastMethodOnly) return '';
  12.     }
  13.     return '';
  14. }).substr(0,0));
  15.  
  16. // Test
  17. Kaefer = function () {}
  18. Kaefer.prototype.init = function (pStrName, pIntAge) {
  19.     this.strName = pStrName;
  20.     this.intAge = pIntAge;
  21. }
  22. Kaefer.prototype.traceProperties = function () {
  23.     trace(this.strName + '(' + this.intAge + ')');
  24. }
  25.  
  26. objPaule = new Kaefer();
  27.  
  28. trace(traceMessages(objPaule)); // <--
  29.  
  30. objPaule.init('Paule', '23');
  31. objPaule.traceProperties();
  32.  
  33. // Output:
  34. //
  35. // call-of> init(Paule, 23)
  36. // call-of> traceProperties()
  37. // Paule(23)
  38.  
__________________
gobogo
hOk ist offline   Mit Zitat antworten
Alt 02-04-2003, 20:11   #5 (Permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
Eine Methode kenne ich,
dazu muss man eine Funktion innerhalb der zu tracenden
Funktion definieren, dann hat man Zugriff auf das Activation-
Objekt der aeusseren Funktion.

ActionScript:
  1. function eins(a,b,c){
  2.     function tracer(){
  3.         for(var i in this) trace(i);
  4.     }
  5.     tracer();
  6. }
  7.  
  8. eins(1,2,3);
  9.  
  10. ausgabe
  11. tracer
  12. c
  13. b
  14. a
  15. arguments

Die innere Funktion könnte man in eine include-Datei legen,
und überall dort wo man sie braucht, includen.

Nicht besonders schön

mfg r.
bokel ist offline   Mit Zitat antworten
Alt 02-04-2003, 20:26   #6 (Permalink)
hOk
Neuer User
 
Benutzerbild von hOk
 
Registriert seit: Jun 2001
Ort: berlin
Beiträge: 829
Stimmt, da hast du recht, schade eigentlich.

PS.: Lese gerade den Fowler, war ein super
Tip, hat auch mein Denken verändert...:-)
__________________
gobogo
hOk ist offline   Mit Zitat antworten
Alt 02-04-2003, 20:39   #7 (Permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
sach ich doch

ich habe gerade die design patterns bestellt.
ich bin gespannt, ich habe nämlich gerade ein
groesseres projekt abgeschlossen, bei dem
das sicher nützlich gewesen wäre

mfg r.
bokel ist offline   Mit Zitat antworten
Alt 03-04-2003, 19:01   #8 (Permalink)
Coalado
 
Registriert seit: Jun 2001
Ort: Lagcity.de
Beiträge: 683
debug

heir passen vieleicht folgene sachen ganz gut rein:


Mich hat es beim debuggen hin und wieder gestört, dass ich nicht wusste welcher Klasse eine instanz angehört.


typeof ist da nur bedingt hilfreich.


damit gehts aber eigentlich ganze gut...:



ActionScript:
  1. Function.prototype.subscribe = function(name) {
  2.     if (Function.reference == null) {
  3.         Function.reference = [];
  4.     }
  5.     var ref = Function.reference;
  6.     this.unSubscribe();
  7.     this.counter++;
  8.     ref.push([this.prototype, name, this.counter]);
  9.     return true;
  10. };
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19. Function.prototype.unSubscribe = function() {
  20.     var ref = Function.reference;
  21.     var max = ref.length;
  22.     for (var i = 0; i<max; i++) {
  23.         if (ref[i][0] == this.prototype) {
  24.             ref.splice(i, 1);
  25.             return true;
  26.         }
  27.     }
  28.     return false;
  29. };
  30.  
  31.  
  32.  
  33. //Anfügen einiger  internen Klassen
  34. Array.subscribe("Array");
  35. Date.subscribe("Date");
  36. Function.subscribe("Function");
  37. Object.subscribe("Object");
  38. String.subscribe("String");
  39. Number.subscribe("Number");
  40. Selection.subscribe("Selection");
  41. Color.subscribe("Color");
  42. MovieClip.subscribe("MovieClip");
  43. Sound.subscribe("Sound");
  44. TextField.subscribe("TextField");
  45.  
  46.  
  47. Object.prototype.getID = function() {
  48.     var ref = Function.reference;
  49.     var max = ref.length;
  50.     for (var i = 0; i<max; i++) {
  51.         if (ref[i][0] == this.__proto__) {
  52.             return ref[i][1];
  53.         }
  54.     }
  55.     return false;
  56. };
  57.  
  58.  
  59. Object.prototype.toString = function(arg) {
  60.     var ID = this.getID();
  61.     var str = ASnative(101, 4);
  62.     if (ID != false && arg != true) {
  63.         return str()+"  -  "+ID;
  64.     } else {
  65.         return str();
  66.     }
  67. };
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77. myArray=[]
  78.  
  79. trace(myArray) // ausgabe:  [Object-Object]   - Array
  80.  
  81.  
  82.  
  83. _global.klasse=function(){
  84.    
  85.     //...}
  86.    
  87. klasse.subscribe("Klasse")
  88.    
  89.    
  90.  
  91.    
  92.     myClass=new Klasse()
  93.    
  94.     trace(myClass)  // ausgabe:  [Object-Object]   - Klasse
  95.     trace(myClass.getID())   // ausgabe  Klasse
  96.  


MFG tumetom
tumetom ist offline   Mit Zitat antworten
Alt 03-04-2003, 19:54   #9 (Permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
@hok
Arg, jetzt habe ich gerade ne Stunde verloren,
bis ich gemerkt habe, dass die Ersatz-Routinen
von traceMessages kein Ergebnis liefern.
Das wird teuer für dich

@tumetom
Das sieht wild aus

Eine andere Möglichkeit ist die Zuweisung des Namens an
die Klasse: Klasse.classname = "MeineKlasse" und die Abfrage
von this.constructor.classname in der Instanz.

mfg r.
bokel ist offline   Mit Zitat antworten
Alt 03-04-2003, 20:06   #10 (Permalink)
Coalado
 
Registriert seit: Jun 2001
Ort: Lagcity.de
Beiträge: 683
hmm oder gleich als prototype... dann kann man sich den umweg über dne Konstruktor sparen..
warum so einfach wenns auch so schön kompliziert geht...??



Wies nicht emhr genau was.. aber irgendwas hab ich mir dabei wohl mal gedacht
tumetom ist offline   Mit Zitat antworten
Alt 03-04-2003, 20:42   #11 (Permalink)
hOk
Neuer User
 
Benutzerbild von hOk
 
Registriert seit: Jun 2001
Ort: berlin
Beiträge: 829
@tumetom
Sieht wirklich interessant aus, nur mit dem Array funktionierts
nicht, Array hat ja sein eigene toString, die den join(',') macht.

@bokel
Hups, dafür haste jetzt einen gemeinen Käfer bei mir gut...:-)

Hier ist noch eine neue Version, die bei jeder Nachricht die
Millisekunden seit der letzten Nachricht ausgibt. Den Bug habe
ich natürlich rausgenommen...:-)

Werde es wohl nochmal ändern, so dass die Zeit ausgeben wird
die der Methoden-Aufruf verbraucht hat, dann hat man einen
schönen Performance-Profiler.

netten Gruß, Holger
ActionScript:
  1. trace(String(traceMessages = function (pObj, pBlnLastMethodOnly) {
  2.     for (var p in pObj) {
  3.         if (typeof pObj[p] != 'function') continue;
  4.         var tmp = pObj[p];
  5.         pObj[p] = function() {
  6.             var t = getTimer() - arguments.callee.__traceMessages.intLastCallTime;
  7.             arguments.callee.__traceMessages.intLastCallTime = getTimer();
  8.             trace('<call-of ['+t+']> ' + arguments.callee.__methodName + '(' + arguments.join(', ') + ')');
  9.             return arguments.callee.__originalMethod.apply(this, arguments);
  10.         }
  11.         pObj[p].__methodName = p;
  12.         pObj[p].__originalMethod = tmp;
  13.         pObj[p].__traceMessages = arguments.callee;
  14.         if (pBlnLastMethodOnly) return '';
  15.     }
  16.     return '';
  17. }).substr(0,0));
__________________
gobogo

Geändert von hOk (03-04-2003 um 20:45 Uhr)
hOk ist offline   Mit Zitat antworten
Alt 03-04-2003, 20:46   #12 (Permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
@hok
Das mit dem Profiler ist eine gute Idee. Man koennte auch gleich
noch die Werte für einzelne Funktionen aufaddieren, dann sieht
man direkt in welchen Funktionen insgesamt die meiste Zeit verbracht wird und wo es sich am ehesten lohnt zu optimieren.

@tumetom
=)


mfg r .
bokel ist offline   Mit Zitat antworten
Alt 05-04-2003, 19:53   #13 (Permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
@hok
Ich habe es noch nicht genau analysiert,
aber ich glaube, wenn man mit Vererbung
arbeitet, gibt es irgendwie auch Probleme
mit traceMessages. Ich bekomme da manchmal
den Rekursionsfehler (256 Stufen).

--------------
So jetzt sind die "Design Patterns" (Gamma et. al.) da.

Das geht ja schon gleich gut los mit der Beschreibung eines
Wysiwig-Editors in OOP. Interessant finde ich die Aussage,
der Komposition gegenüber der Vererbung den Vorzug zu geben.

Da muss ich auch erstmal drüber nachdenken, wie das in meinen
Projekten aussehen würde. Das Problem, dass Änderungen von
Oberklassen u. U. zu Anpassungen in Subklassen führen können,
ist mir auch schon untergekommen. Die Komposition ist aber halt
auch immer etwas aufwendiger, wegen der Weiterleitung an
das betreffende Objekt.

Im Vergleich zum Fowler würde ich sagen, dass das Buch ein
wesentlich höheres Abstraktionsniveau behandelt. Den Fowler
kann jeder Programmierer gebrauchen, der seinen Stil
verbessern möchte, das hier ist schon eher was für Leute
mit viel Erfahrung in OOP.

mfg r.
bokel ist offline   Mit Zitat antworten
Alt 05-04-2003, 20:03   #14 (Permalink)
hOk
Neuer User
 
Benutzerbild von hOk
 
Registriert seit: Jun 2001
Ort: berlin
Beiträge: 829
Ja das denke ich auch.
Zum Thema Komposition versus Generalisierung:
Ich denke das was die GOF meinen ist, das man
nicht ohne wirklich trifftigen Grund generalisieren
soll, sondern nur dann wenn man abstrakte
Gemeinsamkeiten feststellt. Oft wird ja, geerbt
um mal eben noch mehr Funktionalitäten in einer
Klasse zu haben. Ich denke die GOF wollen einfach
nur, die auch von Fowler beschriebene, semantische
Distanz zwischen Methoden und Klasse vermeiden.
nette Gruß, Holger
__________________
gobogo
hOk ist offline   Mit Zitat antworten
Alt 06-04-2003, 13:33   #15 (Permalink)
querdenker
 
Benutzerbild von kelor
 
Registriert seit: Jun 2001
Ort: formel1-stadt hockenheim
Beiträge: 4.734
gefällt mir der threat...
hier habe ich noch was, dass den klassennamen der klasseninstanz zur verfügung stellt und zeitgleich der klasse und der instanz, jeweils ihren namen ausgibt...

ActionScript:
  1. /*******************************************\
  2.      function _getName (hier in _global definiert...geht aber überall...)
  3.      inkl. Function.prototype.getter
  4. /*******************************************/
  5. _global._getName = function (calling,tar) {
  6.         var props,temp;
  7.         tar=(tar==undefined) ? _root : tar;
  8.         this=(calling==undefined) ? this : calling;
  9.         for (props in tar) {
  10.                 if (tar[props]==this ) return props;
  11.                 else  if (typeof tar[props]=="movieclip" ){
  12.                         temp=this._getName(this,tar[props]);
  13.                         if (temp!=undefined) return temp;
  14.                 }
  15.         }
  16. }
  17. Function.prototype.addProperty("_ownName",_getName,null);
  18. /**************************************
  19. ende der globalen getName-fkt inkl. Function.prototype
  20. **************************************/
  21.  
  22. /***************************************
  23. klassenerzeugungsfunktion createClass
  24. ***************************************/
  25.  
  26. _global.createClass=function(tar,name){
  27.             var nm = name;
  28.             var tar=tar;
  29.             tar[nm]=function(){
  30.                 this._className=this.constructor._ownName;
  31.             }
  32.             tar[nm].prototype.addProperty("_ownName",_getName,null);
  33.             delete nm, tar;
  34. }
  35. /**********************************************
  36.   ende der erzeugungsfunktion
  37. ------------------------------------------
  38. funktion createClass nimmt 2 parameter...
  39. 1.parameter : zeitleiste
  40. 2.parameter : name der neuen funktion, als string!
  41. **********************************************/
  42.  
  43.  
  44.  
  45. // erzeugen der klasse 'dideldum' auf aktueller zeitleiste
  46. createClass(this,'dideldum');
  47.  
  48. ASSetPropFlags(dideldum,'prototype',0,1);
  49. // erzeugen eines abkömmlings von 'dideldum' mit dem namen 'diddel'
  50. diddel = new dideldum();
  51.  
  52. // kindsobjekt nach dem namen der klasse fragen, von dem es stammt...
  53. // dem eigenen namen
  54. // und mutterlement(die klasse) fragen, ob sie weiß, wie sie heißt...
  55. trace('diddel._className = '+diddel._className);
  56. trace('diddel._ownName = '+diddel._ownName);
  57. trace('dideldum._ownName = '+this[diddel._className]._ownName);

output:
diddel._className = dideldum;
diddel._ownName = diddel;
dideldum._ownName = dideldum

bezüglich der argumente in _getName(calling...) hatte ich hier noch das problem dass ich 'this' von außerhalb der fkt nicht gezielt ansteuern konnte....*grübel*
deshalb hatte ich es als argument mit an die fkt übergeben...
*anyideas?*

vielleicht hilft´s ja, dem ein oder anderen...

oder passte das jetzt nicht hierher..? *gugg*

greetz

kelor
kelor 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 09:10 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
FFK10 - 13. bis 16. April 2010 in Köln


Copyright ©1999 – 2010 Marc Thiele und Sascha Wolter.