2

I want to refactor some code.

Basically the code I want to refactor is a Form (using System.Windows.Forms;)

The way it is setup now, depending on which radio button you selected it shows a different layout for the window: different labels, buttons, etc. Not always a big difference, but different. This is a lot of conditional statement junk all over the place. I wanted instead to refactor it with the State pattern. There are three main states.

I'm not sure the best way to do this. Right now the IState interface has a DoAction() method which does some action particular to the unique State, and a DrawForm() method which re-draws the form based on the current State... However, to do the DrawForm(), the State classes need to be able to access the Form's member variables. That's what threw me for a loop. I didn't really want to expose them.

Is there a better way to do this?

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
Alex Baranosky
  • 48,865
  • 44
  • 102
  • 150
  • 2
    From what I know about State Pattern DID requires those concrete state classes have access to the "context" (form in your case). It sounds it is inevitable to access those member variables. – xandy Jul 27 '09 at 01:12
  • Thanks, I had to give your comment some love, because there's not one answer to upvote, lol. – Alex Baranosky Jul 27 '09 at 01:39

4 Answers4

3

You could make your state classes nested in your form. They will then be able to acces fields of form without having to expose them.

Ben Lings
  • 28,823
  • 13
  • 72
  • 81
  • This is pretty much exactly what I needed to feel good about the way I was setting it up. Somehow I totally forgot about nested classes. – Alex Baranosky Jul 28 '09 at 07:30
1

If your primary concern is keeping form stuff encapsulated, and you want to keep the state machine outside, I had a similar question a while back, you could check out the answer here - basically it entails creating a private inner 'action' class which DOES have access to form methods, then passing this to the state machine so that it can use the action class to invoke form methods indirectly.

Community
  • 1
  • 1
Benjol
  • 63,995
  • 54
  • 186
  • 268
0

I don't know if this helps, but why not have something like a strategy pattern for drawing the form?

So something along the lines of

interface IDrawStrategy
{ 
   void Draw(FormType form);
}

And then when you pick which state the form is in, you can assign the form's draw strategy. Yes, you will still need to give the draw method access to the Forms variables to allow it to position them, but it at least allows you to make it easier to add different looks based on the states.

AshtonKJ
  • 1,376
  • 2
  • 14
  • 22
0

In wanting to extract the "state" of the Form, you are describing a pattern better known as a "Presentation Model". You will find some good information and tips on how you generally want the Form and State to interact by reading this article by Martin Fowler. In your case, your Form is the "View" and your State is the Presentation Model. As always, Fowler does a great job answering this question and more.

Chris Melinn
  • 2,046
  • 1
  • 17
  • 18