惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

A
About on SuperTechFans
Y
Y Combinator Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Microsoft Security Blog
Microsoft Security Blog
aimingoo的专栏
aimingoo的专栏
I
InfoQ
C
Check Point Blog
IT之家
IT之家
MyScale Blog
MyScale Blog
Apple Machine Learning Research
Apple Machine Learning Research
Vercel News
Vercel News
Last Week in AI
Last Week in AI
GbyAI
GbyAI
P
Proofpoint News Feed
量子位
Stack Overflow Blog
Stack Overflow Blog
Microsoft Azure Blog
Microsoft Azure Blog
月光博客
月光博客
阮一峰的网络日志
阮一峰的网络日志
人人都是产品经理
人人都是产品经理
B
Blog
T
The Blog of Author Tim Ferriss
H
Help Net Security
云风的 BLOG
云风的 BLOG

博客园 - idior

每日代码 - 7/1 减小方法参数的依赖 每日代码 - 6/29 读写分离 每日代码 - 6/28 代码逻辑分组 每日代码 - 6/27 避免创建非法对象 Resume Covariance and Contravariance How does ElementName Binding work? Weird behavior of DataContext Inheritance How does ElementName Binding work – Part 3 InheritanceContext How does ElementName Binding work – Part 2 BindingExpression Logical Tree & Visual Tree Memory leak caused by EventHandle - weak event Resources on Debugging/Tracing WPF How does ElementName Binding work? - Part 1 Logical Tree & NameScope Inside WCF Runtime 有谁准备参加10月份的MVP聚会? MVP聚会 Practical .NET2 and C#2 翻译样章 Be evil or not?
每日代码 - 6/26 lambda表达式
idior · 2013-06-27 · via 博客园 - idior
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);
                    }
                }
        );
    }

    //...

}