Laden...

Klassenstruktur

Erstellt von altertoby vor 17 Jahren Letzter Beitrag vor 17 Jahren 3.222 Views
A
altertoby Themenstarter:in
61 Beiträge seit 2005
vor 17 Jahren
Klassenstruktur

Hi Leute,

hab gerade nen Prob mit der Klassenstruktur...muss dazu sagen, dass ich im Programmieren nicht wirklich blutiger Anfänger bin jedoch mit OOP meine Probs habe und deshalb einfach mal wissen will wie ihr das lösen würdet!

Szenario:
Also ich will ne einfach Webseite machen, wo ein Banner oder Textlink aller 30 sek neu aus der Datenbank geladen wird (mit ReloadSperre).

Dafür hab ich mir ne ne normale Webseite gemacht und ein eigenes UserControl, welches das aller 30sek neuladen und Werbung anzeigen übernehmen soll.
Dieses Control nenne ich jetzt einfach mal RotateAds. Dort gibts 2 Propertys: 1. AdType (Auswahl zw. Banner und Textlink (soll erweiterbar sein) mit Hilfe eines Enum) 2. AdKind (eig. uninteressant...sagt nur welche Art von Werbung angezeigt werden soll...da gibts View oder Klick und wieder mit Enum)
Das Control soll dann einfach verwendet werden, dass man die Propertys setz (oder halt Standardwerte) und dann die Banner angezeigt werden...soweit funz es auch schon.

So jetzt aber zu dem interessanteren Teil:
Wie bekomme ich die Daten aus der Datenbank in mein Control!
Momentane Weg:
Datenbank (Stored Procedures) --> DataSet (automatisch erstellt) --> Klasse BannerAds bzw TextlinkAds

die beiden Klassen sind von der abstrakten Klasse AdsDB (definiert Insert, Delete, SelectAll) abgeleitet und benutzen das Interface IRotatableAds (nur die Methode GetNewAd).

in meinem Control rufe ich dann die GetNewAd auf und bekomme nen DataRow wieder...da lese ich dann die Werte aus und füge sie wieder auf Grundlage von AdType in die Webseite ein (halt entweder normaler Textlink oder ImageLink erzeugen).

            switch (adType)
            {
                case AdType.Banner:
                    ShowBanner();
                case AdType.Textlink:
                    ShowTextlink();
                    break;
                default:
                    ShowBanner();
                    break;
            }

in ShowBanner oder Textlink passiert dann halt alles -🙂

also was ich net so toll finde bzw net verstehe ist:
Ich muss trotz Interface und Abstrakter Klasse für jedes Ad ne neue Klasse machen weil sich das DataSet immer ändert...gibts da ne Möglichkeit das zu ändern? und dann sehe ich kein Vorteil darin mit der Klassenstruktur so zu arbeiten...könnte man doch einfach 2 Klassen BannerAd und TextlinkAd machen und dann darauf in ShowBanner/Textlink drauf zu greifen, auch ohne dass die von einer gemeinsamen Klasse gesagt bekommen, dass sie die gleiche Struktur haben sollen -🙂

EDIT: achso:
und wie man erreichen kann, dass der Weg vom Control bis zur Auslese der Daten eigentlich bei jeder Werbungsart die gleiche ist und ich nicht immer für die beiden oder halt 3 immer das gleiche Schreiben muss -🙂 BannerAd und TextlinkAd sind vom Aufbau gleich (es wird nur auf eine andere Tabelle in der Datenbank zugegriffen sonst ist es das selbe) und auch ShowBanner und ShowTextlink sind gleich (unterscheiden sich nur in der unterschiedlichen Ausgabe der Daten)
weiß aber nicht wie ich das erreichen kann!

wie ihr merkt bin ich leicht verwirrt gerade^^

ups ist ja ziehmlich lang geworden...hoffe trotzdem dass sich jemand die Mühe macht udn das sich durchliest 🙂

3.170 Beiträge seit 2006
vor 17 Jahren

Ich würde das so machen:
Das Interface IRotatableAds


public AdType Type
{
  get;
}

void BuildNewAd(RotateAds myControl);

Die Implementierung von BuildNewAd erfolgt dann in den DataSet-Klassen und kann die Funktion von GetNewAd() mit der zum jeweiligen DataSet passenden Formatierung der übergebenen Control kombinieren.
Die DataSets müssen in der Implementierung der Property "Type" den jeweils passenden Typ zurückliefern.

