Laden...

Vererbung wann?

Erstellt von Pedrito vor 15 Jahren Letzter Beitrag vor 15 Jahren 4.467 Views
P
Pedrito Themenstarter:in
86 Beiträge seit 2006
vor 15 Jahren
Vererbung wann?

Hallo, Leute,

bin gerade am Organisieren der für mein CMS benötigten Namespaces, Objekte und Methoden und ich versuche dabei auch das Konzept der Vererbung umzusetzen.

Grundsätzlich sieht das so aus:

// Root-NameSpace ShortHorn
namespace ShortHorn {
    public class AppInit : System.Web.UI.Page {
        public AppInit()
	}
    public class SqlManager {
        public SqlManager()
	}
    public class MailManager {
        public MailManager()
	}
    public class SecurityManager {
        public SecurityManager()
	}
	// NameSpace ShortHorn.Cms
    namespace Cms {
	    public class CmsInit : AppInit {
	        public CmsInit()
		}
	    public class PageInit : CmsInit {
	        public PageInit()
		}
	}
	// NameSpace ShortHorn.Web
    namespace Web {
	    public class WebInit : AppInit {
	        public WebInit()
		}
	    public class PageInit : WebInit {
	        public PageInit()
		}
	}
}

Je nachdem, ob ich eine CMS-Seite oder eine Webseite initialisiere, kann ich unter Gebrauch des richtigen NameSpace-Astes (Web|Cms).PageInit() aufrufen und habe sämtliche übergeordnete Methoden zur Verfügung. Das kommt mir bis hierher vernünftig vor(falls jemandem nicht, bitte melden 😉.
Globale Klassen befinden sich im obersten Namespace Shorthorn(mein Arbeitsname 😃, für Web oder Cms angepasste im zugeordneten Namensraum.

Jetzt stellt sich mir die Frage, wann man eine Vererbung ausserdem einsetzen darf oder nicht.
Der SecurityManager benötigt z.B. den SqlManager, der den DB-Layer kapselt, der MailManager wird ihn ebenfalls benötigen für ein Massen-Mailing. Jetzt könnte ich den SqlManager innerhalb SecurityManager(oder MailManager) mit new aufrufen.
Wäre es auch denkbar, den SecurityManager von SqlManager erben zu lassen? Oder sollten nur thematisch verwandte Klassen voneinander erben? Das gute Beispiel dafür wäre aus dem Galileo-Openbook: Circle() und GraphicCircle().

Was meinen die Profis dazu? Macht mein grundlegendes Konstrukt überhaupt Sinn?Was meint ihr zur Vererbung?

(Man lernt ja in Büchern schnell die technische Seite, aber Programmier-Moral und globale Organisation sind schwieriger raus zu ziehen)

Grüsse
Pedrito

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Pedrito,

Oder sollten nur thematisch verwandte Klassen voneinander erben?

ja, ich gehe sogar noch weiter. Vererbung kommt nur dann in Frage, wenn die Klassen in einer IST-EIN-Beziehung stehen. Wie in deinem Beispiel: GraphicCircle IST EIN Circle. Sonst nicht!

Man sollte NIE erben, nur weil man irgendwelche Methoden braucht.

Soweit ich das auf die Schnelle sehe, kommt in keiner der von dir genannten Situation Vererbung in Frage.

Normalerweise reicht es ja, wenn ein Objekt, die Objekte, die es braucht enthält oder einfach nur kennt.

herbivore

P
Pedrito Themenstarter:in
86 Beiträge seit 2006
vor 15 Jahren

Habe ich mir fast gedacht, dass es so ist.

Ist aber diese Vererbung okay?
AppInit : CmsInit : PageInit

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Pedrito,

nein!

herbivore

P
Pedrito Themenstarter:in
86 Beiträge seit 2006
vor 15 Jahren

Wieso? Die sind doch thematisch eng verwandt? Eine Cms|Web-Seite ist doch von einer System-Seite abgeleitet oder ist vom Typ System-Seite?

AppInit: Stellt System-Variablen zur Verfügung
CmsInit: Stellt erweiterte Variablen für das Cms zur Verfügung
PageInit: Stellt Methoden zur Page-Initialisierung bereit.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Pedrito,

die Begründung hatte ich ja schon oben gegeben. Die thematische Verwandschaft für sich genommen spielt kein Rolle. Vererbung nur, wenn eine IST-EIN-Beziehung vorliegt. Das ist in deinem Beispiel nicht der Fall.

herbivore

P
Pedrito Themenstarter:in
86 Beiträge seit 2006
vor 15 Jahren

Wahrscheinlich bin ich nur schwer von Begriff, nach meinem Verständnis ist ein PageInit ein CmsInit und das wiederum ein AppInit. Nicht dass du mich falsch verstehst, es geht mir nicht darum, recht zu behalten, ich verstehe es nur nicht besser.

Dann müsste ich also direkt auf der Ausgabe-Seite drei Objekte AppInit, CmsInit und PageInit hintereinander initialisieren?
Sagen wir mal, ich würde in einem fiktiven Fall ein Thumbnail für die betreffende Seite darstellen, dann würde das bedeuten:

string thumbNail =
appInit.RootPath

  • cmsInit.AssetsPath
  • pageInit.PageName
  • ".gif";
49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Pedrito,

mit *Init komme ich sowieso nicht so klar. Was warum *Init und nicht einfach nur App, Cms und Page?

Und dann ist doch klar, dass eine App keine Page ist, sondern dass eine App Pages hat. Und HAT (=Aggregation) ist in der Objektorientierung was ganz anders als IST (=Vererbung).

Die Url des Thumbnails der Seite wäre - so wie ich es verstehen würde - eine Eigenschaft der Seite. Also würdest du schreiben:

string thumbNailUrl = Path.ThumbnailUrl;

herbivore

P
Pedrito Themenstarter:in
86 Beiträge seit 2006
vor 15 Jahren

Dann liegt es vieleicht an der unpassenden Benennung, AppInit bedeutet nicht, das die Applikation gestartet wird, sondern dass Variablen initialisiert werden, die diese beschreiben, Eigenschaften also. CmsInit initialisiert CMS-Variablen, abgeleitet und auch abhängig vom Zustand der Applikation.

Vieleicht könnte man das auch so benennen:
SeiteDerApplikation > SeiteDesCms > HtmlSeiteDesCms
SeiteDerApplikation > SeiteDesCms > XmlSeiteDesCms
SeiteDerApplikation > SeiteDesWeb > PopUpSeiteDesWeb

Also ist eine HtmlSeiteDesCms vom Typ SeiteDesCms vom Typ SeiteDerApplikation.

Vom Thumbnail ausgehend: Das Bild ist Eigenschaft der Seite, aber nicht der Pfad dahin. Wenn einer das System in einen Subfolder des Webs schiebt, ändert eine Eigenschaft des Systems, während das Bild immer noch gleich heisst.

Mir kommt das nicht so völlig anders vor als GraphicCircle:Circle. GraphicCircle zeichnet das Objekt, basierend auf dem Zustand von Circle. Oder sehe ich das falsch?

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Pedrito,

Dann liegt es vieleicht an der unpassenden Benennung,

möglich. Wenn die Klassen wirklich immer weitergehende Spezialisierungen einer Seite sind und deren Objekte dabei weiterhin Seiten darstellen, dann wäre es in der Tat ok.

Vom Thumbnail ausgehend: Das Bild ist Eigenschaft der Seite, aber nicht der Pfad dahin. Wenn einer das System in einen Subfolder des Webs schiebt, ändert eine Eigenschaft des Systems, während das Bild immer noch gleich heisst.

Wenn die Seite ihre Url kennt, dann spricht nichts dagegen, dass sie daraus und aus dem Namen des Thumbnails auch die Url des Thumbnails zusammengesetzt liefert.

Mir kommt das nicht so völlig anders vor als GraphicCircle:Circle. GraphicCircle zeichnet das Objekt, basierend auf dem Zustand von Circle.

Ich kenne das Beispiel nicht. Wenn es so wäre wie du sagst, wäre es kein so gutes Beispiel für Vererbung. In [Artikel] Zeichnen in Windows-Programme ist ein Beispiel für Vererbung bei grafischen Objekten, dass vielleicht besser passt.

herbivore

P
Pedrito Themenstarter:in
86 Beiträge seit 2006
vor 15 Jahren

Man kann das mit dem Pfad sicher auf verschiedene Weise angehen und natürlich ebenfalls völlig korrekt und kurz den kompletten Pfad als Eigenschaft der Seite betrachten. Da aber praktisch jeder Bestandteil des CMS parametrisierbar sein muss, der Root-Pfad kann genau so ändern wie der Name des CMS-Ordners, muss ich das feiner auflösen.

Werde noch genauer nachlesen, was in Deinem Link steht. Hier trotzdem mein Beispiel:
http://openbook.galileocomputing.de/visual_csharp/visual_csharp_03_011.htm#mjbab77f3713a5b4cc7fe2aba44fc532e8
Alle Beispiele, die hier mit Vererbung zu tun haben, klingen ähnlich wie meine Aufgabenstellung, ich selbst drücke mich vieleicht ungenau aus, weil ich alles im Selbststudium mache.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Pedrito,

... muss ich das feiner auflösen.

intern vielleicht, aber nicht nach außen.

Hier trotzdem mein Beispiel:

Ich habs überflogen. Es scheint mir kein sehr schönes Beispiel zu sein., weil die Erweiterung ist funktional motiviert ist; man will eine zusätzliche Methode. Das ist nicht der Ansatz der Objektorientierung, nach dem Klassen als eigenständige Einheit Sinn machen sollen. Überlege zuerst, welche Klassen du brauchst und erst danach, welche Methoden und Eigenschaften sie haben sollen. Wenn man Schwierigkeiten hat, einen kurzen und prägnanten Namen für die Klasse zu finden, ist das ein Zeichen dafür, dass man auf dem Holzweg sein könnte.

herbivore

P
Pedrito Themenstarter:in
86 Beiträge seit 2006
vor 15 Jahren

Wenn man Schwierigkeiten hat, einen kurzen und prägnanten Namen für die Klasse zu finden, ist das ein Zeichen dafür, dass man auf dem Holzweg sein könnte.

Oder dafür, dass man kein Talent zur Namensfindung hat 😃

Wenn für dich das Circle/GraphicCircle nicht der reinen Lehre entspricht, dann frage ich mich, wo Vererbung überhaupt Sinn macht, das war für mich eigentlich das Beispiel, bei dem ich dachte: ah, so geht das mit der Vererbung 😃

C
401 Beiträge seit 2007
vor 15 Jahren

Ein immer wieder gern genommes Beispiel für Vererbung ist folgendes:



public class Person
{
    private int _age;
    private string _firstName;
    private string _lastName;

    // Properties
    ...    

    public Person(int age, string firstName, string lastName)
    {
        _age = age;
        ....
    }

    //Methods
    ....
}

public class Student : Person
{
    private int _matriculationNumber;
    
    // Properties
    ...

    public Student(int age, string firstName, string lastName, int matriculationNumber) : base(age, firstName, lastName)
    {
         _matriculationNumber = matriculationNumber;
    }

    // Methods
}


Für die Korrektheit des Codes gebe ich keine Garantie, ist eben schnell im Antwortfenster zusammengepfuscht.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Pedrito,

die Vererbung bei den Windows.Forms ist ein recht gutes Beispiel für sinnvolle Vererbung.

Hier mal ein kleiner Ausschnitt:


Control
   ButtonBase
      Button
      CheckBox
      RadioButton 
   Label
   ListControl
      ComboBox
      ListBox 
   ScrollableControl
      ContainerControl
         Form
             PrintPreviewDialog
         SplitContainer
      Panel

Wie du siehst, kann man die Systematik nachvollziehen, ohne dass man weiß, welche Methode und Properties in den verschiedenen Unterklassen hinzukommen. Die Klassen machen einfach als Klassen selbst Sinn.

herbivore

P
Pedrito Themenstarter:in
86 Beiträge seit 2006
vor 15 Jahren

Hallo, Leute,

ich danke euch für eure netten Tips und die bewiesene Geduld. Werde das alles nochmals genau überdenken.

Grüsse
Pedrito

3.971 Beiträge seit 2006
vor 15 Jahren

Hallo Pedrito,
eventuell wäre das Buch O´Reilly: Entwurfsmuster von Kopf bis Fuß was für dich. Dort wird Schritt für Schritt erklärt, wo man erben sollte oder wo man es lieber lassen sollte (Strategy-Pattern). Weiterhin werden auf verständliche Art und Weise weitere alltagstaugliche Entwurfspattern an sehr guten alltäglichen Beispielen beschrieben. Schaus dir mal an.

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

S
281 Beiträge seit 2004
vor 15 Jahren

das von eichhörnchen empfohlene buch ist ganz ok. hab ich selbst hier liegen. allerdings ist es einerseits etwas schade, dass es auf java ausgerichtet ist. auch wenn beide sprachen sehr ähnlich sind, ist es manchmal etwas "hubbelig" es im kopf zu übersetzen.
auch vermisse ich dort auch "komplette" patternbeispiele. ich persönlich bin was entwurfsmuster angeht noch am anfang und ich bin mir nie sicher ob ich jetzt auch wirklich das entwurfsmuster umgesetzt habe.

3.971 Beiträge seit 2006
vor 15 Jahren

ansonsten Nicht empfehlenswert: C# 3.0 Entwurfsmuster

Zu nicht Empfehlenswert, kann ich persönlich nix sagen, hab dieses Buch nicht gelesen. Eventuell diverse Kritiken entsprechend lesen oder bei entsprechenden Personen nochmal geziehlt nachhaken.

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo ihr beiden,

bitte Bücher nur in Buchempfehlungen diskutieren. Ein Hinweis auf ei Buch ist ja schon ok, aber mehr bitte in normalen Thread bitte nicht.

herbivore

5.941 Beiträge seit 2005
vor 15 Jahren

Hallo Pedrito

Vererbung ansich ist ja eine nette Sache, allerdings würde ich das nicht so excessiv nutzen.
Du verbaust dir damit bspw. die Möglichkeit, eine Seite von einer Dritthersteller Basisklasse abzuleiten, die Funktionalitäten bereitstellt, die du ansonsten bei jeder Seite von Hand einpflanzen müsstest.

Ich würde eher auf Komposition setzen und bspw. eine Liste von Managern in jeder Seite zu halten.
Um überall Zugriff auf diese Liste zu haben, könntest du eine Schnittstelle verwenden, die das vorgibt.

Das Buch "Entwurfsmuster von Kopf bis Fuss" kann ich sehr empfehlen, dass das für Java geschrieben wurde, macht ist egal. Die Sprachen sind sich so ähnlich das du fast alles 1:1 übernehmen kannst.

Und ausserdem ist der Fokus nicht auf der Sprache, sondern auf der Denkweise und der Muster sowie OOP-Prinzipien.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

P
Pedrito Themenstarter:in
86 Beiträge seit 2006
vor 15 Jahren

Hallo, Peter,
ich möchte eigentlich nur diese Basis-Linie vererben lassen, alles andere wird mit Managern gelöst. Ich benötige einfach saubere Schichten, die genau definierte Methoden und Felder zur Verfügung stellen(nicht so wie in meinem alten ASP-CMS, das ich ersetzen möchte).
Allerdings gebe ich zu, dass das alles an die Grenzen meiner Vorstellungskraft und Abstraktionsfähigkeit geht, vor allem wenn da noch andere Konzepte wie Polymporphie, usw. dazu kommen. Ich versuche nur schon das tolle Getränke-Beispiel mit dem Dekorierer zu verinnerlichen und komme mir dabei so blöd vor.

Gruss (Ebenfalls Peter 😃 Pedrito

P
Pedrito Themenstarter:in
86 Beiträge seit 2006
vor 15 Jahren

Hallo, Leute,
habe mal die Klassen umbenannt, dass da so stimmt:
HtmlPage|ServerPage|AnyOtherPageType ist auch eine CmsPage und eine AppPage.
ES gibt zwei Haupt Vererbungslinien Cms|Web, da ähnliche Methoden anders implementiert werden müssen, z.B. weichen Reaktionen auf Anmeldungen und die Art des Renderns völlig ab.

// Root-NameSpace ShortHorn
namespace ShortHorn {
    public class AppPage : System.Web.UI.Page {
        public AppPage()
	}
    public class SqlManager {
        public SqlManager()
	}
    public class MailManager {
        public MailManager()
	}
	// Cms-NameSpace ShortHorn.Cms
    namespace Cms {
	    public class CmsPage : AppPage{
	        public CmsPage() 
		}
	    public class HtmlPage : CmsPage {
	        public HtmlPage()
		}
	    public class ServerPage : CmsPage {
	        public ServerPage()
		}
	}
	// Web-NameSpace ShortHorn.Web
    namespace Web {
	    public class WebPage : AppPage {
	        public WebPage()
		}
	    public class HtmlPage : WebPage {
	        public HtmlPage()
		}
	    public class ServerPage : WebPage {
	        public ServerPage()
		}
	}
}

Die AppPage und die CmsPage kann selbst ja keine Seite rendern, das macht die abgeleitete Klasse HtmlPage. Damit es der Lehre entspricht, sollte nach meinem (geringen) Verständnis jede Basisklasse der aufrufenden Klasse gleichwertig sein. Es ist natürlich auch nicht geplant, dass man AppPage/CmsPage alleine aufrufen kann.
Müsste ich jetzt diese Klassen abstrakt machen und je eine abstrakte (fiktive Beispiel-) Methode RenderPage() implementieren, die erst auf Stufe HtmlPage konkret wird?