Announcement

Collapse
No announcement yet.

OOA-Muster wechselnde Rollen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • OOA-Muster wechselnde Rollen

    Hallo zusammen,

    Ich bin neu hier, habe aber direkt eine Frage.
    Folgende Problemstellung:

    In einer Applikation soll ein Benutzer-Objekt in Bezug zu einem Runden-Objekt verschiedene Rollen einnehmen können. Das Entwurfsmuster "wechselnde Rollen scheint mir für diesen Zweck gut geeignet. Wenn ich es richtig verstanden habe, dann werden die verschiedenen Rollen dazu benutzt dem Benutzer-Objekt auch verschiedene Arten der Interaktion mit anderen Business-Objekten zu ermöglichen, was sich in der implementierung durch Methoden die die Rolle zur Verfügung stellt niederschlägt. Jetzt meine Hauptfrage. Wie stelle ich hinterher eine Verbindung des UIs mit diesem Muster her? Mir ist noch nicht ganz klar, wie ich entsprechend der Rolle die ein Benutzer hat auch dafür Sorge, dass ihm mehr, weniger oder unterschiedliche Aktionen zur Verfügung stehen.

    Vielen dank schonmal für Antworten.
    „If there's more than one possible outcome of a job or task, and one of those outcomes will result in disaster or an undesirable consequence, then somebody will do it that way.“

    Murphys law

  • #2
    Das klingt jetzt wohl etwas naiv, aber kannst Du nicht einfach im Presenter die verschiedenen Rollen abfragen und dann über view.EnableRollenControls die Controls dem View hinzufügen bzw. sichtbar machen?
    Oder Du baust Dir eine Factory die Dir je nach übergebener Rolle ein Usercontrol zurückgibt welches Du in Deine UI einbauen. Allerdings kommts da auch auf die komplexität der UI an.

    Man möge mir verzeihen, wenn das etwas naiv erscheint Hab auch erst vor kurzem so richtig mit OOP gestartet

    Comment


    • #3
      Hallo fanderlf danke für die Antwort.

      So naiv klingt das nicht mal. So etwas wie die Abfrage Lösung habe ich mir auch überlegt, nur dass ich mir nicht sicher bin, ob das der beste Weg ist. Die Idee mit der Factory finde ich gut. Für meinen Fall ist das glaube ich nicht das geeignete, da ich ein JSF-frontend habe und glaube, dass ein Weg, der über die navigation-control funktioniert besser geeignet ist. Was jetzt aber nicht bedeutet, dass ich eine Lösung speziell für dieses Pattern in Verbindung mit JSF suche.
      Ich bin für jede Idee dankbar, denn mein Problem ist nicht, dass ich die Verbindung garnicht hinkriegen würde, sondern dass ich gerne einen Weg gehen würde, der einem Idiom entspricht. Kennt vielleicht noch jemand ein Pattern für diese Situation?
      „If there's more than one possible outcome of a job or task, and one of those outcomes will result in disaster or an undesirable consequence, then somebody will do it that way.“

      Murphys law

      Comment


      • #4
        In ASP.NET habe ich so etwas ähnliches auch schon programmiert, allerdings über den eingebauten Mechanismus der MembershipProvider und den dazu passenden Controls. Dort konnte man Seitenbereiche definieren die nur sichtbar sind, wenn dem Benutzer eine bestimmte Rolle zugeordnet ist.
        Allerdings kenne ich mich da in der Java Welt leider gar nicht aus.

        Comment


        • #5
          So etwas gibt es auch in der JavaEE. Es ist möglich Rollen zu definieren und nur gewissen Rollen Zugriff auf Methoden zu geben. Das bezieht sich aber mehr auf die Sicherheitskonzepte der JavaEE. Allerdings ist dies nicht das was ich will. Ich saug mir mal ein Beispiel aus den Fingern.

          Das Beispiel ist einfach und Bedarf nicht unbedingt des Einsatzes des Patterns "wechselnde Rollen", aber soll mir jetzt mal zur Veranschaulichung dienen.

          Wir gehen mal von einem Chat aus. Benutzer können einen Channel erstellen, einem vorhandenen Channel beitreten und einen Channel dem sie beigetreten sind wieder verlassen. Ein Benutzer der einem Channel beigetreten ist, kann die normale Chatfunktion im Channel nutzen. Der benutzer der den Channel erstellt hat kann dies auch und darüber hinaus kann er auch andere Benutzer im Channel kicken, muten, etc. und den Channel schließen. Ein Benutzer kann also in Bezug auf einen Channel die Rolle ChannelAdmin oder ChannelUser einnehmen (Gibt bestimmt bessere Namen für die Rollen, aber egal). Ein ChannelAdmin kann andere Benutzer auch in den Status ChannelAdmin erheben, wodurch sich die Rolle des Benutzers in diesem Chat ja ändert. So wie die Beschreibung des Pattersn "wechselnde Rollen" aussieht, sollten jetzt die Rollen die Methoden zur verfügung stellen, als Delegationmethods die einen Controller ansprechen.

          So ungefähr stelle ich mir das vor. Jetzt sagen wir mal, dass der Chat nur ein Teil der gesamten Applikation ist. Für andere Funktionen der Applikation nimmt ein Benutzer andere Rollen in Bezug auf andere BusinessObjekte ein.

          Deshalb sind es also keine Appplikationsweiten Security Roles wie sie in der JavaEE in einem Deploymentdescriptor oder per Annotations zu definieren sind und ich kann die eingebauten Mechanismen der JavaEE nicht nutzen. Es sei denn ich übersehe da was. Lasse mich auch gerne korrigieren.
          „If there's more than one possible outcome of a job or task, and one of those outcomes will result in disaster or an undesirable consequence, then somebody will do it that way.“

          Murphys law

          Comment


          • #6
            Aber kannst Du das nicht einfach im Presenter entscheiden? Der Presenter frägt beim Aufbau des Views nach ob der Benutzer z.B. ChannelAdmin ist, wenn ja dann setzt er das grafische Control für Channel administration.
            Modell und View sollten ja sowieso getrennt sein. Also weiss deine Benutzeroberfläche nichts über das Modell. Deswegen erschließt sich mir das nicht so ganz warum man das direkt miteinander koppeln sollte.
            Der Presenter hängt sich per Observer auf das Modell und sobald sich was an den Rechten ändert teilt es dies dem View mit indem dort eine Funktion aufgerufen wird.

            Aber wie gesagt ich kenne den Basisansatz von JSF nicht... kann auch sein, dass es dort anders läuft (was ich mir aber nur schwerlich vorstellen )

            Comment


            • #7
              Wieso direkt miteinander koppeln? Das will ich ja gar nicht.
              Hier mal eine Beschreibung des Musters.
              http://www.inf.fu-berlin.de/lehre/WS...llenmuster.pdf
              „If there's more than one possible outcome of a job or task, and one of those outcomes will result in disaster or an undesirable consequence, then somebody will do it that way.“

              Murphys law

              Comment


              • #8
                Hm so wie ichs verstanden hab hast Du das role pattern verstanden und versucht nun das ganze in dein UI zu packen
                Geht's dir drum wie du das rollenumster umsetzen sollst?

                Comment


                • #9
                  Nein, nein. Das Rollenmuster hab ich verstanden. Mir gehts schon darum wie ich meine UI so baue, dass ich nutzen aus dem Muster ziehe. Vielleicht drück ich mich falsch aus.
                  Ich hätt wohl gerne mal nen ganz konkreten Vorschlag wie die UI anzubinden ist.
                  „If there's more than one possible outcome of a job or task, and one of those outcomes will result in disaster or an undesirable consequence, then somebody will do it that way.“

                  Murphys law

                  Comment


                  • #10
                    Model-View-Presenter sagt Dir aber schon was, oder?
                    Code:
                    interface IChatView
                    {
                      void EnableAdminButtons();
                      int GetUserId();
                    }
                    
                    class ChatView implements IChatView
                    {
                      ChatPresenter _presenter;
                      int _userId;
                    
                      public ChatView(int userId)
                      {
                        _presenter = new ChatPresenter(this);
                        _userId = userId;
                      }
                    
                      public void EnableAdminButtons()
                      {
                        _btnPromoteUser.Visible = true;
                      }
                    
                      public int GetUserId()
                      {
                        return _userId;
                      }
                    }
                    
                    class ChatPresenter
                    {
                      IChatView _view;
                      IUserDal _dal;
                    
                      public ChatPresenter(IChatView view)
                      {
                        _view = view;
                        _dal = new UserDal(); //normalerweise nicht die konkretet Implementierung angeben, sondern über dependency injection injizieren
                        CreateView();
                      }
                    
                      void CreateView()
                      {
                        User user = _dal.GetUser(_view.GetUserId());
                        
                        if(user.IsInRole("Admin"))
                          _view.EnableAdminButtons();
                      }
                    }
                    If hoffe damit kannst Du was anfangen

                    Comment


                    • #11
                      jap, das MVC-Pattern ist mir auch ein Begriff und das verwende ich ja auch. deshalb redete ich ja davon, dass ich ein Controller die Methoden der Rollen aufruft.
                      Also würdest du die Rollen über namen identifizieren? Das hab kam mir auch in den Sinn, finde ich aber nicht so gut. Java speziefisch könnte man ja das Reflection-API verwenden um und eine instanceof prüfung machen. Aber das ist ja auch wieder sehr java speziefisch. Oder ich gehe über Objektidentitäten. Was wäre deiner Meinung nach die beste Variante?
                      „If there's more than one possible outcome of a job or task, and one of those outcomes will result in disaster or an undesirable consequence, then somebody will do it that way.“

                      Murphys law

                      Comment


                      • #12
                        OK das ist wieder ein anderes Thema... Ich nehme an jede Rollenklasse hat ein zugehöriges Interface. Und dann würde ich prüfen ob die Liste der Rollen das gewünschte Interface enthält (natürlich sollte das gleiche Interface nicht 2 mal in der Liste sein - macht aber auch keinen Sinn ). Aber die Entscheidung kannst Du ja der Klasse überlassen. Sowas in der Art eben:
                        Code:
                        class User
                        {
                          public bool IsInRole(Type roleInterface)
                          {
                            //wenn _roles eine Implementierung von roleInterface enthält
                            return true;
                            else
                            return false;
                          }
                        }
                        Wobei mir das auch nicht wirklich gut gefällt.

                        Vielleicht sowas in der Richtung:

                        Code:
                        enum UserRoleType
                        {
                          User,
                          Admin,
                        }
                        
                        interface IRole
                        {
                          UserRoleType GetUserRoleType();
                        }
                        
                        interface IUserRole extends IRole
                        {
                          //UserMethoden
                        }
                        
                        interface IAdminRole extends IRole
                        {
                          //AdminMethoden
                        }
                        Dann kannst in deinem User Objekt eine generische List über IRole anlegen. Schon mal besser als eine ArrayList über Objects. Spart ein paar Casts.
                        Verwenden kannst dass dann so:

                        Code:
                          class User
                          {
                             public bool IsInRole(UserRoleType type)
                             {
                               foreach(IRole role in _roles)
                                if(role.GetUserRoleType() == type)
                                 return true;
                              
                                return false;
                             }
                          }
                        
                          if(User.IsInRole(UserRoleType.Admin)
                            //Admin Geschichten setzen
                        Sorry ist jetzt bissl Java/C# mischmasch... aber ich denke du erkennst was ich meine

                        Comment


                        • #13
                          Ja doch. Ich erkenne was du meinst. Ja die Lösung mit den Interfaces gefällt mir. Danke für die Unterstützung. Hast mir gut weitergeholfen.
                          „If there's more than one possible outcome of a job or task, and one of those outcomes will result in disaster or an undesirable consequence, then somebody will do it that way.“

                          Murphys law

                          Comment

                          Working...
                          X