【问题标题】:Refactoring named beans to avoid code duplicity重构命名 bean 以避免代码重复
【发布时间】:2019-09-28 15:07:25
【问题描述】:

我检测到我在命名 bean 中系统地重复代码,所以我正在寻找一种方法来重新组织代码。

例如,我有三个命名的 bean,它们重复有关 Collars 的代码:

@Named(value = "dogController")
@ViewScoped
public class DogController implements Serializable {

    private Dog dog;  // Class Dog has a List<Collar>
    private Collar collar = new Collar();  // to be used in an XHTML form
    ....
    public addCollar(){
        //adds collar in dog
    }
    public removeCollar(){
        //removes collar from dog
    }
  }

所以 bean CatControllerBirdController 也有相同的代码。 Photo 也是如此,它们都重复代码。所以我认为我落后于一个模式。

我的直接步骤是为DogCatBird 创建一个interface HasCollar。然后我把重复的代码移到一个新的bean中:

@Named(value = "collarController")
@ViewScoped
public class CollarController implements Serializable {

    private HasCollar animal;
    private Collar collar = new Collar();  // to be used from the XHTML
    ....
    public addCollar(){
        //adds collar in animal
    }
    public removeCollar(){
        //removes collar from animal
    }
  }

到目前为止一切顺利。我现在的问题是:

  • 如何初始化animal?特别是因为同一个 XHTML 可能同时使用 DogCat。之前没问题,因为每种类型都有一个 Collar 对象。如果我必须注射它,我不知道如何注射。 (问题似乎与this 相似,但略有不同)。
  • 通常我会从 CollarController 扩展命名 bean 并重用所有功能,但这是不可能的,因为命名 bean 已经从另一个类继承。

那么,我该如何重构这种情况以尽可能减少重复代码?

(如果需要更多信息,请告诉我)

【问题讨论】:

  • "我如何初始化动物" _你将如何在纯 java 中做到这一点? _“通常我会从 CollarController 扩展命名的 bean” 不要...你会在普通 java 中做同样的事情吗?

标签: java jsf-2


【解决方案1】:

考虑DogCollar 之间的关系:a Dog has-a Collar

换句话说,addCollar()removeCollar()Dog 的操作,因此这些方法属于 Dog

 public class Dog {
    public addCollar(){
        //adds collar
    }
    public removeCollar(){
        //removes collar
    }
}

CatBird 等也是如此。此时代码仍然重复。

然后控制器可以简单地委托:

@Named(value = "dogController")
@ViewScoped
public class DogController implements Serializable {
    private Dog dog;  // Class Dog has a List<Collar>
    private Collar collar = new Collar();  // to be used in an XHTML form

    public addCollar(){
        //adds collar in dog
        dog.addCollar();
    }
    public removeCollar(){
        //removes collar from dog
        dog.removeCollar();
    }
}

CatBird 等控制器也是如此。

现在通用代码可以放在一个单独的类中如:

public class CollarHandler {
    private List<Collar> collars;
    public addCollar(){
        //adds collar
    }
    public removeCollar(){
        // remove a collar;
    }
}

Dog 的构造函数采用CollarHandler,其方法委托给处理程序:

public class Dog {
    private CollarHandler collarHandler;
    public Dog(CollarHandler collarHandler) {this.collarHandler = collarHandler; }

    public addCollar(){
        collarHandler.addCollar();
    }
    public removeCollar(){
        collarHandler.removeCollar();
    }
}

CatBird 等也是如此。

没有通用接口也没有继承。每个控制器仍然是独立的,但行为可以共享。

【讨论】:

  • Mmm... 但这看起来与我目前拥有的相似,除了实际的“添加”是在处理程序中进行的。但是代码仍然不是更短,而是更大。这是我有时在使用 OOP 时遇到的一个问题:与在处理程序中调用“CollarHandler.addCollar()”+ 在处理程序中执行实际的“addCollar”相比,在 dog 中执行实际的“addCollar”所需的精力更少。如果这只是为了使代码更易于维护,我不确定一种解决方案是否比另一种更好(注意我并不是说你的答案不正确,我只是暴露了我的一些担忧)
  • 重复的代码是从多个类中提取出来的,并移动到一个公共类中,现有的方法只是简单地委托给公共类。代码怎么变大了?
  • 因为现在我们在每个类中有 1 行(调用添加)+ 1 行(调用删除)+ 具有 2 个方法的全新类(1 个用于实际添加,1 个用于实际删除)。之前每个班级只有 1 行(实际添加)+ 1 行(实际删除)并且没有新班级
  • 我假设addCollar()removeCollar() 的详细信息并不重要。如果这些方法只是简单地将元素添加/删除到列表中,那么我的建议没有多大价值。
  • 是的,我想我正在寻找一种模式,其结果与从另一个类扩展的类一样好,因此代码根本不会重复。
猜你喜欢
  • 1970-01-01
  • 2014-03-07
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
  • 2012-06-28
  • 1970-01-01
相关资源
最近更新 更多