防止状态耦合?

发布于 2025-01-06 05:50:11 字数 705 浏览 2 评论 0原文

我有以下对象和关系,

Lecture >- Tests
Test >- Questions

业务规则

When the lecture is started, a test can be given
If a test is being given, questions can be asked

推理

Therefore questions shouldn't be asked if the lecture hasn't been started.

问题模型

class Question
  belongs_to :test
  belongs_to :lecture, :through => :test

  def ask_question
    raise "Test not started!" unless test.started?
    raise "Lecture not started!" unless lecture.started?
  end
end

很明显,问题模型的状态现在与测试和类的状态耦合。

在创建单元测试时,为了测试这一点,我需要设置所有这些状态,这变得非常笨拙,特别是当业务案例变得越来越复杂时。

我怎样才能避免这种情况?

I have the following objects and relationships,

Lecture >- Tests
Test >- Questions

Business rules

When the lecture is started, a test can be given
If a test is being given, questions can be asked

Inference

Therefore questions shouldn't be asked if the lecture hasn't been started.

Question Model

class Question
  belongs_to :test
  belongs_to :lecture, :through => :test

  def ask_question
    raise "Test not started!" unless test.started?
    raise "Lecture not started!" unless lecture.started?
  end
end

So clearly the state of the question model is now coupled to the state of test and class.

When creating unit tests, to test this I need to set up all this state, which gets quite unwieldy, especially as the business cases get more and more complicated.

How can I avoid this?

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

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

发布评论

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

评论(1

人生戏 2025-01-13 05:50:11

我对 Ruby 关联没有经验,但在我看来,数据模型以某种方式与运行时逻辑在这里混合在一起。

如果我要为问题和测试创建一个数据模型,我希望在测试中重复使用我的问题,并在讲座中重复使用准备好的测试(问题集)。在这种情况下,我会写一些类似的东西,

class Lecture
  has_and_belongs_to_many :tests
end

class Test
  has_and_belongs_to_many :lectures
  has_and_belongs_to_many :questions
end

class Question
  has_and_belongs_to_many :tests
end

与该结构分开,我会有一些与实时讲座、测试、问题和结果概念相对应的结构。结果是尝试回答给定学生的实时问题。

我还将对讲座会话状态的检查“委托”给测试会话。如果由于某种原因无法开始测试会话,则问题会话也无法开始。

要对问题会话进行单元测试,您只需要模拟测试会话,要对测试会话进行单元测试,您将需要模拟讲座会话,等等。

class Lecture_Session
  has_many :tests_sessions
  belongs_to :lecture
end

class Test_Session
  belongs_to :lecture_session
  belongs_to :test
  has_many :question_sessions

  def validate
    raise "Lecture not started!" unless lecture_session.started?
  end
end

class Question_Session
  belongs_to :question
  belongs_to :test_session

  def validate
    raise "Test not started!" unless test_session.started?
  end
end

class Result
  belongs_to :lecture_session
  belongs_to :test_session
  belongs_to :question_session
  belongs_to :student

  def validate
    raise "Question is not active!" unless question_session.active?
  end
end

希望这有帮助。

I'm not experinced with Ruby associations, but it seems to me that somehow data model is cofused with run-time logic here.

If I'd make a data model for question and tests, I'd want to re-use my questions across tests and also re-use prepared tests (sets of questions) across lectures. In that case I'd write something like

class Lecture
  has_and_belongs_to_many :tests
end

class Test
  has_and_belongs_to_many :lectures
  has_and_belongs_to_many :questions
end

class Question
  has_and_belongs_to_many :tests
end

Separately from that structure I'd have some structure corresponding to real-time lectures, tests, questions and a notion of a result. A result is an attempt to answer a real-time question by a given student.

I'd also "delegate" the check of the lecture session state to the test session. If test session cannot be started for whatever reason the question session cannot be started too.

To unit-test a question session you will only need to mock a test session, to unit test a test session you will need to mock a lecture session, and so on.

class Lecture_Session
  has_many :tests_sessions
  belongs_to :lecture
end

class Test_Session
  belongs_to :lecture_session
  belongs_to :test
  has_many :question_sessions

  def validate
    raise "Lecture not started!" unless lecture_session.started?
  end
end

class Question_Session
  belongs_to :question
  belongs_to :test_session

  def validate
    raise "Test not started!" unless test_session.started?
  end
end

class Result
  belongs_to :lecture_session
  belongs_to :test_session
  belongs_to :question_session
  belongs_to :student

  def validate
    raise "Question is not active!" unless question_session.active?
  end
end

Hope this helps.

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