Dann kannst Du eine Liste aller DataSets erstellen (evtl. static), und zwar als IRotatableAds, also wie folgt:


public static List<IRotatableAds> adsList;

Dieser Liste fügst Du die DataSets durch AdsList.Add(dataSet) an.

Dann kannst Du schließlich in deiner Control folgendes tun:


foreach(IRotatableAds ads in adsList)
{
  if(ads.Type == adType)
  {
    ads.BuildNewAd(this)
  }
}

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

A
altertoby Themenstarter:in
61 Beiträge seit 2005
vor 17 Jahren

Danke für deinen Vorschlag Stein, aber ich hab ihn jetzt nicht verwendet, da dort die Anzeige mit dem BusinessLogicLayer vermischt wird (du gibts ja ein Control an die BBL).

Naja hab jetzt weiter rumexperimentiert und das ist dabei rausgekommen:
Ich erzeuge eine Instanz von RotatableAds (ist jetzt ne Klasse die nur noch vom Interface Ads abgeleitet wird) mit einem ganz bestimmten AdTyp.
Aber beim Erzeugen der Methoden komm ich irgendwie net weiter!

Also alle von VS automatisch erzeugten Klassen (fürs DataSet) werde ich so bennen:
Ads_ADTYPETableAdapters.Ads_ADTYPE_TableAdapter (bzw das macht VS dann so)

also hab ich nach einer Möglichkeit gesucht mit dem String von AdType auf die Methoden zuzugreifen:

            Type typ = Type.GetType("Ads_BannerTableAdapters.Ads_Banner_TableAdapter");
            object obj = Activator.CreateInstance(typ);
            MethodInfo method = typ.GetMethod("GetBannerNotInReloadBan"); 
            Object[] paras = {Ip, Convert.ToByte((int)AdKind)};
            return (DataRow)method.Invoke(obj,paras);

(noch Hardgecodet zum Testen)

das Prob ist ich bekomme nen Timeout heul
also die Frage, muss ich zuerst die Klasse instanzieren um auf die Methode draufzugreifen zu können?

das ist der Code direkt auf Banner bezogen:

        public static Ads_Banner.Ads_BannerRow GetFirstBannerNotInReloadBan(string Ip, BannerKind Kind)
        {
            using (Ads_Banner_TableAdapter db = new Ads_Banner_TableAdapter())
            {
                return GetFirstRow(db.GetBannerNotInReloadBan(Ip, Convert.ToByte((int)Kind)));
            }
        }

wobei das GetFirstRow weggelassen werden kann.

und das ist von VS so erstellt:

        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
        [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, false)]
        public virtual Ads_Banner.Ads_BannerDataTable GetBannerNotInReloadBan(string UserIP, System.Nullable<byte> Kind) {
            this.Adapter.SelectCommand = this.CommandCollection[6];
            if ((UserIP == null)) {
                this.Adapter.SelectCommand.Parameters[1].Value = System.DBNull.Value;
            }
            else {
                this.Adapter.SelectCommand.Parameters[1].Value = ((string)(UserIP));
            }
            if ((Kind.HasValue == true)) {
                this.Adapter.SelectCommand.Parameters[2].Value = ((byte)(Kind.Value));
            }
            else {
                this.Adapter.SelectCommand.Parameters[2].Value = System.DBNull.Value;
            }
            Ads_Banner.Ads_BannerDataTable dataTable = new Ads_Banner.Ads_BannerDataTable();
            this.Adapter.Fill(dataTable);
            return dataTable;
        }

