简体   繁体   中英

state design pattern from Java to Ruby

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.

To translate this to ruby you can just leave out the interface and keep everything else as is. Ie 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM