从 Java 到 Ruby 的状态设计模式

发布于 2024-08-06 20:08:10 字数 1942 浏览 1 评论 0原文

我在 java 中有一个工作解决方案,使用经典的状态设计模式,但在将其转换为 ruby​​ 时面临一些困难。我是 Ruby 新手,但我认为困难在于如何在动态语言中实现模式的差异。

我的接口描述了模型在每种状态下可以执行的操作:

public interface State {

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

接下来,我实现状态接口并创建逻辑的具体状态:

    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));
}

如您所见,每个具体状态都可以进入模型并更改其状态。为了避免封装问题,我在 Model 类中实例化我的具体状态,该类还引用当前状态:

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(){...}

客户端将像这样使用模型:

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

我认为上述所有 Java 都很简单,但现在我尝试将此设计移植到 Ruby 中。我知道类型检查方面的差异,以及模块和混入在 Ruby 中与 Java 接口相比应该如何工作。

我还在 pickaxe 书中找到了有关 Ruby 中的状态设计模式的信息。 现在我有点困惑哪种是尝试这种转换的最佳方法。我仍在 Java 框内思考,想知道是否应该在不同的 .rb 文件中具体实现每个状态,然后在客户端类中需要它?

有没有办法在不使用 delegate.rb 库的情况下实现上述内容?

任何有关如何开始我的转换的建议都将受到热烈欢迎。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

霓裳挽歌倾城醉 2024-08-13 20:08:10

要将其转换为 ruby​​,您可以省略界面并保持其他所有内容不变。即每个状态都是一个定义方法 do_task_N 的类,并且没有与其他状态类的连接(这意味着您不必通过混合来“模拟”公共接口)模块或任何东西,你根本不需要它)。

我还在Java里面思考
盒子,想知道我是否应该拥有我的
各州具体实施
在不同的 .rb 文件中,然后
在客户端类中需要它吗?

听起来不错,是的。

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.

我们的影子 2024-08-13 20:08:10

您是否正在尝试将特定程序从 Java 移植到 Ruby,或者您是否正在尝试学习编写 Ruby?

如果#1,为什么?

如果#2,我建议您使用现有的 Ruby 代码来学习 Ruby 风格。为此,我强烈推荐 Ruby on Rails,因为它是一个编写得非常好的框架。
我从 Rails 中学到了很多经验教训,即使当我用其他语言编写其他类型的程序时也可以使用它们。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文