Methode vorschreiben, Schnittstelle nicht

Die Objektorientierung mit ABAP®: Vererbung, Dynamische Programmierung, GUI Controls (u.a. ALV im OO).
15 Beiträge • Seite 1 von 1
15 Beiträge Seite 1 von 1

Methode vorschreiben, Schnittstelle nicht

Beitrag von ralf.wenzel (Top Expert / 3924 / 200 / 280 ) »
Moin,

gegeben sei folgende Anforderung: Es gibt mehrere Klassen, die dieselben obligatorischen Methoden implementieren, eine dieser Methoden hat eine klassenspezifische Schnittstelle. Eigentlich ist der Fall klar: Abstrakte Superklasse - sie schreibt vor, dass alle Methoden redefiniert werden müssen. Aber dann müssen auch die Schnittstellen alle gleich sein. Ist die fragliche Methode mit der klassenspezifischen Schnittstelle nicht Bestandteil der Superklasse, wird sie in den unteren Klassen nicht redefiniert, sondern einfach zusätzlich implementiert. Das hat den Vorteil, dass die Schnittstellen dieser Methode frei definiert werden kann -- dann habe ich aber keine Möglichkeit, die Implementierung dieser Methode zu erzwingen.

Wer hilft mir aus dem Dilemma?
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

gesponsert
Stellenangebote auf ABAPforum.com schalten
kostenfrei für Ausbildungsberufe und Werksstudenten


Re: Methode vorschreiben, Schnittstelle nicht

Beitrag von a-dead-trousers (Top Expert / 4395 / 223 / 1182 ) »
Arbeite mit Interfaces:
Interface A mit Methode X
Interface B mit Methode Y
Klasse 1 implementiert nur Interface A
Klasse 2 erbt von 1 und implementiert zusätzlich Interface B

Oder du arbeitest mit "Generischen Parametern" (Type ref to Data, Type ref to Object, Clike, Csequence, any, usw. )

lg ADT
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Methode vorschreiben, Schnittstelle nicht

Beitrag von ralf.wenzel (Top Expert / 3924 / 200 / 280 ) »
Das erben der Schnittstelle B muss der Entwickler aber selbst machen -- ich kann ihm das nicht vorschreiben. Wenn ich es ihm vorschreibe, indem ich die Schnittstelle B schon in der Superklasse aufführe, ist die Schnittstelle wieder festgeschrieben.

Das Problem ist, dass die Methode zum Funktionieren der Anwendung zwingend notwendig ist, sie auch immer (grundsätzlich) dasselbe Ergebnis liefert, aber eben aus (sowohl in der Zahl, als auch in der Struktur und des Inhaltes) unterschiedlichen IMPORTING-Parametern.

Stell dir eine Methode vor, die aus unterschiedlichsten Eingabedaten einen MARA-Satz erzeugt (damit das ein bisschen plastisch wird). Mal muss ein Teil der Daten konvertiert werden und mal nicht, es gibt Felder, die gefüllt sein können aber nicht müssen, mal wird ein XML angeliefert das erst geparst werden muss, etc. Am Ende kommt immer dasselbe raus, nämlich der MARA-Satz. Wenn ich die Subklasse für eine "Eingabeart" ausprogrammiere, weiß ich auch, wie die Schnittstelle aussehen muss, aber eben nicht vorher, wenn ich die Oberklasse gestalte. Ich weiß, wenn ich die Oberklasse gestalte nur, DASS etwas kommen wird (aus nix kann man keinen MARA-Satz erzeugen), aber habe nicht im Entferntesten eine Ahnung, was denn das sein könnte.

Und ich will nicht die Methode in der Oberklasse jedesmal um optionale Parameter erweitern, weil was Neues dazukommt. Dienstag Oberklasse will ich nicht anfassen, wenn ich eine neue Subklasse definiere.
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: Methode vorschreiben, Schnittstelle nicht

Beitrag von a-dead-trousers (Top Expert / 4395 / 223 / 1182 ) »
Vor so einem ähnlichen Problem bin ich vor kurzem auch mal gestanden.
Ein bestimmtes Ergebnis, aber mehrere unterschiedliche Eingaben.

Lösung: Datenobjekte!