(also DataTable wird eigetnlich zurückgegeben...aber bekomme schon ne Timeout Fehler im Watch wenn ich das oben getestet hab!

Hoffe ihr könnt mir helfen wie man das am besten löst...sonst funz alles und ich will nicht in jeder Methode ne switch Schleife haben wo alles fest drinne steht! (vllt. kann mans auch mit Delegates Lösen, oder? )

L
667 Beiträge seit 2004
vor 17 Jahren

und wie man erreichen kann, dass der Weg vom Control bis zur Auslese der Daten eigentlich bei jeder Werbungsart die gleiche ist und ich nicht immer für die beiden oder halt 3 immer das gleiche Schreiben muss -smile BannerAd und TextlinkAd sind vom Aufbau gleich (es wird nur auf eine andere Tabelle in der Datenbank zugegriffen sonst ist es das selbe)

Suche dazu mal bei google nach dem Stichwort "Vererbung" - das sollte Dich weiter bringen.

"It is not wise to be wise" - Sun Tzu

A
altertoby Themenstarter:in
61 Beiträge seit 2005
vor 17 Jahren

Original von Lynix

und wie man erreichen kann, dass der Weg vom Control bis zur Auslese der Daten eigentlich bei jeder Werbungsart die gleiche ist und ich nicht immer für die beiden oder halt 3 immer das gleiche Schreiben muss -smile BannerAd und TextlinkAd sind vom Aufbau gleich (es wird nur auf eine andere Tabelle in der Datenbank zugegriffen sonst ist es das selbe)

Suche dazu mal bei google nach dem Stichwort "Vererbung" - das sollte Dich weiter bringen.

ich bedanke mich für den sehr aufschlußreichen Tipp, jetzt hab ich absolut keine Probleme alle meine Probleme zu lösen! THX!

und ich bitte dich mal zu überlegen ob es nicht angebracht wäre den ganzen Thread zu lesen!

P.s: Vererbung hatten wir gerade in der Schule...und ich kann da jetzt nicht ganz den Zusammenhang zw. DNA und m-RNA und t-RNA ect. mit Werbung verbinden...ich frag mal morgen meinen Bio Lehrer

L
667 Beiträge seit 2004
vor 17 Jahren

Wenn Du immer so reagierst, wenn Dir jemand helfen will, dann möcht ich nicht Dein Lehrer sein 🙂

Vererbung ist genau das Mittel um die von Dir beschriebene Struktur zu realisieren.

der Weg vom Control bis zur Auslese der Daten eigentlich bei jeder Werbungsart die gleiche ist und ich nicht immer für die beiden oder halt 3 immer das gleiche Schreiben muss -smile BannerAd und TextlinkAd sind vom Aufbau gleich (es wird nur auf eine andere Tabelle in der Datenbank zugegriffen sonst ist es das selbe)

Bevor Du also drei Mal die selben Funktionen auf dieselbe Art und Weise implementierst solltest Du eine Basisklasse anlegen, die diese Funktionen einmal definiert, und all deine spezielleren Typen (BannerAd, TextlinkAd) erben dann von dieser Basisklasse. Da ihr ja gerade Vererbung in der Schule gelernt habt, dürfte das doch kein großes Problem sein oder ?

"It is not wise to be wise" - Sun Tzu

A
altertoby Themenstarter:in
61 Beiträge seit 2005
vor 17 Jahren

mhhh nur wenn mir jemand nen wort an den Kopf knallt reagiere ich so (besonderns wenn es schon deutlich wird, dass ich weiß worum es sich dabei handelt)...sorry und schwamm drüber 🙂

also ich weiß schon was Vererbung ist, ABER ich weiß nicht wie ich eine Basisklasse realisieren soll, da immer auf andere Objekte zugegriffen wird, aber der Zugriff an sich ist immer der selbe!

z.b.:

public static Ads_Banner.Ads_BannerRow GetFirstBannerNotInReloadBan(string Ip, BannerKind Kind)
        {
            using (Ads_Banner_TableAdapter db = new Ads_Banner_TableAdapter())
            {
                return GetFirstRow(db.GetBannerNotInReloadBan(Ip, Convert.ToByte((int)Kind)));
            }
        }

und

public static Ads_Textlink.Ads_Ads_TextlinkRow GetFirstAds_TextlinkNotInReloadBan(string Ip, BannerKind Kind)
        {
            using (Ads_Ads_Textlink_TableAdapter db = new Ads_Ads_Textlink_TableAdapter())
            {
                return GetFirstRow(db.GetAds_TextlinkNotInReloadBan(Ip, Convert.ToByte((int)Kind)));
            }
        })

das ist mein Problem, welches ich mit Reflection lösen wollte, aber nur nen TimeOut bekamm! (s. Code unten)

L
667 Beiträge seit 2004
vor 17 Jahren

Tja, auch auf die Gefahr hin mich zu wiederholen, Vererbung ist das Zauberwort. Leite deine Klassen Ads_Banner und Ads_Textlink von einer gemeinsamen Basisklasse ab und schon brauchst Du nur noch eine Funktion, der Du als Parameter ein Objekt der Basisklasse übergibst.

Falls Du mit .NET 2.0 arbeitest kannst Du auch eine generische Funktion daraus machen.

"It is not wise to be wise" - Sun Tzu