public class CartViewRender { public static CartView renderMyCartView(Cart cart){ ErrorCodeEnum errorCode = null; try { cart.source = CartSource.My_Cart; CartFlowProccess.proccessMyCart(cart); } catch (TradeBaseException e) { errorCode = e.getErrorCodeEnum(); } catch(Exception e){ errorCode = ErrorCodeEnum.Cart_Error_System; } return RenderViewHelper.renderMyCartView(cart, errorCode); } public static CartView renderMobileMyCartView(Cart cart){ ErrorCodeEnum errorCode = null; try { CartFlowProccess.proccessMyCart(cart); } catch (TradeBaseException e) { errorCode = e.getErrorCodeEnum(); } catch(Exception e){ errorCode = ErrorCodeEnum.Cart_Error_System; } return RenderViewHelper.renderMyCartView(cart, errorCode); } public static CartView renderAddCartView(Cart cart){ ErrorCodeEnum errorCode = null; try { cart.source = CartSource.Add_Cart; CartFlowProccess.proccessAddCart(cart); } catch (TradeBaseException e) { errorCode = e.getErrorCodeEnum(); } catch(Exception e){ errorCode = ErrorCodeEnum.Cart_Error_System; } return RenderViewHelper.renderAddCartView(cart, errorCode); } //... }
这是一段典型的重复代码示例,前两个方法基本上是完全重复的,最后一个方法则是非常的类似。先把前两个方法改了,这个非常简单。
public static CartView renderMyCartViewFromNoSource(Cart cart) { ErrorCodeEnum errorCode = null; try { CartFlowProccess.proccessMyCart(cart); } catch (TradeBaseException e) { errorCode = e.getErrorCodeEnum(); } catch(Exception e){ errorCode = ErrorCodeEnum.Cart_Error_System; } return RenderViewHelper.renderMyCartView(cart, errorCode); } public static CartView renderMyCartView(Cart cart){ cart.source = CartSource.My_Cart; return renderMyCartViewFromNoSource(cart); } public static CartView renderMobileMyCartView(Cart cart){ return renderMyCartViewFromNoSource(cart); }
比较麻烦的是最后一个方法如何消除重复,在.net的世界中有delegate和lambda表达式,这个问题会比较容易搞定,而java只能用匿名类了。
首先观察第三个方法与前两个方法的不同之处。其实只有两行代码不同,那么我们只要想办法将它们抽取出来就可以了。
先声明两个泛型接口,用于表示两个变化点:
interface Action<T> { void act(T t); } interface Func<T1,T2,T3> { T3 execute(T1 t1,T2 t2); }
然后使用这两个接口创建一个通用方法。
public static CartView renderCartView(Cart cart, Action<Cart> action, Func<Cart, ErrorCodeEnum, CartView> func) { ErrorCodeEnum errorCode = null; Action<Cart> cartAction = null; try { action.act(cart); } catch (TradeBaseException e) { errorCode = e.getErrorCodeEnum(); } catch (Exception e) { errorCode = ErrorCodeEnum.Cart_Error_System; } return func.execute(cart, errorCode); }
最后改写最后一个方法的实现,由于没有lambda表达式,代码看上去比较复杂些。
public static CartView renderAddCartView(Cart cart) { cart.source=CartSource.Add_Cart; return renderCartView(cart, new Action<Cart>() { @Override public void act(Cart cart) { CartFlowProccess.proccessAddCart(cart); } }, new Func<Cart, ErrorCodeEnum, CartView>() { @Override public CartView execute(Cart cart, ErrorCodeEnum errorCode) { return RenderViewHelper.renderAddCartView(cart, errorCode); } } ); }
如果你用了Intellj IDE,它会帮你自动做一些代码格式化。Java8之后就能支持的更好了。
最后完整代码如下:
public class CartViewRender { public static CartView renderCartView(Cart cart, Action<Cart> action, Func<Cart, ErrorCodeEnum, CartView> func) { ErrorCodeEnum errorCode = null; Action<Cart> cartAction = null; try { action.act(cart); } catch (TradeBaseException e) { errorCode = e.getErrorCodeEnum(); } catch (Exception e) { errorCode = ErrorCodeEnum.Cart_Error_System; } return func.execute(cart, errorCode); } public static CartView renderMyCartViewFromNoSource(Cart cart) { return renderCartView(cart, new Action<Cart>() { @Override public void act(Cart cart) { CartFlowProccess.proccessMyCart(cart); } }, new Func<Cart, ErrorCodeEnum, CartView>() { @Override public CartView execute(Cart cart, ErrorCodeEnum errorCode) { return RenderViewHelper.renderMyCartView(cart, errorCode); } } ); } public static CartView renderMyCartView(Cart cart) { cart.source = CartSource.My_Cart; return renderMyCartViewFromNoSource(cart); } public static CartView renderMobileMyCartView(Cart cart) { return renderMyCartViewFromNoSource(cart); } public static CartView renderAddCartView(Cart cart) { cart.source=CartSource.Add_Cart; return renderCartView(cart, new Action<Cart>() { @Override public void act(Cart cart) { CartFlowProccess.proccessAddCart(cart); } }, new Func<Cart, ErrorCodeEnum, CartView>() { @Override public CartView execute(Cart cart, ErrorCodeEnum errorCode) { return RenderViewHelper.renderAddCartView(cart, errorCode); } } ); } //... }