Eine Klasse oder besser ein Interface spezifiziert ein oder mehrere Public-Readonly-Attribute deines benötigten Typs. Wie dieses Attribut genau gefüllt wird, dafür muss der Programmierer sorge tragen der das Interface implementiert bzw. die Klasse ableitet. Du kannst aber auch noch GET/SET-Methode als "Abkürzung" vorgeben.
In deiner Weiterverarbeitung greifst du dann nur mehr auf das Attribut zu, das deine benötigt Struktur, Datentyp, Tabelle oder was auch immer hat. Das heißt alle nachgeschaltetenen Methode haben nur noch dieses Datenobjekt als Parameter. Du verschiebst also deine ganzen Methodenparameter in ein Objekt. Es ginge auch mit Strukturen aber IMHO bist du mit Objekten flexibler, weil du die Befüllungsmethoden gleich dabei hast.

lg ADT
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Methode vorschreiben, Schnittstelle nicht

Beitrag von ralf.wenzel (Top Expert / 3924 / 200 / 280 ) »
Wenn ich dich richtig verstehe, lasse ich die Importing-Parameter der fraglichen Methode einfach weg und definiere die Methode in der abstrakten Oberklasse (womit sie verpflichtend ist. Statt der Importing-Parameter implementiert die Subklasse eine öffentlich sichtbare Schnittstelle (und die kann ja von Subklasse zu Subklasse unterschiedlich sein). Statt also die Methode mit Importing-Parametern aufzurufen, implementiere ich eine passende Schnittstelle, in deren Attribute ich die Daten schreibe, die ich sonst in die Importing-Schnittstelle schreiben würde. Richtig?

Das klingt richtig gut. Wie bist du darauf gekommen?
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: Methode vorschreiben, Schnittstelle nicht

Beitrag von a-dead-trousers (Top Expert / 4395 / 223 / 1182 ) »
Jein. Lass die Subklassen am besten ganz weg. Deine Hauptklasse implementiert die ganzen Verarbeitungsmethoden. Diese Methoden verwenden in der Schnittstelle als einzigen Importing-Parameter ein Interface. Und dieses umfasst die eigentlichen Parameter, die du für die korrekte Verarbeitung brauchst als Public-Attribute. Derjenige der deine Klasse verwenden möchte muss also eine Klasse mit dem Interface implementieren, wobei er die Befüllung der Schnittstelle nach eigenem Ermessen machen kann (XML, DB-Selektion, usw.)

Das theoretische Grundkonzept kenn ich noch aus Schulzeiten. Aber erst jetzt durch einen neuen Mitarbeiter in der Abteilung hab ich die praktische Anwendbarkeit verstanden ;)
Ich wollte ursprünglich Methoden mit Parametern vom Typ ANY implementieren und dann im Coding per RTTI den tatsächlichen Typ ermitteln und die zugehörige Implementierung aufrufen. Mein neuer Kollege stammt aus der JAVA-Welt (war auch mein Ursprung, is aber schon lange her...) und er hat sich mit Händen und Füßen gewehrt eine "generische" Schnittstelle zu verwenden. Vollständige Typisierung ist immer besser, weil man zur Kompilierung schon Fehler sieht. So hab ich also an einer Lösung getüftelt die unser beider Ansätze ermöglicht.
Am Ende hatte ich dann ein Modell das auf Interfaces basiert. Diese umfassen Public-Attribute (die Typisiert sein müssen) und Methoden zur Befüllung (die generisch sein können). Wichtig für die Weiterverarbeitung sind nur die Public-Attribute. Wie die Befüllung passieren soll, bleibt dem jeweiligen Programmierer überlassen, der das Interface in seiner Klasse implementiert. Ein weiterer Vorteil von Interfaces ist, dass man auch mehrere in ein und derselben Klasse implementieren kann. Wenn also der Ausgangspunkt ein XML ist, wo mehrere unterschiedliche Datensätze gespeichert sind die in mehreren unterschiedlichen Schnittstellen benötigt werden, kann man das Auslesen in nur einer Klasse implementieren. Diese befüllt die Daten der implementierten Interfaces und kann dann auch in mehreren weiterverarbeitenden Methoden Verwendung finden.

lg ADT
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Methode vorschreiben, Schnittstelle nicht

Beitrag von ralf.wenzel (Top Expert / 3924 / 200 / 280 ) »
Dann hatte ich dich komplett falsch verstanden. Ich behalte mal die Trennung "abstrakte Klasse" / "konkrete Klasse" bei, damit man hier trennt zwischen dem, was jetzt vorgedacht und dem, was später umgesetzt werden muss.

