应该如何修改这个类才能遵循 DIP(依赖注入原则)?

发布于 2024-12-25 08:57:56 字数 1120 浏览 1 评论 0原文

如何修改此类以遵循 DIP(依赖倒置原则),以便删除构造函数中的两个 ArrayList 依赖项?接口应该如何?

让我困惑的一件事是,新引用指向 ArrayList而不仅仅是类的构造函数。而且我不知道如何处理这种情况...

package mvc.controllers;

import java.util.ArrayList;
import mvc.models.AbstractModel;
import mvc.views.AbstractViewPanel;

public abstract class AbstractController {

    private ArrayList<AbstractViewPanel> registeredViews;
    private ArrayList<AbstractModel> registeredModels;

    public AbstractController() {
        registeredViews = new ArrayList<AbstractViewPanel>();
        registeredModels = new ArrayList<AbstractModel>();
    }

    public void addModel(AbstractModel model) {
        registeredModels.add(model);
        model.addPropertyChangeListener(this);
    }

    public void removeModel(AbstractModel model) {
        registeredModels.remove(model);
        model.removePropertyChangeListener(this);
    }

    public void addView(AbstractViewPanel view) {
        registeredViews.add(view);
    }

    public void removeView(AbstractViewPanel view) {
        registeredViews.remove(view);
    }
    ...
}

How I can modify this class to follow DIP (Dependency Inversion Principle) in order to remove the two ArrayList dependencies in the constructor? How should the interfaces be?

One thing that confuses me is that the new references points to an ArrayList<type> not just the constructor of a class. And I don't know how to handle that situation...

package mvc.controllers;

import java.util.ArrayList;
import mvc.models.AbstractModel;
import mvc.views.AbstractViewPanel;

public abstract class AbstractController {

    private ArrayList<AbstractViewPanel> registeredViews;
    private ArrayList<AbstractModel> registeredModels;

    public AbstractController() {
        registeredViews = new ArrayList<AbstractViewPanel>();
        registeredModels = new ArrayList<AbstractModel>();
    }

    public void addModel(AbstractModel model) {
        registeredModels.add(model);
        model.addPropertyChangeListener(this);
    }

    public void removeModel(AbstractModel model) {
        registeredModels.remove(model);
        model.removePropertyChangeListener(this);
    }

    public void addView(AbstractViewPanel view) {
        registeredViews.add(view);
    }

    public void removeView(AbstractViewPanel view) {
        registeredViews.remove(view);
    }
    ...
}

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

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

发布评论

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

评论(3

奈何桥上唱咆哮 2025-01-01 08:57:56

要以依赖关系反转方式执行此操作,您可以执行以下操作之一:

  1. 在构造函数中给出对列表的依赖关系:

    公共抽象类 AbstractController {
    
    私有列表注册观看次数;
    私有列表注册模型;
    
    公共 AbstractController(ListregisteredViews, ListregisteredModels) {
        this.registeredViews = 注册视图;
        this.registeredModels = 注册模型;
    }
    
  2. 为列表添加修改器(setter):

    公共抽象类 AbstractController {
    
    私有列表注册视图;
    私有列表注册模型;
    
    公共抽象控制器(){
    }
    
    公共无效setRegisteredViews(列表视图){
       this.registeredViews = 视图;
    }
    
    公共无效setRegisteredModels(列表模型){
       this.registeredModels = 模型;
    }
    

顺便说一句,我将 ArrayList 更改为 List。无需引入对 List 实现的依赖。

To do it in Dependency Inversion -way, you could do one of the following:

  1. Dependencies to the lists are given in the constructor:

    public abstract class AbstractController {
    
    private List<AbstractViewPanel> registeredViews;
    private List<AbstractModel> registeredModels;
    
    public AbstractController(List<AbstractViewPanel> registeredViews, List<AbstractModel> registeredModels) {
        this.registeredViews = registeredViews;
        this.registeredModels = registeredModels;
    }
    
  2. Add mutators (setters) for the lists:

    public abstract class AbstractController {
    
    private List<AbstractViewPanel> registeredViews;
    private List<AbstractModel> registeredModels;
    
    public AbstractController() {
    }
    
    public void setRegisteredViews(List<AbstractViewPanel> views) {
       this.registeredViews = views;
    }
    
    public void setRegisteredModels(List<AbstractModel> models) {
       this.registeredModels = models;
    }
    

Btw, I changed the ArrayLists to Lists. There's no need to introduce a dependency on the List implementation.

葬シ愛 2025-01-01 08:57:56

目前尚不清楚您要删除什么依赖项,但如果您想删除显式 ArrayList 实例化,您可以使用构造函数注入:

private final List<AbstractViewPanel> registeredViews;
private final List<AbstractModel> registeredModels;

public AbstractController(final List<AbstractViewPanel> registeredViews,
        final List<AbstractModel> registeredModels) {
    this.registeredViews = registeredViews;
    this.registeredModels= registeredModels;
}

It's not really clear what dependency you're trying to remove, but if you want to remove the explicit ArrayList instantiation, you could use constructor injection:

private final List<AbstractViewPanel> registeredViews;
private final List<AbstractModel> registeredModels;

public AbstractController(final List<AbstractViewPanel> registeredViews,
        final List<AbstractModel> registeredModels) {
    this.registeredViews = registeredViews;
    this.registeredModels= registeredModels;
}
红墙和绿瓦 2025-01-01 08:57:56

我不会将列表注入到对象中,从而破坏封装,只是为了通过模拟列表来对其进行单元测试。该列表不是外部依赖项。它是班级内部的一部分。

如果您想对此类进行单元测试,请测试使用列表中存储的对象的方法是否确实按应有的方式使用它们。您还应该测试当您更改已添加到控制器的模型的属性时是否调用 propertyChange 方法。

或者,您可以添加 getView()getModels() 方法(可能受保护),以测试添加是否按预期工作。

I wouldn't inject a List into an object, and thus break encapsulation, just for the sake of unit testing it by mocking the list. The List is not an external dependency. It's part of the internals of the class.

If you want to unit-test this class, test that the method who uses the objects stored in the list do actually use them as they should. You should also test that the propertyChange method is called when you change a property of a model that you've added to the controller.

Or you could add a getView() and a getModels() method (potentially protected), to test that the addition worked as expected.

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