demeter法则 - 只使用一个点,我可以改进这个逻辑吗?

时间:2016-05-13 09:23:32

标签: java oop refactoring law-of-demeter

我有以下方法:

    private boolean reserveSeat(int selectedRow, int selectedSeat) {
    if (show.getRows().get(selectedRow).getSeats().get(selectedSeat).getReservationStatus()) {
        return false;
    } else {
        show.getRows().get(selectedRow).getSeats().get(selectedSeat).reserve();
        setRowNumber(selectedRow);
        setSeatNumber(selectedSeat);

        return true;
    }
}

位于Reservation类中。这个类有一个Show Object(show),一个show有Rows(另一个对象),Rows有Seats(另一个对象)。

我的问题是这种方法可以改进吗?我已经阅读了有关LoD的内容并担心我的点会发出错误的设计,尽管我认为这是合乎逻辑的。 Seat对象知道它是否被保留。然而,从Show到Seat与陌生人交谈?还是因为每个对象包含下一个对象的方式是否正常?

如果我的探索不明确,请道歉。我似乎发生的事情(可能是因为我自学)是我设计的东西,然后我读了一些OOP设计原则并思考废话,它的工作但它不是很好的设计!

任何建议表示赞赏。

3 个答案:

答案 0 :(得分:3)

是的,这个电话链太长了。 如果show负责座位, 那么如果完全负责会更好。 现在它没有完全掌控, 因为座位可以在没有节目知道的情况下保留。 这种责任分散是很奇怪的。

您可以通过不showSeat展示Reservation来完全管理private boolean reserveSeat(int selectedRow, int selectedSeat) { if (show.isSeatReserved(selectedRow, selectedSeat)) { return false; } else { show.reserveSeat(selectedRow, selectedSeat); setRowNumber(selectedRow); setSeatNumber(selectedSeat); return true; } } , 隐藏辅助方法背后的座位状态操作:

show

或者,如果您不希望show负责座位, 然后它根本不应该知道座位, 所以你不能通过public class GcmBroadcastReceiver extends WakefulBroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // Explicitly specify that GcmIntentService will handle the intent. ComponentName comp = new ComponentName(context.getPackageName(), GcmIntentService.class.getName()); JSONObject json = new JSONObject(); try { json.putOpt("userid", StorePreference.GetSharedPreferenceDetails(context, "memberid")); json.putOpt("rid",StorePreference.GetSharedPreferenceDetails(context, "partnerid")); json.putOpt("message", "Received"); BoundService.getInstance().onlinestatus(json); } catch (Exception e) { e.printStackTrace(); } startWakefulService(context, (intent.setComponent(comp))); setResultCode(Activity.RESULT_OK); } } 访问座位, 但另一个负责这个的课程。

答案 1 :(得分:1)

您正在使用show作为数据对象,并将用于处理该数据的所有逻辑放在包含它的类中。这使得Show成为一个数据类,而封闭的类成为上帝类。

处理show 内的数据的逻辑应该真正在Show类本身内部(数据是智能的)。

您可以在Show课程中制作一个方法来预订座位。同样,您可以在Row课程中制定一个方法来保留座位。

然后,只需将消息传递给下一个消息,直到您到达Seat

如果您将Show的实现更改为使用2D数组,该怎么办?这会打破预订类中的代码。

通过执行这些长链接调用,而不是让类处理自己的数据。您正在使用户类依赖于所使用的数据结构的实现。

如果您想更改一个,则必须更新所有用户类,而不是仅包含数据结构的一个类。

答案 2 :(得分:0)

非常感谢您的建议,反馈确实有助于我的学习。所以我接下来要做的是基于关系 - >>预订(现在称为预订 显示显示 席位(s)。

在预订课程中,我现在有了这个:谢谢@janos

public boolean isSeatReserved(int selectedRow, int selectedSeat) {
    if (getRow(selectedRow).getSeatStatus(selectedSeat)) {
        return true;
    } else
        return false;
}

在Show类我有这个:

public boolean getSeatStatus(int selectedSeat) {
    return getSeat(selectedSeat).getReservationStatus();
}

在Row类中我有

 override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    navigationController?.toolbarHidden = false

我认为对于刚开始(像我一样)的其他人来说,使用从jarchitect工具中获取的图表之前和之后以图形方式显示它可能是有用的,这显示了我的代码所带来的混乱!我使用相同的逻辑来整理“知道太多”的其他类。

Before Refactoring

After Refactoring