Was ich verstanden hatte: Definiere in der abstrakten Klasse die fragliche Methode ohne Importing-Parameter, damit ist sie vorgeschrieben. Statt die Werte nun über Importing-Parameter mitzugeben, kann der Entwickler der konkreten Klasse in die Attribute der Klasse eine Schnittstelle eintragen (die er ja frei definieren kann), damit ist die Schnittstelle der Methode (quasi ausgelagert auf die Klassenattribute) variabel. Vor dem Aufruf der Methode "befüllt" der Entwickler also die Schnittstelle und die Methode bedient sich aus ihrer.

Jetzt klingt das eher nach: Definiere in der abstrakten Klasse die fragliche Methode mit einem Importing-Parameter, in dem die Schnittstelle übergeben wird. Aber dann bin ich doch vom Typ her wieder festgelegt (ich muss ja den Importing-Parameter typisieren, wenn ich die Methode definiere). Oder habe ich das immer noch nicht richtig verstanden?

Was spricht gegen die obere der beiden Lösungen?
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: Methode vorschreiben, Schnittstelle nicht

Beitrag von a-dead-trousers (Top Expert / 4395 / 223 / 1182 ) »
Die Flexibilität.

Natürlich kannst du es auch rein mit Klassen machen. Der Vorteil bei Interfaces liegt darin, dass du sie beliebig kombinieren kannst.
In deinem Fall hast du die Parameter als Attribute für den Methodenaufruf öffentlich in der Hauptklasse. Das finde ich nicht so toll, weil du ja durchaus mehrere solcher Methoden haben kannst und dann würden sich die Parameter uU sogar überschneiden.

Vielleicht kannst du meine Lösung so besser verstehen:

Ein "Request"-Objekt, dass die Parameter für den Methodenaufruf als Attribute definiert.
Die Methode selbst ist Teil eines "Access"-Objektes und nimmt für die Verarbeitung das "Request"-Objekt als Parameter entgegen.
Das Ergebnis (Return) der Methode wäre dementsprechend dann ein "Result"-Objekt.

Durch Definition als Interfaces kann man dann ziemlich viel auch wiederverwendbar machen.
Wie die Befüllung des Attributes bzw. der Attribute des "Request"-Objekts erfolgt, wird erst in der implementierenden Klasse festgelegt.

lg ADT
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Methode vorschreiben, Schnittstelle nicht

Beitrag von ralf.wenzel (Top Expert / 3924 / 200 / 280 ) »
Du verstehst mich miss ;) Im Gegensatz zu dir (Interface als Parameter der Methode) will ich das Interface als Attribut der Klasse mitgeben, die die fragliche Methode implementiert. Vorteil in meinen Augen: Derjenige, der die konkrete Klasse programmiert, kann so viele Datenobjekte in die Schnittstelle packen und sie nach Belieben typisieren wie er will.

Das muss er nicht öffentlich sichtbar machen, er kann die Schnittstelle auch auf privat setzen und entsprechende Setter-Methoden implementieren (was sauberer ist).

Sehe ich die Schnittstelle als Importing-Parameter vor, muss ich den Parameter schon jetzt typisieren -- und gerade das will ich ja nicht, weil ich gar nicht weiß, was er an die Methode übergeben will.

Oder habe ich irgendwas falsch verstanden?
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: Methode vorschreiben, Schnittstelle nicht

Beitrag von a-dead-trousers (Top Expert / 4395 / 223 / 1182 ) »
Du meine Güte, steh ich oft auf der Leitung ;)
Vorallem da ich dir das vorgeschlagen hab und du es noch eher kapiert hast als ich :P

Natürlich gehts so wie du das vorhast. Mit Getter und Setter ist es sogar noch eine Spur eleganter als mit den Attributen. Ich hab mich zu sehr von meiner Variante blenden lassen. Ich hab das für ein DAO/MOCK-Framework für UNIT-Tests entwickelt. Da war die Vorgabe, dass beim DAO keine Daten (Zustände) gespeichert werden dürfen und somit dessen Arbeitsweise beeinflussen (können). Also musste ein "Request"-Objekt diesen Part übernehmen. Da wird alles reingestopft was für die DB-Abfrage notwendig ist. Dein Ansatz hat mich sehr stark daran erinnert, daher hab ich mich zu sehr auf das versteift. Sorry.

