I've been making more of an effort lately to build better OO designs, creating classes for distinct collections of members etc. However, i've hit a bit of a wall in my project.

The program is designed to control an automated watering system. The system is split into multiple bays which are turned on and off independantly.

I have my form which shows a map of the system with a custom button for each bay. I also have controls that allow the user to create a sequence of bays. eg, turn on bay 1, then bay 2, then 3 & 4..etc.

I have a class which stores details of the bay, one which stores a step in the sequence, one which stores the entire sequence and the form to handle user input. (see attached class diagram)

The problem i have is that the Bay Class has a draw method that paints it to the form. The colour it is painted depends on wether the bay is on or off. This is no problem since the on/off status is stored within the bay. The problem is that i need to add a third colour option, the third colour will be used if the bay isnt on in the current step, but IS part of a different step in the sequence.

My quandary is this: do i a) include a flag in the bay to show that it is in another step, b) have the step check with the sequence to see if any steps contain it, or c) check in the main form and pass a colour to the draw method?

Ive always had a problem thinkin in terms of OO...my early projects were coded ENTIRELY on a single form...makes me cringe looking back lol. To my mind, having a flag in the bay class is storing information about the sequence in the bay which doesnt feel right, but having the bay communicate with the sequence feels wrong too; i may be wrong, but i thought the classes behaviour should be internal.

Anyone with a good grasp of OO wanna throw me a bone :p Whats the best way to handle this, and have i made a complete mess of it so far. I'd rather get it right and get a better grasp on OO than kludge it :)

Attachments CD.jpg 78.66 KB

Hello, Ryshad :)
Ok, let's go .. I'll give a few comments on your suggestions and then give you an example.

a) include a flag in the bay to show that it is in another step

No, you shouldn't. Because the Bay class shouldn't be aware of what's happening outside of it.

b) have the step check with the sequence to see if any steps contain it

Also sounds a bit weird .. if rephrase - it would be "the element of an collection should be aware of other elements in collection "

c) check in the main form and pass a colour to the draw method

That's seems the right abstraction level for that design. The Form contains the collection and can be aware of what stored in it. But, probably not passing a color, but calling the right method or calling method with parameters.

Ok, for the first sight that all may seem kinda confusing, but here's example:
Imho, the one of the best methods of explanation - is use of metaphors...

Let's imagine that class is a closed box. If you're inside that box - you can't see what is happening outside (see your a suggestion).

But if we outside the box - we can see some of it characteristics (the methods or data, that you opened for public viewing aka open interface of the class).

Now let's put a few boxes in a row .. we have now a collection of boxes. Now you think, could we see the other boxes from inside of one of them? NO (see your b suggestion).
Now let's imagine, that our boxes are placed on some surface. We can see whole collection of the boxes also as one single element of that collection (box). And here's your form, containing a collection (see your c suggestion).

Now few words about the way your form interact with elements in collection:
You have a surface, with boxes on it .. Now, could the surface know, what color of box should have if it's in the given state? Or rather SHOULD it know that?
If you decided to use OO, then you decided to use some abstraction .. You have Bays, which can be in a few states etc. etc. So you can go further with that abstraction and depending on the Bay state - call methods e.g. draw() (if we have it) or drawStub() (if we haven't it yet) .. (everything this said after assuming, that the On property is publicity visible).

The drawStub() may be static, for the case if you haven't right instance of Bay class right now (but will have in future), but should display the Bay for the further steps.

Hope this will help you :)

Comments
great explaination :) thank you

>>Ive always had a problem thinkin in terms of OO...my early projects were coded ENTIRELY on a single form...makes me cringe looking back lol
Same thing here. I still have to support them too :X

Antenka's points were all the right way to think about it. I have one more approach to add:

You could also create a bay control for the designer that encapsulates your business entity, or extends it with drawing methods. That would keep the business logic tied in at the bay class while allowing a colored baycontrol object to be placed on your form. You could do it the easy way and encapsulate it with a user control but that is no fun!

[edit]
If your color changes based on the the status of the bay then you could implement System.ComponentModel.INotifyPropertyChanged in the Bay class. In the BayControl class you would subscribe to the class if you encapsulate the field and know to invalidate the control and repaint with the new color. If you extend the control then mark the public property as virtual and you could invalidate the control there.
[/edit]

Edited 7 Years Ago by sknake: n/a

Sorry for not replying guys, i was taken ill end of last week. Still not 100% but i've dragged myself back to work...the world waits for no man :p

Thanks for your suggestions, your explanation helped a lot ddoubled, i had a feeling the first two werent correct OO :) I'm gonna implement as suggested by having the form chcek the collection then call the appropriate draw() method.

At a later date i will look at seperating the control aspect from the bay class (which i think is what sknake is suggesting) but for now i have far too many projects on the go...wish i had a couple more of me...or better still, wish i had the budget to hire the both of you haha

This question has already been answered. Start a new discussion instead.