如何重构此代码

时间:2010-08-03 17:12:05

标签: java design-patterns refactoring

我目前正在重构一些旧代码。我正在寻找有关最佳设计模式的说明。 我在考虑工厂模式,但我不确定这是不是最好的方式。

所以这里是伪代码的简要概述。 Foo类具有核心业务逻辑。

Class Foo{
    private List<Things> stuff;
    private static Integer count; 
    //getter setter for stuff

    public Foo(List<Things> stuff){
        this.stuff = stuff; 
        this.count=1;
    }

    //the following 3 methods are 90% similar

    public List<Newthings> doSomeThingFirst(){
        //uses the list stuff and also increments the static member count for each entry in List<NewThings> based on certain conditions
    }

    public List<Newthings> doSomethingSecond(){
        //uses the list stuff and also increments the static member count for each entry in List<NewThings> based on certain conditions
    }

    public List<Newthings> doSomethingThird(){
        //uses the list stuff and also increments the static member count for each entry in List<NewThings> based on certain conditions
    }

    //in the future there may be doSomethingFourth(), doSomethingFifth() ... etc.

}


The caller of class Foo looks something like below.

Class SomeServiceImpl{
    public List<Things> getAllFoo(List<Things> stuff){
        Map<Integer,NewThings> fooList = new HashMap<Integer,NewThings>();
        Foo foo = new Foo(stuff);
        fooList.put(1,foo.doSomeThingFirst());
        fooList.put(2,foo.doSomeThingSecond());
        fooList.put(3,foo.doSomeThingThird());
            return new ArrayList<Things>(fooList.values());

    }
}

请告诉我您如何认为此代码应该针对可维护性和重用进行重构,或者它是否很好?

感谢您的投入。

5 个答案:

答案 0 :(得分:5)

 // the following 3 methods are 90% similar

由于您没有提供实际代码,这就是您要考虑的部分。

答案 1 :(得分:2)

命令模式可以在这里提供帮助。这是应用“封装变化”原则的典型案例。 代码是:

public interface Command {
  public List<NewThings> doSomething();
}

class DoSomethingFirst implements Command {
  public DoSomethingFirst(Foo foo) {
  ...
  }
  public List<NewThings> doSomething() {
  ...
  }
}

然后您的服务代码将

   fooList.put(1,(new DoSomeThingFirst(foo)).doSomething());
   fooList.put(2,(new DoSomeThingSecond(foo)).doSomething());
   fooList.put(3,(new DoSomeThingThird(foo)).doSomething());

因此可以删除Foo中的方法并将您的操作委托给类。 这是我的观点比以前的方法更灵活,因为您可以添加任意数量的操作 - 即使在运行时也是如此。

如果Command派生类有很多代码类似于:

public abstract class DoSomethingBasic implements Command {
...
// common code here.
...
} 

public class DoSomethingFirst extends DoSomething {
  public list<NewThings> doSomething() {
    super.doSomething(); //if possible
    ...
  }
}
我的2美分。

答案 2 :(得分:1)

看起来BUILDER模式按顺序调用方法。

link http://en.wikipedia.org/wiki/Builder_pattern

可能会删除90%重复的STRATEGY模式

link http://en.wikipedia.org/wiki/Strategy_pattern

答案 3 :(得分:1)

首先,你需要用Map替换List

Class SomeServiceImpl{
    public getAllFoo(List<Things> stuff){
        Map<Integer,NewThings> fooMap = new HashMap<Integer,NewThings>();
        Foo foo = new Foo(stuff);
        fooMap.add(1,foo.doSomeThingFirst());
        fooMap.add(2,foo.doSomeThingSecond());
        fooMap.add(3,foo.doSomeThingThird());

    }
}

接下来的事情是,这个例子真的是没有逻辑的毛孔,很难理解你真正想做的事情。

班级SomeServiceImpl正在列表中执行某些操作,但在值 1,2,3 下,您始终获得相同的结果。当您从该映射中检索列表时,无法在添加到列表时执行操作。

我认为你选择了错误的设计模式,而不是你应该使用Builder模式。

http://en.wikipedia.org/wiki/Builder_pattern#Java

答案 4 :(得分:1)

我会说将90%分解为一个向调用者提供服务的公共方法,然后使用私有帮助方法来处理doFirst()doSecond()等。这种方式,如果你添加更多它们,你的公共API将不会改变并破坏客户端。