1 votes

Problème de conception lorsque des classes implémentent différentes interfaces pour restreindre les actions des clients.

Disons que je définis une classe de jeu qui met en œuvre deux vues différentes :

interface IPlayerView {
    void play();
}

interface IDealerView {
    void deal();
}

La vue qu'un jeu voit lorsqu'il joue, et une vue que le croupier voit lorsqu'il distribue le jeu (c'est-à-dire qu'un joueur ne peut pas faire d'actions de croupier et qu'un croupier ne peut pas faire d'actions de joueur). La définition du jeu est la suivante :

class Game : IPlayerView, IDealerView {
    void play() { ... }
    void deal() { ... }
}

Supposons maintenant que je veuille permettre aux joueurs de jouer le jeu, mais pas de le distribuer. Mon idée originale était qu'au lieu d'avoir

public Game GetGame() { ... }

J'aurais quelque chose comme

public IPlayerView GetGame() { ... }

Mais après quelques tests, j'ai réalisé que si j'essaie ce code plus tard, il fonctionne :

IDealerView dealerView = (IDealerView)GameClass.GetGame();

cela fonctionne et permet à l'utilisateur de jouer le rôle de croupier.

Est-ce que je m'inquiète trop ? Comment gérez-vous habituellement ces modèles ? Je pourrais plutôt créer deux classes différentes, peut-être une classe "principale", la classe du croupier, qui agirait comme une usine de classes de joueurs. De cette façon, je pourrais contrôler exactement ce que je souhaite transmettre au public. D'un autre côté, cela rend tout un peu plus complexe qu'avec cette conception originale.

Gracias

3voto

Georgy Bolyuba Points 3932

Premièrement, vous essayez de créer une classe qui est responsable de deux choses vaguement liées. Je diviserais cette implémentation en au moins deux classes. Pourquoi ne pas donner la méthode "play" à un joueur qui est censé l'appeler dans votre conception de toute façon ?

Deuxièmement, vous vous inquiétez trop. Les caractéristiques du langage comme les interfaces et les caractéristiques de conception comme les modèles ne sont pas là pour vous protéger de vous-même (ou des autres développeurs). Si quelqu'un veut en abuser, il le fera (c'est ce qu'on appelle le "hack", je crois). Elles sont là pour vous faciliter la vie, rendre votre code plus facile à maintenir, à utiliser et à tester.

Il y aura toujours un moyen d'abuser de votre code. Si ce n'est pas via le casting, alors avec la réflexion. Il suffit de laisser tomber et de se concentrer sur la construction de la "prochaine grande chose".

0voto

Phani Points 1848

Créez une classe d'implémentation pour les vues, puis passez l'objet de vue à l'objet d'usine et utilisez cette usine pour obtenir les vues correspondantes. Demain, si vous avez besoin d'implémenter une vue supplémentaire, vous pourrez facilement l'améliorer.

0voto

Gala101 Points 191

Je ne pense pas qu'il y ait beaucoup à gagner à avoir 2 méthodes différentes play() et deal(), parce qu'alors vous ne faites pas vraiment de polymorphisme d'exécution.

Conceptuellement, ce dont vous avez besoin est une méthode play() mais avec des implémentations différentes pour les classes Player et Dealer. D'un point de vue général, le croupier et le joueur jouent tous les deux au jeu, d'où la méthode play(), mais la façon dont ils jouent réellement est différente, le croupier distribuant (les cartes) et le joueur faisant des paris.

Donc, dans la lignée de ce qu'a dit Georgy, il est préférable de changer le design et de le rendre plus logique et plus simple pour commencer Je garde généralement les choses aussi simples que possible au départ, de toute façon elles ont tendance à être surchargées et surchargées au cours des itérations futures.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X