btw. Das mit den Public (Read-Only!) Attributen ist meiner Faulheit geschuldet: Mir war es zu mühsam dafür die Setter zu schreiben. Außerdem müsste man dann in der Methode die das SELECT-Statement ausführt für jeden einzelnen Parameter wieder eine lokale Variable vorhalten. Dank der Attribute, kann ich darauf auch direkt im SELECT zugreifen ohne irgendwelche unnötigen Verrenkungen zu machen.

lg ADT

Folgende Benutzer bedankten sich beim Autor a-dead-trousers für den Beitrag:
ralf.wenzel

Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Methode vorschreiben, Schnittstelle nicht

Beitrag von ralf.wenzel (Top Expert / 3924 / 200 / 280 ) »
Trotzdem möchte ich deine Variante auch verstehen, aber dazu müssen wir uns wohl mal treffen, fürchte ich.
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: Methode vorschreiben, Schnittstelle nicht

Beitrag von a-dead-trousers (Top Expert / 4395 / 223 / 1182 ) »
Tja, wenn du mal im Süden von Österreich zu tun hast, gerne ;)

Kleines Beispiel anhand der MARA zum leichteren Verständnis:
DataRequestObjetct

Code: Alles auswählen.

interface ZIF_DRO_MARA
  public .
  data GT_MATNR type range of MATNR read-only.
  data GT_MTART type range of MTART read-only .
endinterface.

Code: Alles auswählen.

class ZCL_DRO_MARA definition
  public
  create public .
public section.
  interfaces ZIF_DRO_MARA.

  methods ADD_MATNR
    importing
      !ID_MATNR type MATNR.
ENDCLASS.

Code: Alles auswählen.

CLASS ZCL_DRO_MARA IMPLEMENTATION.
METHOD ADD_MATNR.
  Field-symbols:
    <ls_matnr> like line of me->gt_matnr.

  APPEND INITIAL LINE TO me->gt_matnr ASSIGNING <ls_matnr>.
  <ls_matnr>-sign = 'I'.
  <ls_matnr>-option = 'EQ'.
  <ls_matnr>-low = ID_MATNR.
ENDMETHOD.
DataAccessObjetct

Code: Alles auswählen.

interface ZIF_DAO_MARA
  public .

  methods GET_MULTIPLE
    importing
      !IR_REQUEST type ref to ZIF_DRO_MARA
    returning
      value(RT_RESULT) type MARA_TAB
    raising
      CX_DYNAMIC_CHECK .
endinterface.

Code: Alles auswählen.

class ZL_DAO_MARA definition
  public
  create public .
public section.
  interfaces ZIF_DAO_MARA.
ENDCLASS.

Code: Alles auswählen.

CLASS ZL_DAO_MARA IMPLEMENTATION.
METHOD ZIF_DAO_MARA~get_multiple.
  REFRESH rt_result.

  SELECT *
    FROM mara
    INTO TABLE rt_result
    WHERE matnr IN ir_filter->gt_matnr
      AND mtart IN ir_filter->gt_mtart.
  
  SORT rt_result BY matnr.
ENDMETHOD.
ENDCLASS.
Der Zugriff würde dann in etwa so ablaufen:

Code: Alles auswählen.

data: 
  lr_dao type ref to ZIF_DAO_MARA,
  lr_dro type ref to ZIF_DRO_MARA,
  lt_mara type mara_tab.

create object lr_dro
  type ref to ZCL_DRO_MARA.
create object lr_dao
  type ref to ZCL_DAO_MARA.

lr_dro->add_matnr( id_matnr = '...' ).
lt_mara = lr_dao->get_multiple( ir_request = lr_dro ).
In dem Beispiel sieht das noch nach nichts aus, aber man kann Klassen die den DAO global verwenden einfach einen anderen DAO (MOCK) unterschieben der Testdaten zur Laufzeit enthält und keine DB-Selektion macht. Damit lassen sich dann UNIT-Tests schreiben die nicht von den DB-Daten abhängig sind um die Funktionalitäten der Hauptklasse zu testen.

lg ADT
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Methode vorschreiben, Schnittstelle nicht

