Basé sur un rôle de programmation en gras
Un exemple de mise en œuvre de l'Acteur/Rôle de modèle en Gras.
basées sur le Rôle de la programmation en Gras
Gras permet aux développeurs de développer des applications de la programmation orientée objet qui persistent à une base de données. Cela nous donne la possibilité d'ajouter de l'héritage à nos applications, mais cette capacité peut être plus utilisé.
par exemple, dans une application que j'ai développé en Gras une fois que j'avais le modèle suivant
La structure ci-dessus permet à l'application d'enregistrement des ordres d'achat à l'encontre d'un Client, le travail d'administration peut être attribué à une AdminEmployee, et de vol d'informations peuvent être enregistrées à l'encontre d'un Pilote.
basé sur un Rôle
Le problème avec le scénario ci-dessus est quand les rôles commencent à se mêler. Par exemple, un Employé peut devenir un Client, ou un Pilote peut faire une partie-gestion du temps de travail.
La solution à ce problème est l'utilisation de l'Acteur/Rôle de modèle. Chaque Acteur (classe abstraite) peut recevoir de multiples Rôles (aussi une classe abstraite). Il est de ces Rôles qui ont les affaires liées à des informations qui leur sont associés. Par exemple, un PilotRole aurait le vol d'informations associés, et la CustomerRole aurait des ordres d'achat associés.
Le nouveau modèle devrait ressembler à quelque chose comme ceci.
- Un Acteur peut ne pas avoir de rôles, ou de nombreux rôles.
- Une instance spécifique d'un Acteur, d'interdire la suppression d'un rôle.
- Un rôle peut refuser la demande d'un Acteur en particulier.
- Un rôle peut spécifier qu'il est nécessaire et ne peut pas être supprimé (c'est à dire, LoginRole ne peut pas être supprimé parce que l'utilisateur a aussi un SystemAdministratorRole)
- Une instance spécifique d'un Acteur peut rejeter un rôle.
Liste 1: l'Acteur
//Accepter ou de refuser un rôle fonction de TActor.CanAcceptRole(ARoleClass: TRoleClass): Boolean begin si non ARoleClass.AllowDuplicates et HasRole(ARoleClass, nil) then Result := False else si non ARoleClass.AllowActiveDuplicates et HasActiveRole(ARoleClass, nil) then Result := False else Result := ARoleClass.CanApplyTo(Auto) fin
//d'Autoriser ou d'interdire la suppression d'un rôle fonction de TActor.CanRemoveRole(ARole: TRole): Boolean begin Result := pas d'ARole.IsRequired fin
//Retourne un rôle, mais seulement si elle est active fonction de TActor.FindActiveRole(Classe: TClass ExcludeInstance: TRole): TRole var I: Integer begin Résultat := nil for I := 0 to Rôles.Count - 1 do si les Rôles[I].Active et (Rôles[I].ClassType = Classe) et (Rôles[I] <> ExcludeInstance) begin Result := Rôles[I] Break fin fin
//Retourne un rôle, qu'elle soit active ou pas fonction de TActor.FindRole(Classe: TClass ExcludeInstance: TRole): TRole var I: Integer begin Résultat := nil for I := 0 to Rôles.Count - 1 do if (Rôles[I].ClassType = Classe) et (Rôles[I] <> ExcludeInstance) begin Result := Rôles[I] Break fin fin
//Retourne Vrai si l'Acteur possède un rôle spécifique et il est actif fonction de TActor.HasActiveRole(Classe: TClass ExcludeInstance: TRole): Boolean begin Résultat := Assigné(FindActiveRole(Classe, ExcludeInstance)) fin
//Retourne Vrai si les Acteurs possède un rôle spécifique (actif ou inactif) fonction de TActor.HasRole(Classe: TClass ExcludeInstance: TRole): Boolean begin Résultat := Assigné(FindRole(Classe, ExcludeInstance)) fin
fonction de TActor.ReceiveQueryFromOwned(Auteur: TObject OriginalEvent: TBoldEvent const Args: array de const Abonné: TBoldSubscriber): Boolean var ObjectLocator: TBoldObjectLocator Rôle: TRole begin Result := hérité ReceiveQueryFromOwned(Initiateur, OriginalEvent, Args, l'Abonné) si pas de Résultat ou de BoldObjectIsDeleted puis Sortie //Vérifier pour l'insertion des rôles if (Auteur = M_Roles) puis begin si OriginalEvent = bqMayInsert puis begin //Obtenir le rôle inséré Assert(Args[1].VType = vtObject) ObjectLocator := (Args[1].VObject comme TBoldObjectLocator) Rôle := (ObjectLocator.BoldObject comme TRole) //Vérification des doublons des rôles qui ne sont pas autorisés si (pas de Rôle.AllowDuplicates) et (HasRole(Rôle.ClassType, nil)) begin Result := False SetBoldLastFailureReason( TBoldFailureReason.Create('Ce rôle ne peut être appliqué qu'une fois', Self) ) else //Vérification des doublons des rôles actifs qui ne sont pas autorisés si (pas de Rôle.AllowActiveDuplicates) et (HasActiveRole(Rôle.ClassType, nil)) puis begin
Result := False SetBoldLastFailureReason( TBoldFailureReason.Créer ('Impossible d'appliquer ce rôle parce que' 'il y a déjà un rôle actif de cette nature', l'Auto) ) else Result := CanAcceptRole(TRoleClass(Rôle.ClassType)) si pas de Résultat, alors SetBoldLastFailureReason( TBoldFailureReason.Créer (Rôle ne peut pas être appliquée à cet objet', Self) ) fin du else //bqMayInsert //Vérification de la suppression de rôles si OriginalEvent = bqMayRemove puis begin //Récupère le rôle de l'objet supprimé Assert(Args[0].VType = vtInteger) Rôle := Rôles[Args[0].VInteger] Result := (pas de Rôle.Active) ou (pas de Rôle.IsRequired) si pas de Résultat, alors SetBoldLastFailureReason( TBoldFailureReason.Créer (Rôle ne peut pas être supprimé, ' 'il est requis par un autre rôle actif', Self) ) fin //bqMayRemove fin fin |
Liste 2: Rôle
//Autoriser ou d'interdire l'application d'un Acteur en particulier fonction de classe TRole.CanApplyTo(AObject: TActor): Boolean begin Result := False fin
//méthode Virtuelle à remplacer dans des descendants qui décrit le rôle fonction de classe TRole.GetRoleName: string begin Result := ' fin
//Optionnel, spécifie si active, les doublons sont autorisés ou pas fonction de classe TRole.AllowActiveDuplicates: Boolean begin Result := False fin
//Optionnel, spécifie si les doublons sont autorisés ou non (actif ou inactif) fonction de classe TRole.AllowDuplicates: Boolean begin Result := False fin
//Retourne Vrai si l'un rôle dépend de ce rôle d'être présent fonction TRole.IsRequired: Boolean var I: Integer begin si l'Acteur <> nil then begin Result := True for I := 0 à l'Acteur.Les rôles.Count - 1 do si l'Acteur.Rôles[I] <> auto si l'Acteur.Rôles[I].RequiresRole(auto) Sortie fin Result := False fin
//Remplacer cette option pour spécifier si un autre rôle est tributaire de l' fonction TRole.RequiresRole(ARole: TRole): Boolean begin Result := False fin
//Remplit le dérivé RoleName attribut à partir de la méthode de classe procédure TRole._RoleName_DeriveAndSubscribe(DerivedObject: TObject Abonné: TBoldSubscriber) begin hérité M_RoleName.AsString := GetRoleName fin
//Empêche la suppression d'un rôle nécessaire fonction TRole.MayDelete: Boolean begin Result := pas IsRequired fin
fonction TRole.ReceiveQueryFromOwned(Auteur: TObject OriginalEvent: TBoldEvent const Args: array de const Abonné: TBoldSubscriber): Boolean begin Result := hérité ReceiveQueryFromOwned(Initiateur, OriginalEvent, Args, l'Abonné) si pas de Résultat, alors la Sortie if (Auteur = M_Active) puis //Active l'attribut begin si OriginalEvent = bqMayModify puis begin si l'Acteur = nil then Result := True else si Active, alors begin //Interdire la désactivation si un autre rôle il faut //cette rôle actif Résultat := pas IsRequired si pas de Résultat, alors SetBoldLastFailureReason( TBoldFailureReason.Créer ('Ne peut pas désactiver ce rôle,' 'autres rôles exigent', Auto) ) else begin //Interdire la réactivation si un autre rôle actif existe //et les doublons ne sont pas autorisés Result := AllowActiveDuplicates ou (pas l'Acteur.HasActiveRole(De Soi.ClassType, Auto)) si pas de Résultat, alors SetBoldLastFailureReason( TBoldFailureReason.Créer ('Impossible d'activer ce rôle' 'car il y a déjà une similaire rôle actif', Self) ) fin fin //bqMayModify fin //Active attributeend fin |
Le code jusqu'à présent, a été abrégé. Tout ce qui reste est de descendre certaines classes concrètes de l'Acteur et de son Rôle.
Conclusion
au Lieu d'avoir une classe Employé ou un Client de classe, nous pouvons maintenant facilement attribuer une EmployeeRole ou CustomerRole à tout type de Personne objet (qui est un Acteur).
en Outre, nous pouvons mélanger les rôles, un Pilote peut effectuer l'administration, et tout ce qui pourrait être un client (une Personne, un Service, une Entreprise, ou même d'un Pays).
j'espère que cet article a été instructif.
& nbsp
Base sur un role de programmation en gras
Base sur un role de programmation en gras : Plusieurs milliers de conseils pour vous faciliter la vie.
Un exemple de mise en œuvre de l'Acteur/Role de modele en Gras.
basees sur le Role de la programmation en Gras
Gras permet aux developpeurs de developper des applications de la programmation orientee objet qui persistent a une base de donnees. Cela nous donne la possibilite d'ajouter de l'heritage a nos applications, mais cette capacite peut etre plus utilise.
par exemple, dans une application que j'ai developpe en Gras une fois que j'avais le modele suivant
La structure ci-dessus permet a l'application d'enregistrement des ordres d'achat a l'encontre d'un Client, le travail d'administration peut etre attribue a une AdminEmployee, et de vol d'informations peuvent etre enregistrees a l'encontre d'un Pilote.
base sur un Role
Le probleme avec le scenario ci-dessus est quand les roles commencent a se meler. Par exemple, un Employe peut devenir un Client, ou un Pilote peut faire une partie-gestion du temps de travail.
La solution a ce probleme est l'utilisation de l'Acteur/Role de modele. Chaque Acteur (classe abstraite) peut recevoir de multiples Roles (aussi une classe abstraite). Il est de ces Roles qui ont les affaires liees a des informations qui leur sont associes. Par exemple, un PilotRole aurait le vol d'informations associes, et la CustomerRole aurait des ordres d'achat associes.
Le nouveau modele devrait ressembler a quelque chose comme ceci.
- Un Acteur peut ne pas avoir de roles, ou de nombreux roles.
- Une instance specifique d'un Acteur, d'interdire la suppression d'un role.
- Un role peut refuser la demande d'un Acteur en particulier.
- Un role peut specifier qu'il est necessaire et ne peut pas etre supprime (c'est a dire, LoginRole ne peut pas etre supprime parce que l'utilisateur a aussi un SystemAdministratorRole)
- Une instance specifique d'un Acteur peut rejeter un role.
Liste 1: l'Acteur
//Accepter ou de refuser un role fonction de TActor.CanAcceptRole(ARoleClass: TRoleClass): Boolean begin si non ARoleClass.AllowDuplicates et HasRole(ARoleClass, nil) then Result := False else si non ARoleClass.AllowActiveDuplicates et HasActiveRole(ARoleClass, nil) then Result := False else Result := ARoleClass.CanApplyTo(Auto) fin
//d'Autoriser ou d'interdire la suppression d'un role fonction de TActor.CanRemoveRole(ARole: TRole): Boolean begin Result := pas d'ARole.IsRequired fin
//Retourne un role, mais seulement si elle est active fonction de TActor.FindActiveRole(Classe: TClass ExcludeInstance: TRole): TRole var I: Integer begin Resultat := nil for I := 0 to Roles.Count - 1 do si les Roles[I].Active et (Roles[I].ClassType = Classe) et (Roles[I] <> ExcludeInstance) begin Result := Roles[I] Break fin fin
//Retourne un role, qu'elle soit active ou pas fonction de TActor.FindRole(Classe: TClass ExcludeInstance: TRole): TRole var I: Integer begin Resultat := nil for I := 0 to Roles.Count - 1 do if (Roles[I].ClassType = Classe) et (Roles[I] <> ExcludeInstance) begin Result := Roles[I] Break fin fin
//Retourne Vrai si l'Acteur possede un role specifique et il est actif fonction de TActor.HasActiveRole(Classe: TClass ExcludeInstance: TRole): Boolean begin Resultat := Assigne(FindActiveRole(Classe, ExcludeInstance)) fin
//Retourne Vrai si les Acteurs possede un role specifique (actif ou inactif) fonction de TActor.HasRole(Classe: TClass ExcludeInstance: TRole): Boolean begin Resultat := Assigne(FindRole(Classe, ExcludeInstance)) fin
fonction de TActor.ReceiveQueryFromOwned(Auteur: TObject OriginalEvent: TBoldEvent const Args: array de const Abonne: TBoldSubscriber): Boolean var ObjectLocator: TBoldObjectLocator Role: TRole begin Result := herite ReceiveQueryFromOwned(Initiateur, OriginalEvent, Args, l'Abonne) si pas de Resultat ou de BoldObjectIsDeleted puis Sortie //Verifier pour l'insertion des roles if (Auteur = M_Roles) puis begin si OriginalEvent = bqMayInsert puis begin //Obtenir le role insere Assert(Args[1].VType = vtObject) ObjectLocator := (Args[1].VObject comme TBoldObjectLocator) Role := (ObjectLocator.BoldObject comme TRole) //Verification des doublons des roles qui ne sont pas autorises si (pas de Role.AllowDuplicates) et (HasRole(Role.ClassType, nil)) begin Result := False SetBoldLastFailureReason( TBoldFailureReason.Create('Ce role ne peut etre applique qu'une fois', Self) ) else //Verification des doublons des roles actifs qui ne sont pas autorises si (pas de Role.AllowActiveDuplicates) et (HasActiveRole(Role.ClassType, nil)) puis begin
Result := False SetBoldLastFailureReason( TBoldFailureReason.Creer ('Impossible d'appliquer ce role parce que' 'il y a deja un role actif de cette nature', l'Auto) ) else Result := CanAcceptRole(TRoleClass(Role.ClassType)) si pas de Resultat, alors SetBoldLastFailureReason( TBoldFailureReason.Creer (Role ne peut pas etre appliquee a cet objet', Self) ) fin du else //bqMayInsert //Verification de la suppression de roles si OriginalEvent = bqMayRemove puis begin //Recupere le role de l'objet supprime Assert(Args[0].VType = vtInteger) Role := Roles[Args[0].VInteger] Result := (pas de Role.Active) ou (pas de Role.IsRequired) si pas de Resultat, alors SetBoldLastFailureReason( TBoldFailureReason.Creer (Role ne peut pas etre supprime, ' 'il est requis par un autre role actif', Self) ) fin //bqMayRemove fin fin |
Liste 2: Role
//Autoriser ou d'interdire l'application d'un Acteur en particulier fonction de classe TRole.CanApplyTo(AObject: TActor): Boolean begin Result := False fin
//methode Virtuelle a remplacer dans des descendants qui decrit le role fonction de classe TRole.GetRoleName: string begin Result := ' fin
//Optionnel, specifie si active, les doublons sont autorises ou pas fonction de classe TRole.AllowActiveDuplicates: Boolean begin Result := False fin
//Optionnel, specifie si les doublons sont autorises ou non (actif ou inactif) fonction de classe TRole.AllowDuplicates: Boolean begin Result := False fin
//Retourne Vrai si l'un role depend de ce role d'etre present fonction TRole.IsRequired: Boolean var I: Integer begin si l'Acteur <> nil then begin Result := True for I := 0 a l'Acteur.Les roles.Count - 1 do si l'Acteur.Roles[I] <> auto si l'Acteur.Roles[I].RequiresRole(auto) Sortie fin Result := False fin
//Remplacer cette option pour specifier si un autre role est tributaire de l' fonction TRole.RequiresRole(ARole: TRole): Boolean begin Result := False fin
//Remplit le derive RoleName attribut a partir de la methode de classe procedure TRole._RoleName_DeriveAndSubscribe(DerivedObject: TObject Abonne: TBoldSubscriber) begin herite M_RoleName.AsString := GetRoleName fin
//Empeche la suppression d'un role necessaire fonction TRole.MayDelete: Boolean begin Result := pas IsRequired fin
fonction TRole.ReceiveQueryFromOwned(Auteur: TObject OriginalEvent: TBoldEvent const Args: array de const Abonne: TBoldSubscriber): Boolean begin Result := herite ReceiveQueryFromOwned(Initiateur, OriginalEvent, Args, l'Abonne) si pas de Resultat, alors la Sortie if (Auteur = M_Active) puis //Active l'attribut begin si OriginalEvent = bqMayModify puis begin si l'Acteur = nil then Result := True else si Active, alors begin //Interdire la desactivation si un autre role il faut //cette role actif Resultat := pas IsRequired si pas de Resultat, alors SetBoldLastFailureReason( TBoldFailureReason.Creer ('Ne peut pas desactiver ce role,' 'autres roles exigent', Auto) ) else begin //Interdire la reactivation si un autre role actif existe //et les doublons ne sont pas autorises Result := AllowActiveDuplicates ou (pas l'Acteur.HasActiveRole(De Soi.ClassType, Auto)) si pas de Resultat, alors SetBoldLastFailureReason( TBoldFailureReason.Creer ('Impossible d'activer ce role' 'car il y a deja une similaire role actif', Self) ) fin fin //bqMayModify fin //Active attributeend fin |
Le code jusqu'a present, a ete abrege. Tout ce qui reste est de descendre certaines classes concretes de l'Acteur et de son Role.
Conclusion
au Lieu d'avoir une classe Employe ou un Client de classe, nous pouvons maintenant facilement attribuer une EmployeeRole ou CustomerRole a tout type de Personne objet (qui est un Acteur).
en Outre, nous pouvons melanger les roles, un Pilote peut effectuer l'administration, et tout ce qui pourrait etre un client (une Personne, un Service, une Entreprise, ou meme d'un Pays).
j'espere que cet article a ete instructif.
& nbsp
Basé sur un rôle de programmation en gras
By commentfaire
Basé sur un rôle de programmation en gras : Plusieurs milliers de conseils pour vous faciliter la vie.