2010-08-03 116 views
1

我目前正在重构一些旧代码。我正在寻找有关在此使用的最佳设计模式的方向。 我在考虑工厂模式,但我不确定这是否是最好的方法。如何重构此代码

所以这里是伪码的简要概述。 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()); 

    } 
} 

让我知道你怎么看待这个代码需要重构的可维护性和重用或者是罚款,是什么?

感谢您的输入。

+0

我的Java是生锈的,但ArrayList需要两个类型的参数?究竟是什么? – 2010-08-03 17:15:44

+0

我的不好。我试图从实际代码中创建一个伪代码,并输入一个列表而不是一张地图。 – CoolBeans 2010-08-03 17:19:18

+0

无法理解您的代码。也似乎有很多编码错误 – YoK 2010-08-03 17:19:24

回答

5
// the following 3 methods are 90% similar 

既然你没有提供实际的代码,这就是你分解出的部分。所有的

+1

DRY - 不要重复自己 - 只做一次事情,没有98%的代码。 +1 – 2010-08-03 17:33:41

1

首先你需要用地图

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()); 

    } 
} 

接下来的事情就是例子是真的了逻辑毛孔更换名单,这是很难理解你真正想做的事情。

正在列表中执行一些操作,但在值1,2,3之下的结果始终是相同的。您在添加到列表时执行操作,而不是在您从该映射中检索列表时执行操作。

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

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

1

我想说的因素了90%成给调用者提供的服务的公共方法,然后有私人助手方法去照顾doFirst()doSecond(),等等这样的话,如果你添加更多的,你的公共API不会改变和破坏客户端。

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()); 

从而美孚的方法可以被删除,委托你的行动上课。 这是我的观点比以前的方法更灵活,因为您可以添加尽可能多的动作 - 即使在运行时。

如果命令派生类有很多类似的代码做一些事情为:

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

public class DoSomethingFirst extends DoSomething { 
    public list<NewThings> doSomething() { 
    super.doSomething(); //if possible 
    ... 
    } 
} 

我的2美分。

+0

有趣。过去我没有接触过这种模式。很高兴知道。感谢您的帮助伴侣。 – CoolBeans 2010-08-04 14:10:45