Designfrage => Informationhiding



  • Hallo Leute,

    ich habe eine Klasse Bar, diese enthält Objekte vom Typ Foo.
    Und auch nur Foo ist für Bar Bekannt (deswegen nested)
    Nach außen dürfen aber nur eigenschaften des IFoo bekannt sein,
    nur die klasse Bar Kenn "Foo" und arbeiet damit":

    Und so habe ich es mal pseude mässig umgesetzt:

    class Bar
    {
    
    class Foo : IFoo
    {
      public int A{get; set;}
      public int B{get; set;
    }
    
      private  List<Foo> _data = new List<Foo>();
    
      IFoo GetElementAt(int index)
    { 
    return _data.At(index);
    }
    
     public IFoo Create()
    {
     return new Foo();
    }
    
     public Add(IFoo foo)
    { 
     _data.Add((Foo)foo);
    }
    }
    
    interface IFoo
    {
      int A{get; set;}
    }
    

    Nun meine Frage, kann ich das Problem auch schöner lösen? Finde es etwas gehackt! 😃



  • sorry den code etwas schöner eingerückt:)

    class Bar
    	{
    
    		class Foo : IFoo
    		{
    			public int A { get; set; }
    			public int B
    			{
    				get;
    				set;
    			}
    
    			private List<Foo> _data = new List<Foo>();
    
    			public IFoo GetElementAt(int index)
    			{
    				return _data[index];
    			}
    
    			public IFoo Create()
    			{
    				return new Foo();
    			}
    
    			public void Add(IFoo foo)
    			{
    				_data.Add((Foo)foo);
    			}
    		}
    	}
    
    	public interface IFoo
    	{
    		int A { get; set; }
    	}
    


  • Fuck sorry 😞 hab ne block falsch gesetzt.. hier der code richtig:)

    class Bar
    	{
    		class Foo : IFoo
    		{
    			public int A { get; set; }
    			public int B
    			{
    				get;
    				set;
    			}
    		}
    
    		private List<Foo> _data = new List<Foo>();
    
    		public IFoo GetElementAt(int index)
    		{
    			return _data[index];
    		}
    
    		public IFoo Create()
    		{
    			return new Foo();
    		}
    
    		public void Add(IFoo foo)
    		{
    			_data.Add((Foo)foo);
    		}
    	}
    
    	public interface IFoo
    	{
    		int A { get; set; }
    

    }



  • Ich finde es ganz in Ordnung. Man verzichtet oft darauf, dass man komplexe Klassen ineinander verschachtelt, sondern packt die irgendwo in nach aussen nicht sichtbare pakages, aber sonst ist das design in Ordnung mit Ausnahme dieser Methode:

    NullBockException schrieb:

    [code="cs"]
    public void Add(IFoo foo)
    {
    _data.Add((Foo)foo);
    }

    Es gibt keinen Grund, warum man extern erzeugte Objekte einfuegen sollte, denn fuer diesen Fall hat man Create.
    Explizites casten ist boese und macht Compilezeit- zu Laufzeitfehlern.



  • Hi Marthog ,

    Danke für deine Antwort!

    Leider muss ich das so machen!

    Grund:

    Ich will Objekte nachträglich in die Liste "eingliedern" eigentlich müsste die Methode ehr "Enqueue" heisen! Und eine "Dequeue" Methode soll es wieder ausgliedern!

    Deswegen der unschöne Cast! Die Create-Methode zu nicht explizit das Element in die liste packen, sonder nur erzeugen!

    Der Cast sorgt auch dafür, dass keine anderen Objekte die "IFoo" implementieren eignedliedert werden könenn, da NUR "Foo" die nötigen Eigenschafte hat, damit Bar amit arbeiten kann! Diese Eigenschaften sollen eben nach außen unsichtbar bleiben!:)

    Grüßle



  • Dann verstehe ich den Sinn des Interfaces nicht.
    Mach Foo zum friend von Bar damit Bar auf die ganzen "geheimen" Funktionen zugreifen kann und gib dem Anwender direkt echte Foos.

    Oder warum trennst du hier mit IFoo auf?



  • Ja statt IFoo kann ich auch ein FooBase machen!

    nach aussen sollen nur die Eigenschaften, von FooBase bekannt sein,

    Bar benötigte aber noch weitere Eigeschaften (zur verwaltnung), die direkt mit FooBase (Instanz) verknüpft sein sollen!

    class FooBar : FooBase
    {
       pulic BarUsedProperty{get;}
    }
    

    Auén darf aber die Eigenschaft "BarUsedProperty" nich sichtbar oder veränder bar sein, weil diese nur von Bar angefasst werden soll!

    nach außen ist so nur FooBase bekannt...

    ich könnte auch einfach FooBar nach außen bekannt machen, und auf ein private feld "BarUsedProperty" via Reflection zugreifen, aber das is uncool...oder?



  • Ich werd bisschen Konkrete, damit ihr das Problem seht!

    Ich habe Objekte (Foo) , die ich in eine verkette Liste (Bar) eingliedern wird, und auch wieder ratzfatz ausgliedern will!

    Deswegen spendiert ich jeder Foo instanz einen Pointer (LinkedListNode<Foo>) auf die eigene pos. in der liste !! speichert!

    so kann ich später beim ausgliedern eines Foo Objekts aus Bar, direkt den Pointer nehemen, was ja viel effizienter ist als wenn ich Remove(Foo) mache!

    Die Liste hat sehr sehr viel Foo elemente und ich werde auch sehr oft ein und ausgliedernt..

    so sovuel zum kontext;)

    Und nach außen darf eben der Pointer nich angefasst werden!



  • private machen?

    PS:
    Oder Adapater verwenden

    Interfaces sind dafür da viele unterschiedliche Objekte gleich ansprechen zu können. Und das willst du hier ja scheinbar nicht. Also ist ein Interface unpraktisch.



  • Habe das ganze jetzt einfach in eine andere Assembly gepackt,
    und die Eigenschaften mit "internal" markiert, die nach außen unbekannt sind

    😉


Anmelden zum Antworten