在Java中,传递对象的引用被认为是不鼓励的吗?

18 浏览
0 Comments

在Java中,传递对象的引用被认为是不鼓励的吗?

我是一个自学的程序员,和很多其他新手一样,我曾经在经典的“在表单之间传递数据”问题上苦苦挣扎过。大约一年前,当我在Java中构建我的第一个聊天应用程序时,我再次遇到了这个问题。我通过将运行中的GUI的引用传递给另一个类的构造函数来解决了这个问题,以便它可以直接操作GUI。例如:\n

class GUI {
    Writer w;
    void initGUI() {
        w = new Writer(this);
    }
}
class Writer {
    GUI ui;
    public Writer(GUI ui) {
        this.ui = ui;
        ui.textBox.write("Yo");
        // 现在,我可以使用“ui.w”或“ui.w.ui.w.ui.w…”来代替“this”关键字
    }
}

\n我确信这是传输数据“向上流动”的最有效方法之一,但是当我在一个面向有相同问题的人的论坛上建议时,我遭到了一些指责(和一些赞扬)。那么在更大的应用程序中这样做可能会导致什么样混乱?当我看我的使用这种方法的应用程序时,我注意到它们非常务实和高效,但也有点过于有机(如果你愿意)和复杂(尤其是当有不同时间访问GUI的线程时等)。\n有没有更好的方法来做到这一点?在使用Qt时,我出于必要采取了不同的方法,但它更复杂,因为它使用了信号、槽和线程。请指点我正确的方向。谢谢。

0
0 Comments

在Java中传递一个对象的引用是不鼓励的。这个问题的出现是因为`Writer`类假设`GUI`类是固定的,意味着它将始终具有一个名为`textBox`的属性。根据目前的情况,`Writer`类不应负责访问和操作`GUI`类的属性。如果更改`GUI`中的内容,则还需要重新编写`Writer`类。可以重新编写`Writer`类,只需向`GUI`发送一个消息,因为它的责任只是告诉`GUI`要写什么,而不是如何写。然后由`GUI`来处理该消息。

class GUI {
     Writer w;
     void initGUI() {
        w = new Writer(this); 
     }
     void ReceiveMessage(string message) {
         this.textBox.text = message;
     }
}

`Writer`类:

class Writer {
    GUI ui;
    public Write(GUI ui) {
         this.ui = ui;
         // Don't send the message in the constructor.
    }
    // The program calls this function with whatever text the user enters.
    public void SendMessage(string message) {
        ui.ReceiveMessage(message);
        // Writer no longer depends on ui to have a textbox Element.
    }
}

上述代码可以通过使用接口进行改进。这样,可以将任何需要知道如何接收消息的内容传递给`Writer`:

interface IMessageReceiver {
    void ReceiveMessage(string message);
}

现在,`GUI`类成为`IMessageReceiver`:

class GUI implements IMessageReceiver {
     Writer w;
     void initGUI() {
        w = new Writer(this); 
     }
     public void ReceiveMessage(string message) {
         this.textBox.text = message;
     }
}

`Writer`类现在为:

class Writer {
    IMessageReceiver receiver;
    public Write(MessageReceiver receiver) {
         this.receiver = receiver;
         // Don't send the message in the constructor.
    }
    // The program calls this function with whatever text the user enters.
    public void SendMessage(string message) {
        receiver.ReceiveMessage(message);
    }
}

这里的区别是`Writer`不再关心它是否是一个`GUI`。只要它是一个知道如何接收消息的`IMessageReceiver`对象就可以。如果您对接口不熟悉,请阅读/研究一下。它们非常方便,甚至是必不可少的!

0
0 Comments

在Java中传递对象的引用被认为是不鼓励的,因为这违背了关注点分离的原则。关注点分离是指将业务逻辑与表示层分离,使得业务逻辑能够独立于GUI进行测试,并且能够在不修改后端的情况下更改前端GUI。

为了实现关注点分离,有许多设计模式可以使用,其中之一就是模型-视图-控制器(Model View Controller,MVC)模式。在MVC模式中,不直接与GUI进行交互,而是直接与模型进行交互。

通过将运行中的GUI的引用传递给另一个类的构造方法,以便直接操作GUI,可以解决这个问题。以下是解决方法的示例代码:

public class GUIManipulator {
    private GUI gui;
    public GUIManipulator(GUI gui) {
        this.gui = gui;
    }
    public void manipulateGUI() {
        // manipulate the GUI using the reference
        gui.setText("Hello, World!");
    }
}
public class GUI {
    private String text;
    public void setText(String text) {
        this.text = text;
    }
    public String getText() {
        return text;
    }
}
public class Main {
    public static void main(String[] args) {
        GUI gui = new GUI();
        GUIManipulator manipulator = new GUIManipulator(gui);
        manipulator.manipulateGUI();
        System.out.println(gui.getText()); // Output: Hello, World!
    }
}

通过将GUI的引用传递给GUIManipulator类的构造方法,GUIManipulator类就可以直接操作GUI,从而实现了解耦业务逻辑和表示层的目的。这样,就可以在不修改GUI的情况下修改业务逻辑,并且可以在测试时独立于GUI进行测试。

在Java中不鼓励传递对象的引用,因为这违背了关注点分离的原则。为了解决这个问题,可以使用设计模式,如MVC模式,并将对象的引用传递给需要操作该对象的类的构造方法。这样可以实现业务逻辑与表示层的解耦,使得业务逻辑可以独立于GUI进行测试,并且可以在不修改GUI的情况下修改业务逻辑。

0
0 Comments

在Java中,将对象的引用传递给另一个对象的做法是不被鼓励的。这种做法的主要问题是耦合性。Writer类本来应该是一个通用的、可重用的写入类,能够完成工作并在需要时发送关于其工作内容的事件,但是现在它与特定的GUI类紧密耦合在一起。

如果Writer类接受监听器(listener),就像所有的Swing组件一样,就可以在多个不同的GUI中重用Writer类,或者选择更新文本区域(text area)而不是文本字段(text field)。

另一种解决方法是使用“pull”而不是“push”。即让GUI调用Writer类的方法来查询其状态,而不是让Writer类更新GUI。虽然这种方法不一定总是可行的,但通常是可行的。

我假设“pull”方法需要使用线程?这样做没有问题,但正如你所说,它并不总是可行的。不过,如果一个GUI应用程序不仅仅是一个基本的计算器或者类似的应用,那么它通常应该使用并发编程。

不一定。假设Writer类的工作是接收一个OrderItem对象,将其保存在数据库中,并返回累计的订单金额。Writer类可以将结果写入GUI中的“累计订单金额”文本字段,或者只是将结果返回给GUI,由GUI本身来更新文本字段。

哦,这样就说得通了。我想我经常这样做,但通常不是在GUI编程的上下文中。

0