Beitrag von ralf.wenzel (Top Expert / 3924 / 200 / 280 ) »
a-dead-trousers hat geschrieben:Tja, wenn du mal im Süden von Österreich zu tun hast, gerne ;)
Oh, dann wird das wohl nix.
a-dead-trousers hat geschrieben:Kleines Beispiel anhand der MARA zum leichteren Verständnis:
Genau an deinem Beispiel kann man das Problem erkennen: Du musst vorgeben, welchen Typ das hat, was reinkommt. Projeziert auf mein Beispiel: Angenommen, jetzt möchte jemand nicht nach MATNR und MTART, sondern ( zusätzlich order ausschließlich) nach ersda und ernam selektieren. Dann musst du die Schnittstelle deiner Methode ändern (was bei einer vererbten Methode nicht geht).

In meinem Lösungsweg hat get_multiple keine Importing-Parameter, sondern bedient sich aus der Schnittstelle, die der Entwickler der erbenden Klasse in eben diese Klasse hängt. Die kann er ja gestalten, wie er will, er MUSS aber eine in die Attribute hängen, weil er get_multiple ja auf anderem Wege keine Daten geben kann, die es verarbeiten könnte. Und statt Importing-Parameter mitzugeben, füllt er einfach die Schnittstelle.
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: Methode vorschreiben, Schnittstelle nicht

Beitrag von a-dead-trousers (Top Expert / 4395 / 223 / 1182 ) »
Das Kozept von mir geht ja in die Richtung, dass bei einer neuen Anforderung die Schnittstelle um zusätzlich Parameter erweitert wird.
Oder eben ein neues Schnittstellen-Interface angelegt wird inkl. einer neuen Abfrage-Methode.
Ursprünglich wollte ich es ja so generisch wie möglich lösen, aber meine Kollegen bestanden darauf, dass die statische Syntaxprüfung als Sicherheitsnetz nicht ausgehebelt wird, weil es sich um eine Low-Level-API handelt.

In deinem Fall ist ja die Datenhaltung und die Verarbeitungs-Methode in einem Objekt kombiniert. Bei mir war es eine Vorgabe diese getrennt zu halten. Daher musste ich irgendwo eine Art von (statischer) Schnittstelle dazwischen bereitstellen. Dank Rang-Tabelle ist es wenigsten etwas flexible geworden, damit man nicht jeden kleinen Furz ausprogrammieren muss.

Ursprünglich hab ich mir gedacht, dass das Paradigma auch zur Gänze auf dein Problem anwendbar wäre. Du hast es natürlich gleich durchschaut und dir das rausgepickt was für dich brauchbar war ;)

lg ADT
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50


Seite 1 von 1

Vergleichbare Themen

1
Antw.
3968
Views
REST-Schnittstelle mit PUT-methode
von GünterL » 27.11.2023 13:57 • Verfasst in Development Related
3
Antw.
1772
Views
Schnittstelle zu SAP
von KristinF » 18.06.2007 12:51 • Verfasst in ABAP® für Anfänger
3
Antw.
3061
Views
SD-PP-Schnittstelle
von ewx » 14.12.2004 18:22 • Verfasst in Sales and Distribution
4
Antw.
2352
Views
URL für RFC Schnittstelle
von cschmoel » 01.10.2012 14:23 • Verfasst in ABAP® für Anfänger
2
Antw.
4768
Views
XML-RPC-Schnittstelle
von Otscho » 01.04.2008 13:11 • Verfasst in ABAP® Core

Aktuelle Forenbeiträge

Dialog-Container mit Toolbar/Status
vor einer Stunde von black_adept gelöst 21 / 2533
SAP Trial Version für SAP Fiori
vor 2 Tagen von tar 2 / 1669

Newsletter Anmeldung

Keine Beiträge verpassen! Wöchentlich versenden wir lesenwerte Beiträge aus unserer Community.
Die letzte Ausgabe findest du hier.
Details zum Versandverfahren und zu Ihren Widerrufsmöglichkeiten findest du in unserer Datenschutzerklärung.

Aktuelle Forenbeiträge

Dialog-Container mit Toolbar/Status
vor einer Stunde von black_adept gelöst 21 / 2533
SAP Trial Version für SAP Fiori
vor 2 Tagen von tar 2 / 1669

Unbeantwortete Forenbeiträge

Daten an Tabelle binden
vor 2 Tagen von Bright4.5 1 / 729
aRFC im OO-Kontext
vor 4 Wochen von ralf.wenzel 1 / 2356
Hilfe bei SWEC/SWE2
letzen Monat von retsch 1 / 8940