Designfrage , Objekte erzeugen nach Bedingung



  • Hallo Leute,

    folgender Umstand:

    Ich habe diverse Typen, die unter best. Bedingung erzeugt werden sollen!

    Die Bedingung bzw. dessen Logik ob ein Object eines best. Types erzeugt werden soll steckt im objekt selber.

    Pseudo:

    Interface ICondition
    {
       bool isValid(Condext bla);
    }
    
    class Foo : ICondition
    {
       bool IsValid(Condext bla)
      {
         // logik ob foo für Context bla gilt
      }
    }
    
    class Bar : ICondition
    {
       bool IsValid(Condext bla)
      {
         // logik ob Bar für Context bla gilt
      }
    }
    

    Nun muss ich das Object erst erzeuigen, damit ich mit IsValid prüfen kann ob es in frage kommt!
    Um das zu umgehen, müsste ich für jeden Typ , also für Foo und Bar die Logik auslagern, dafür bräuchte ich aber zu jedem Typ ein weiter Typ der die Logik enthält als quasi Typ Meta Infos!

    Gibt es eine weiter Option diese Problem zu umgehen?

    Hoffe ihr könnt mir folgen 🤡



  • NullBockException schrieb:

    Gibt es eine weiter Option diese Problem zu umgehen?

    Eine Objektfabrik die abhängig von den Bedingungen die Objekte erzeugt?



  • Richtig, sowas in der Art habe ich auch!
    Allerdings würde ich gern die Erzeugungs-Bedingung (Logik) fest mit dem Typ definiert im Verbund haben, sonst bräuchte ich für jeden Typ noch eine extra extra von außen gegeben bedingung logik!

    Pseudo bsp. C#:

    class Logic<T>
      where T: class
    {
       public Logic(Func<Context, bool> condition)
    {
    _condition= condition;
    }
     private Func<Context, bool> _condition
       T Create(Context context)
       {
        if(_condition(context))
          return Activator.createInstance<T>();
       }
    }
    
      var l=  new Logic<Bar>((context)=> /* logic */);
    
       var obj= l.Create(...);
    

    in dem Fall erzeuge ich das Objkect er wenn die Bedigung true ist, aller ding is das die Bedinung nich direkt mit dem Typ Bar gekoppelt, was ich gerne hätte!
    Aber denke das geht nich.. via reflections könnte ich meta infos nutzen, aber in Attribute bekomme ich ja keine "logic" reine nur werte...

    Danke



  • NullBockException schrieb:

    Richtig, sowas in der Art habe ich auch!
    Allerdings würde ich gern die Erzeugungs-Bedingung (Logik) fest mit dem Typ definiert im Verbund haben,

    Solange man in Interfaces keine statischen Methoden vorgeben kann, sehe ich keine Chance dies ohne die Objekterzeugung in einer generischen Methode zu machen (Oder man muss per Reflection diese statischen Methoden ansprechen, performant ist sicherlich etwas anderes...).



  • Eben daran hatte ich auch schon gedacht:)

    Hmm.. maja aber ob es performanter ist, daa object zu erzeugen, und wenn es nich gültich ist direkt wieder zu verwerfen! ?

    Grüße und Danke



  • erstmal wuerde ich bei den objekten die initialisierung aufteilen in einen teil den zu zur validierung brauchst und den teil der den rest initialisiert, dann genug speicher allokieren fuer das groesste objekt und dann mit in-placement new durch die objekte durchgehen und instanzieren, validieren, falls mal ein valid true liefert, init vom rest des objektes aufrufen und den pointer zurueckliefern.



  • Hey raspo,

    erstmal wuerde ich bei den objekten die initialisierung aufteilen in einen teil den zu zur validierung brauchst und den teil der den rest initialisiert, dann genug speicher allokieren fuer das groesste objekt und dann mit in-placement new durch die objekte durchgehen und instanzieren, validieren, falls mal ein valid true liefert, init vom rest des objektes aufrufen und den pointer zurueckliefern.

    gute Idee.. so mach ich das sogar, außer mit der allokation und in-placement new , das würde dann nur in unmanaged bzw. c++ gehn:)

    Danke



  • NullBockException schrieb:

    ...außer mit der allokation und in-placement new , das würde dann nur in unmanaged bzw. c++ gehn:)

    das war mein hauptaugenmerk ;), so kannst du quasi einen static call emulieren mit einer initialisierung, aber ohne overhead, da du nur einmal allokierst wie du es auch machen wuerdest wenn du es mit zwei objekten implementieren wuerdest.

    was du noch machen koenntest waere eine 'clone' funktion, du wuerdest das objekt selbst als faktory regestrieren (also von jedem typ eine instanz) und wenn die instanz valid ist, rufst du 'clone' auf.



  • Guten Morgen,

    ja Clone wäre auch noch ne gute Idee, hast recht!

    Anstatt "this" zurückzugeben "clone()" aufrufen, hmm aber das kostet evtl. mehr performance!?



  • NullBockException schrieb:

    ... hmm aber das kostet evtl. mehr performance!?

    sollte eigentlich schneller sein, weil du die objekte ja nicht mehr auf verdacht erzeugst, dann in valid false lieferst und deletest, sondern einmal quasi den 'prototype' hast und falls 'valid' true ist, es clonst. damit solltest du also wirklich nur ein einziges mal fuers richtige objekt instanzieren.


Anmelden zum Antworten