"Peter Duniho" <(E-Mail Removed)> skrev i meddelandet
news:(E-Mail Removed)...
> On 3/16/11 4:28 PM, Tony Johansson wrote:
>> "Peter Duniho"<(E-Mail Removed)> skrev i meddelandet
>> news:(E-Mail Removed)...
>>> On 3/16/11 3:51 AM, Tony Johansson wrote:
>>>> Here is a method InitialDeal that is responsible to deal two cards to
>>>> each
>>>> player.
>>>> pnlPlayer is a Panel type.
>>>
>>> Those first two sentences by themselves tell me your design is
>>> incorrect.
>>> A method that deals cards should have no reason whatsoever to know about
>>> a
>>> Panel instance. It should only be interacting with a non-GUI type that
>>> manages the state of the game.
>>>
>>>> gm is an instance of a class called GameManager.
>>>> This method is located in the MainGUI class.
>>>> I just want your opinion if this kind of design of a method in the
>>>> MainGUI
>>>> is somewhat sensible if we look at the OOP.
>>>
>>> It is not sensible. Again, perhaps if you ignore the bigger picture and
>>> focus _only_ on the very abstract object-oriented question, you could
>>> argue in favor of the design. But it's not enough to abstract things in
>>> an object-oriented way; you have to abstract things in a way that is
>>> proper in all the ways that matter.
>>>
>>> Using GUI objects to maintain or even access/reveal the state of the
>>> non-GUI aspects of your program is poor design. It causes your types to
>>> be too involved with matters that aren't relevant to the primary purpose
>>> of those types.
>>>
>>> You keep asking about "OOP" but IMHO that's not really the important
>>> context for this line of questioning.
>>>
>>> From a design point of view, your question is sort of like asking "I am
>>> designing a new animal; here I have followed the usual technique of
>>> providing pulmonary, circulatory, lymphatic, muscle, and nervous
>>> systems.
>>> Even though I've put the eyeballs on the soles of the feet, doesn't the
>>> fact that I've got all the basic networked systems in the body mean that
>>> my animal is correct?"
>>>
>>> OOP is not an end unto itself. It's just a single piece of a larger
>>> process for making a good program. It's important to have a good OOP
>>> foundation on which the rest of your program is built, but it's not
>>> sufficient to concern yourself only with the object-oriented nature of
>>> the
>>> code. You have to look at the big picture.
>>>
>>> Pete
>>
>>
>> From the MainGUI I call a method called Start this is located in the
>> GameManager. This GameManager was instansiated in MainGUI. From
>> GameManager
>> I call NewDeal that is located in the Game class and here I deal two card
>> to
>> each player to put in the hand of the player
>> What I want now is to put the cards that is stored in the hand of each
>> player in the PlayerGUI.
>> What is the best way to establish that.
>
> The best way to establish that is for the PlayerGUI class to subscribe to
> an event on the Player class that is raised when the hand of the player
> changes. Then the PlayerGUI will update itself based on the new contents
> of the player's hand.
>
>> I mean If I use this
>> NotifyPropertyChanged when I added a new card in the hand of a Player I
>> can't subscribe to this event from the MainGUI class because I don't have
>> a
>> reference to the hand class it's only the Player class that has a
>> reference
>> to the hand class.
>
> You can either expose the Hand class so that the GUI classes can see it,
> or you can write a new event in the Player class that essentially
> delegates the event to the Hand class, by having the Player class
> subscribe to the Hand class's event and then raising its own when the Hand
> class's event is raised.
>
> Without a proper code example, I don't really understand how the PlayerGUI
> can even show the cards in the player's hand if it doesn't know about the
> Hand class. But whatever: the bottom line is, if you're going to follow
> your current design, just put the event wherever the GUI types are
> currently finding out about the cards in the hand already.
>
>> It seems impossible to make the GUI subscribe to some sort of event so
>> they
>> can update the GUI with cards.
>
> It's programming. Nothing is impossible, though lots of choices are
> ill-advised. Sometimes the only available choices are in fact
> ill-advised, which then means you've messed up the overall design. In
> that case, you can either go with fixing the code in an ill-advised way,
> or you have to go back and fix the design first, so that you have options
> that are not ill-advised.
>
> Pete
Here is how my classes talk to each other and I hope it would be possible to
subscribe to the event PropertyChanged
that is raised in the Hand class when a new card is added to the hand of a
Player.
I hope that you can give me some advise how I can do that.
This MainGUI class which is called CardGameTester has a reference two these
two class library CardGameClassLib and CardGameControlLib
CardGameClassLib contains these classes Game,Deck,Card,PLayer and Hand
CardGameControlLib contains these classes PlayerGUI and CardGUI which is
user controls
public partial class CardGameTester : Form
{
private BindingSource bindingSource = new BindingSource();
private GameManager gm = new GameManager();
....
private void BtnStartGame_Click(object sender, EventArgs e)
{
gm.Start();
}
....
}
public class GameManager
{
private Game game = new Game();
public void Start()
{
game.NewDeal();
}
}
public class Game
{
const int InitialDealRound = 2;
private int currentPlayer;
private Deck deck = new Deck();
private int nrOfPlayers;
private List<Player> players = new List<Player>();
public void NewDeal()
{
nrOfPlayers = players.Count;
deck.Shuffle();
for (int cardNr = 0; cardNr < InitialDealRound; cardNr++)
{
for (int playerNr = 0; playerNr < nrOfPlayers; playerNr++)
{
players[playerNr].DrawCard(deck.GetNextCard());
}
}
}
}
public class Deck
{
const int MaxNumOfCardsPerDeck = 52;
private Card[] cards;
private int currentPosition = 0 ;
public Card GetNextCard()
{
if (currentPosition == cards.Length)
{
currentPosition = 0;
Shuffle();
}
return cards[currentPosition++].Clone() as Card;
}
....
}
public class Player
{
private Hand hand = new Hand();
private int playerID;
private int losts;
private string name;
private int wins;
private int sum;
private int currentSum;
public void DrawCard(Card card)
{
hand.AddCard(card);
}
}
public class Hand : INotifyPropertyChanged,ICloneable
{
const int LuckyNumber = 21;
private List<Card> cards = new List<Card>();
public event PropertyChangedEventHandler PropertyChanged;
public void AddCard(Card card)
{
cards.Add(card);
NotifyPropertyChanged("CardAdded");
}
private void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
//Tony
|