2009-11-17 6 views
0

plus de contenu original supprimé pour faire référence à la question plus facile:Quel est le meilleur moyen de renvoyer plusieurs valeurs enum? (Java et C#)

J'ai une classe House qui a une méthode House.buy(Person p), ce qui provoque la personne d'acheter la maison. Je veux savoir si c'est possible pour la personne d'acheter la maison, donc j'ai aussi une méthode House.tryBuy(Player p) qui revient si la personne peut acheter la maison. J'ai un enum BuyState avec des valeurs comme OK, NotEnoughMoney et AlreadyOwned. Il y a quelques conditions différentes à satisfaire, et le client aimerait savoir lequel a échoué. Mais que faire si plusieurs conditions échouent? Je pourrais soit avoir une hiérarchie, comme si la maison est déjà détenue et personne n'a pas assez d'argent, retour BuyStates.AlreadyOwned. Mais cela me permet seulement de dire une chose au client. Je pourrais avoir N conditions séparées et une énumération avec des valeurs N * N, comme ConditionA_AND_ConditionB_ANDConditionC mais cela n'a aucun sens pour plusieurs raisons. Je sais qu'il y a des champs de bits, avec un peu pour chaque condition, mais ils semblent juste trop bas, ennuyeux à implémenter, et non scalable. Donc je besoin d'un moyen de retourner une liste de valeurs à partir d'un ENUM, que diriez-vous donc une classe comme ceci:

class C<type_of_enum> { 
    private List<type_of_enum> values; 

    //etc etc 
} 

Est-ce le « meilleur » conception possible?

(en gardant cette question sur Java et C# pour conserver des réponses valides)

+9

Je dois juste dire ceci: la personne. (Maison) ferait tellement plus de sens. –

Répondre

0

Il semble bien pour moi. Vous voulez retourner une liste des conditions qui ont échoué et vous renvoyez une liste des conditions qui ont échoué.

1

Oui, cela semble être le meilleur design. Vous voulez renvoyer une liste (ou un ensemble) de raisons, il est donc naturel de le renvoyer en tant qu'ensemble.

1

Je pense que retourner une liste de raisons de ne pas acheter est génial; c'est très expressif de ce que vous essayez de faire. Un ensemble serait probablement plus approprié, mais seulement légèrement.

12

En Java, la manière la plus naturelle de le faire est avec EnumSet. Un exemple de construire un:

return EnumSet.of(BuyConditions.NotEnoughMoney, BuyConditions.AlreadyOwned); 
+0

+1. C'est la bonne solution pour Java. En particulier, comme 'EnumSet' ne sont en réalité rien d'autre que des bits-fields avec une interface plus conviviale (' Set' like) – Dirk

0

Vous pouvez utiliser un rappel:

class House { 

    public void buy(Result result) { 

     if (true) 
      result.ok(this); 
     else 
      result.error(this, EnumSet.of(Status.NOT_ENOUGH_MONEY, Status.ALREADY_OWNED)); 

    } 

} 

enum Status { 

    NOT_ENOUGH_MONEY, 
    ALREADY_OWNED 

} 

interface Result { 

    public void ok(House house); 

    public void error(House house, EnumSet<Status> status); 

} 
0

au lieu de retourner une liste, vous pouvez passer un pointeur de liste à la fonction, à remplir avec des motifs en cas des conditions d'erreur se produisent. La fonction elle-même peut renvoyer 0 pour indiquer le succès et 1 pour l'échec, auquel cas vous pouvez vérifier le contenu de la liste. Cela permettra de savoir plus rapidement si l'appel de fonction a réussi ou non, en supposant que la plupart du temps ce sera un succès.

7

Est-ce la "meilleure" conception possible?

Cela ressemble à un design bizarre tout autour.Lors de la modélisation de choses réelles dans un logiciel, il est payant de faire en sorte que le modèle reflète la réalité; ces modèles sont plus faciles à comprendre, à maintenir et à développer. Tout d'abord, une maison n'est pas quelque chose qui achète une personne. Une personne est quelque chose qui achète une maison. La méthode "acheter" devrait être sur "personne", pas sur "maison". Deuxièmement, une maison n'est pas quelque chose qui détermine si une maison peut être achetée. Le propriétaire de la maison est l'entité qui détermine si elle peut être achetée. (Pourquoi y a-t-il une condition d'erreur "déjà possédé"? Bien sûr, la maison est déjà la propriété Quelqu'un le possède.)

Troisièmement, vous pourriez avoir à considérer ce qui se passe dans un monde où plusieurs acheteurs pourraient tenter de acheter la maison tout à la fois. En réalité, le vendeur recueille diverses offres et fait des contre-offres, les ventes peuvent être subordonnées à d'autres événements, et ainsi de suite. Est-ce que toutes ces choses devraient être présentes dans le modèle? Si oui, où? Probablement dans l'état de l'objet représentant le propriétaire, puisque le propriétaire est la chose en cours de négociation. Quatrièmement, en réalité, les transactions d'achat de logements impliquent généralement une tierce partie de confiance à faire un dépôt fiduciaire, et diverses autres parties telles que les prêteurs du vendeur et de l'acheteur qui pourraient fournir des fonds ou détenir des privilèges. Ces parties sont-elles reflétées dans ce modèle? Cinquièmement, si votre intention est d'ajouter à votre modèle des «raisons pour lesquelles vous ne pouvez pas acheter cette maison», alors ce que vous décrivez est un système de politique . Dans ce cas, représentez les stratégies en tant qu'objets de première classe dans votre système, afin qu'elles puissent être manipulées comme n'importe quel autre objet. Les propriétaires ont des politiques sur les conditions dans lesquelles ils vont vendre. Les banques ont des politiques sur les conditions dans lesquelles elles vont prêter. Etc. Dans ce modèle, votre problème consiste à «demander au moteur de résolution de la politique si l'acheteur remplit toutes les conditions nécessaires imposées par les arbres de politique de chaque agence concernée afin d'acheter une maison donnée». En d'autres termes, la question "peut X acheter Y?" n'est pas pour X ou Y pour comprendre; c'est une question pour un moteur de résolution de politique à travailler, et cette chose est ce qui vous donne une liste des politiques X n'a ​​pas réussi à acheter Y à partir de Z.

Avez-vous du sens?

Questions connexes