0

Perhaps strategy pattern isn't what I'm after. Say my code looks like this (pseudo version):

class Machine
{
    private Stack<State> _internals;

    public void DoOperation(Thingy x)
    {
        switch (x.operation)
        {
            case Op.Foo:
                DoFoo();
                break;

            case Op.Bar:
                DoBar();
                break;

            case Op.Baz:
                DoBaz();
        }
    }

    private void DoFoo()
    {
        // pushing and popping things from _internals, doing things to those States
    }

    private void DoBar()
    {
        // similarly large method to foo, but doing something much different to _internals
    }

    private void DoBaz()
    {
        // you get the idea...
    }
}

Foo, Bar, and Baz are rather complex methods (not extremely long, just deserve separating) so I want to break them into classes with a common interface, a la strategy pattern. The problem is, I can't encapsulate _internals in those classes. I mean, I could pass it into the Execute method on those classes, but that seems like a bad way to go. The internals persist longer than the single operation, so the strategy classes can't "own" the internals themselves. Multiple different operations could be done on this Machine, with different Thingy's passed in.

Is there a different route you can suggest?

edit

This is kind of a state machine, but not in the sense that one operation is only valid in a particular state. _internals is a stack of states instead of just the current state. Any of the three operations can be done at any time.

Tesserex
  • 17,166
  • 5
  • 66
  • 106
  • I couldn't get the idea behind breaking methods into classes. – MNZ Aug 24 '13 at 23:53
  • All the classes would inherit or implement a common base. Thus ensuring , through the inheritance restriction that any method is not just a random method, but a method specifically designed to do this job. And enforced. – Andyz Smith Aug 25 '13 at 00:00
  • I guess the crucial criteria for selecting this pushing into classes, is, **do the methods do the same thing in a different way** – Andyz Smith Aug 25 '13 at 00:02
  • This may be more of a Command pattern candidate. You want to do radically different things to the internals, but you want to hide the fact that you are doing things by having an 'instruction' Thingy x? http://www.dofactory.com/Patterns/PatternCommand.aspx – Andyz Smith Aug 25 '13 at 00:08
  • OTOH, if you know at compile time that you have classes that do different things, but need access to the same data then you really need a Template base class. http://www.dofactory.com/Patterns/PatternTemplate.aspx – Andyz Smith Aug 25 '13 at 00:14
  • Since your example is rather abstract it is difficult to answer your question. What other things are a part of "Thingy". If it is only the supplier of the operation (like an enum), then let the interface reflect that. If your machine is more acting like a state machine (e.g. operation "Foo" is only valid once operation "Bar" has been applied) the "State pattern" may be a better match. Can you make your question a bit more concrete? What does "Thingy" represent and what are the operations supposed to achieve? – Alex Aug 25 '13 at 00:52
  • Do you want to change the behavior of `Machine` at runtime? Foo behavior, Bar behavior, etc.. depending on `Thingy`? If yes then Strategy Pattern is the right choice. – Imran Aug 25 '13 at 05:42

1 Answers1

0

Your strategy 'strategy' seems sound. Code looks good so far, you need to actually declare an interface, but I think you got that.

I dot't see why you can't pass the _internals. That would be part of the interface definition. That members be able to accept a type of " : _internals_data" or whatever.

You could wrap it up a bit, my defining the interface to be like

Execute

sendinlimitedsubsetofinternals

Returnsmodifiedsubsetofinternals

Then the two data methods could be like just an array of strings or something to really tighten down the interaction. Then you could use a serialization in the middle sometime later or something.

Andyz Smith
  • 698
  • 5
  • 20