views:

133

answers:

2

Hello,

I have a working solution in java using a classic state design pattern and facing some difficulties translating it to ruby. I am new in ruby, but the diffuclty I believe lies in the differences on how patterns can be implemented in dynamic languages.

My interface is describing the actions the model can execute in every state:

public interface State {

    public void doTask1(Model a_model);
    public void doTask2(Model a_model);
    public boolean doTask3(Model a_model, Helper a_helper);
}

Next, I implement the state interface and create concrete states of my logic:

    public class LogicState1 implements State {

 public void doTask1(Model a_model) {
  a_model.implementTask1();
 }

 public void doTask2(Model a_model) {
  a_model.implementTask2();
 }

 public boolean doTask3(Model a_model, Helper a_helper) {
                a_model.useHelper();
      return a_model.setState(a_model.getALogicstate(a_key));
}

As you can see, each concrete state can reach into the model and change its State. To avoid encapsulation issues, I instantiate my concrete states within the Model class, which has also a reference to the current State:

public class Model {

private State currentState;

public void setState(State state){
 this.currentState = state;
 }

public State getState(){
 return currentState;
 }

private final Map<String, State> everyState = new HashMap<String, State>();

public Model(String initialStateKey){
   everyState.put("key1", new LogicState1());
   everyState.put("key2", new LogicState2());
   //...etc, instantiate and store all business logic states
   this.currentState = everyState.get(initialStateKey);
}

public State getALogicState(String key){
 return everyState.get(key);
}
public void useHelper(){...}

A client would use the Model like this:

public void run(Model a_model) {
 a_model.getState().doTask1(a_model);
}

I think all of the above Java is straightforward, but now I am attempting to port this design into Ruby. I am aware of the differences in type-checking, and how modules and mixins are supposed to work in Ruby in contrast to Java's interfaces.

I have also found out about the State design pattern in Ruby in the pickaxe book. Now I am a bit confused about which is the best way to try such conversion. I am still thinking inside the Java box, and wondering if I should have my concrete implementation of each state in a different .rb file and then require it in the client class?

Is there a way to implement the above without using the delegate.rb library?

Any suggestions on how to start with my conversion will be enthusiastically appreciated.

+3  A: 

To translate this to ruby you can just leave out the interface and keep everything else as is. I.e. each state is a class that defines the methods do_task_N and doesn't otherwise have a connection to the other state classes (meaning you don't have to "emulate" the common interface by mixing-in a module or anything, you simply don't need it at all).

I am still thinking inside the Java box, and wondering if I should have my concrete implementation of each state in a different .rb file and then require it in the client class?

That sounds fine, yes.

sepp2k
Thanks for the helpful advice. So it looks like I can do without the ruby delegator class as well.
denchr
A: 

I you trying to port a specific program from Java to Ruby or are you trying to learn to write Ruby?

If #1, why?

If #2, I would recommend that you work with existing Ruby code in order to learn the Ruby style. I highly recommend Ruby on Rails for this, since it is a very well written framework. I learned a lot of lessons from Rails, which I can use even when I write other kinds of programs and in other languages.

Jørgen Fogh