【问题标题】:Bad class design using Java Runnable使用 Java Runnable 进行糟糕的类设计
【发布时间】:2020-09-10 14:47:15
【问题描述】:

您能否解释一下为什么在以下程序中以这种方式实现 Runnable 接口是一个糟糕的设计决策?直观地说,如果我必须自己编写这个,我会让 Hotel 成为它自己的类,并在实现 Runnable 的新类中编写 run() 规范。但是,我无法真正解释为什么下面的代码是一个糟糕的设计决策。

该课程为一家酒店建模,其中包含排队等候的人员和房间列表。有几个“工作台”在不同的线程上运行,每个工作台负责将人员从队列中移出并将他们签入可用的房间。为简单起见,不包括退房。方法的实现并不重要(相信它是线程安全的),这个问题是关于将 run() 放入 Hotel 类的设计决策。

public class Hotel implements Runnable {
    private final static int NR_ROOMS = 10;
    private final Person [] rooms = new Person [ NR_ROOMS ];
    private final List < Person > queue = new ArrayList < >();
    private final Lock queueLock = new ReentrantLock ();

    private boolean occupied (int i) {
        return ( rooms [i] != null);
    }

    private int checkIn ( Person p) {
        // add Person to a free room
    }


    private void enter ( Person p) {
        // add a person to the waiting queue
    }

    // every desk employee should run as a separate thread
    @Override
    public void run () {
        // remove guests from the queue and check them in
    }
}

【问题讨论】:

  • 请发布可重现的代码示例。如果您注释掉所有方法,我不知道代码有什么不好。另外,我不知道将这个可运行对象添加为线程的主类。
  • 将数据类、业务逻辑和多线程混合在一个地方并不是一个好主意。

标签: java multithreading thread-safety runnable


【解决方案1】:

OO 编程的重点是创建类来模拟您的业务逻辑;由于您的问题涉及酒店、房间、人员等,因此可以期望在您的问题域中存在代表这些“名词”的类。然后,这些类上的方法代表对对象执行的操作。

我对 Hotel 类上的 run() 方法的直接问题是,对于酒店“运行”意味着什么并不清楚。我想在某些情况下这可能是有道理的;例如,如果你有一个模拟,并且已经制定了关于酒店随着时间推移应该发生的事情的规则。不自然的部分是酒店通常是发生事情的地方,而不是做事情的地方。

就此而言,对我来说,酒店实例有一个rooms 列表似乎过于简单,每个列表都是Person 类型。您可以通过这种方式使简单的逻辑工作,但是 OO 设计的原则之一是使现有程序的扩展变得容易,因为您已经对问题域的真实世界对象进行了建模,因此用它们做更多的事情将是自然比你没有更容易。在这种情况下,在我看来,如果 Hotel 有一个 Room 对象列表,那么与已知问题空间的匹配会更好,然后每个 Room 对象可以包含一定数量的 Person 对象。那么一个房间的人数就更灵活了,不同房间的人数可能不同,等等。

我完全赞成从一个简单的系统开始,但既然你问的是 OO 设计,我想我会借此机会指出这些关于这个的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    相关资源
    最近更新 更多