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

推荐订阅源

有赞技术团队
有赞技术团队
G
Google Developers Blog
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
J
Java Code Geeks
P
Proofpoint News Feed
V
Visual Studio Blog
爱范儿
爱范儿
The Cloudflare Blog
博客园 - 叶小钗
V
V2EX
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
M
MIT News - Artificial intelligence
Microsoft Security Blog
Microsoft Security Blog
博客园 - 聂微东
H
Help Net Security
B
Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 【当耐特】
量子位
宝玉的分享
宝玉的分享
WordPress大学
WordPress大学
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

博客园 - 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);
                    }
                }
        );
    }

    //...

}