Pattern/Idiom for Simplifying Interface

Started by
6 comments, last by laztrezort 12 years ago
I'm doing some refactoring of a Winforms app, and a particular piece of code doesn't smell right to me. I have a custom control class (call it Canvas), on which a number of Tools can act on it (typical drawing tools such as paint, line, fill, etc.)

Since the Canvas class has grown rather heavy (both in size and public interface), I thought I'd seperate out each tool into a seperate class, which interacts with Canvas directly. Each Tool object is notified of relevent input messages, and communicates back to the Canvas in order to draw, save state for undo, query any necessary data, etc. To do this, each Tool stores a reference to Canvas, and vice versa.

Since Tool needs to communicate with Canvas (and vice versa), it can only do so through public methods on Canvas. Thus, the public Canvas interface isn't getting any smaller/simpler as I'd hoped, although it now has a manageable footprint at least.

To generalize, if I have a class A which the client (application) interacts with, and a class B which interacts only with A (to handle logic related to A), how do I provide an interface on A for B to use that is not exposed to the client?

The obvious answer is to seperate out A and B into its own assembly, make B an internal class, and add internal methods to A for B to call. I've also thought about hooking into events exposed by B, but I'm not sure this is the ideal use for events.

So I'm wondering if I'm missing something obvious here, a better way, or at least an alternative to seperate assemblies?

Then again, maybe I'm over-thinking things as I sometimes do...

Thanks for any suggestions.
Advertisement
A sounds like a facade for a composition of B's. Personally I would ditch A and use the appropriate B at the call sites on the client.

A sounds like a facade for a composition of B's.


Looking up "facade pattern" and reading this here: http://msdn.microsof...7730-01-04.aspx, it looks like this is basically what I have (where each Tool in my case would be a "subsystem", and the Canvas acting as a facade of sorts). In the example, they indeed use seperate compilation and internal for limititing visibility, so it appears that is the "correct" way to handle this.
The way I tend to do undo/redo is to have methods on the data model perform actions and return an object that is capable of undoing/redoing what was performed. These are then put on to a stack. Extra features such as composing/merging actions based on various predicates (e.g. temporal proximity, homogeneity, etc) can be added on top. In this system, the canvas would not know anything about the tools.

But I've never used Winforms in anger, so I may be missing some specifics that are relevant to your problem.

The way I tend to do undo/redo is to have methods on the data model perform actions and return an object that is capable of undoing/redoing what was performed. These are then put on to a stack.


Interesting, I hadn't thought of this approach. As it is, I have only a simple single undo/redo toggle implemented, in which I just keep a copy of the last state. In the future, I may come back and add proper undo/redo though.

Also, what both you and return0 seem to be suggesting is working directly through the Tools as the interface, another approach I hadn't considered, and which might work well as far as extending later.

Thanks for the ideas!
Undo/Redo is generally implemented with the command pattern.
The command pattern is certainly a starting point, but if naively won't get you very far, unless you have the simplest of applications.

I have a few posts on my blog that describe how you might begin setting up an undo/redo system. It's C++-centric, though most of the ideas/points should translate to .Net.

http://www.mr-edd.co...edo_1_easy_bits
http://www.mr-edd.co...xception_safety
http://www.mr-edd.co...mbining_actions

Maybe I'll finish the series one day... smile.png
Thanks for links, I'll digest these later when I get some time.

For anyone else reading who might be interested, I also found these:

http://www.codeproje...nd-pattern-in-C looks at one way to implement the command pattern in C#

http://www.codeproje...ation-in-C-Part implements Undo using 3 different methods, including command and memento patterns.

This topic is closed to new replies.

Advertisement