views:

53

answers:

3

Let's say I'm defining a game class that implements two different views:

interface IPlayerView {
    void play();
}

interface IDealerView {
    void deal();
}

The view that a game sees when playing the game, and a view that the dealer sees when dealing the game (this is, a player can't make dealer actions and a dealer can't make player actions). The game definition is as following:

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

Now assume I want to make it possible for the players to play the game, but not to deal it. My original idea was that instead of having

public Game GetGame() { ... }

I'd have something like

public IPlayerView GetGame() { ... }

But after some tests I realized that if I later try this code, it works:

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

this works and lets the user act as the dealer.

Am I worrying to much? How do you usually deal with this patterns? I could instead make two different classes, maybe a "main" class, the dealer class, that would act as factory of player classes. That way I could control exactly what I would like to pass on the the public. On the other hand, that turns everything a bit more complex than with this original design.

Thanks

+3  A: 

First, you are trying to make a class that is responsible for two loosely related things. I would split this implementation in at least two classes. How about giving method "play" to a Player which supposed to call it in your design anyway?

Second, you worry too much. Language features like interfaces and design features like patterns are not there to protect you from yourself (or other developers). If someone wants to abuse it they will (that is what is called "hack" I think). They are there to make your life easier, your code more maintainable, expendable and testable.

There always will be a way to abuse your code. If not via casting, than with reflection. Just let it go and concentrate on building "next big thing".

Georgy Bolyuba
Yes, I think you are correct on both points.
devoured elysium
A: 

Create a implementation classes to Views and then pass the View Object to Factory Object and use that Factory to get corresponding views.Tomorrow if you need to implement one more view then you could easily enhance.

Phani
A: 

I don't think much is to be gained by having 2 different methods play() and deal(), because then you are not really doing any run-time polymorphism.

Conceptually what you need is a play() method but with different implemetations for Player and Dealer classes. From a high level, both the dealer and the player are playing the game, hence the play() method, but how they actually play it is different, with Dealer dealing (the cards) and Player making bets.

So in line with that Georgy said, it's better to change the design and make it more logical and simpler to start with.. I generally keep things as simple as possible in starting, anyway they tend to get overloaded and overburdened in due course of future iterations.

Gala101
The idea here is not achieving polymorphism! Is restricting user access.
devoured elysium
In that case, a trivial safety feature could be adding a final boolean playerMode (with private setter) and setting this to true at the time of making a Player, then in the deal() method you can check if it's a player and stop deal()
Gala101