400 028 6601

建站动态

根据您的个性需求进行定制 先人一步 抢占小程序红利时代

Java进阶高手读书笔记1-行为参数化-创新互联

阅读完《Java进阶高手》第一章以及第二章;对书中知识进行复盘整理;主要记录:通过行为参数化传递代码

成都创新互联是一家专业的成都网站建设公司,我们专注成都网站设计、成都做网站、网络营销、企业网站建设,卖友情链接1元广告为企业客户提供一站式建站解决方案,能带给客户新的互联网理念。从网站结构的规划UI设计到用户体验提高,创新互联力求做到尽善尽美。

文章目录


正文内容:

一、行为参数化二、具体的业务场景1.初试牛刀:筛选绿苹果

具体的代码如下所示:

public class Apple {private Integer weight;

   private Color color;
   
   public Integer getWeight() {   return weight;
   }

   public void setWeight(Integer weight) {   this.weight = weight;
   }
   
   public Color getColor() {   return color;
   }

   public void setColor(Color color) {   this.color = color;
   }
}
enum Color {RED, GREEN
}
public class Filter {public static ListfilterGreenApple(Listinventory) {Listresult = new ArrayList<>();
        for (Apple apple : inventory) {if (GREEN.equals(apple.getColor())) {result.add(apple);
            }
        }
        return result;
    }
}

我们现在使用枚举类把苹果的颜色进行描述,然后将苹果抽象化为Apple类,包含颜色与重量的属性,最后构造过滤类,在过滤类里面给出具体的过滤绿色苹果的方法filterGreenApple;如果现在需求变了,农民需要过滤红色苹果,那么我们就需要将filterGreenApple方法复制一份,将方法名改为filterRedApple并且将里面的GREEN颜色改为RED;这个样子确实解决了问题,但是很明显,重复代码很多,并不是一个好的解决方法;一个好的解决方法是我们编写类似代码后,尽量对其进行抽象化

2.再展身手:把颜色作为参数

在上一版代码中,我们复制filterGreenApple方法完成对红色苹果的过滤,重复了filterGreenApple中大量代码,怎样避免这种问题的发生呢?好的解决方式是将颜色进行参数化,把颜色作为参数传递给过滤的方法,这样子就灵活适应变化了

public static ListfilterApple(Listinventory,Color color) {Listresult = new ArrayList<>();
        for (Apple apple : inventory) {if (color.equals(apple.getColor())) {result.add(apple);
            }
        }
        return result;
    }

现在解决了颜色筛选的问题,但是农民又跑过来告诉你:要是可以区分苹果的重量就太好了,重的苹果一般是重量大于150克
对于我们来说,这不是问题,我们只需要重新写一个过滤苹果的方法就可以了,我们现在复制filterApple方法,然后把形参color改为weight,然后把筛选条件改为weight大于150就完成了
具体代码如下所示:

public static ListfilterApple(Listinventory, Integer weight) {Listresult = new ArrayList<>();
        for (Apple apple : inventory) {if (apple.getWeight() >weight) {result.add(apple);
            }
        }
        return result;
    }

-我们可以将重量和颜色都作为参数传递给方法,然后给一个标记,根据标记去判断是通过颜色还是重量过滤苹果

3.第三次尝试:对你能想到的每个属性做筛选

我们将所有的苹果属性结合起来,如下所示:

public static ListfilterApple(Listinventory,
 Color color, Integer weight, boolean flag) {Listresult = new ArrayList<>();
        for (Apple apple : inventory) {if ((flag && color.equals(apple.getColor())) ||
             (!flag && apple.getWeight() >weight)) {result.add(apple);
            }
        }
        return result;
    }

现在的问题确实已经解决了,但是这个解决方案再差不过。首先客户端看上去糟糕透了,true和false是什么意思?此外,这个解决方案无法应对变化的需求,如果这位农民要求你对苹果的不同属性进行筛选,比如,大小,产地,形状等,该怎样处理?或者农民要求组合属性,做更复杂的查询,比如绿色的重苹果,又该怎么办?如今的情况,我们需要一种更好的解决方式来告诉过滤方法

4.行为参数化

一种可能的解决方式是对我们的选择标准进行建模:考虑的是苹果,需要根据Apple的某些属性(比如它是绿色的吗?重量超过150克吗?)来返回一个boolean值。我们把它称为谓词(即一个返回boolean值的函数)。让我们定义一个接口来对选择标准建模:

public interface ApplePredicate {boolean test(Apple apple);
}

选择苹果的不同策略,可以将这些标准看作filter方法的不同行为。刚才做的这些和策略设计模式相关,它让我们定义一族算法,把它们封装起来(称为策略),然后再运行的时候选择一个算法。在则这里,算法族就是ApplePredicate,不同的策略就是AppleGreenColorPredicate和AppleHeavyWeightPredicate

public class AppleGreenColorPredicate implements ApplePredicate{@Override
    public boolean test(Apple apple) {return GREEN.equals(apple.getColor());
    }
}
public class AppleHeavyWeightPredicate implements ApplePredicate {@Override
    public boolean test(Apple apple) {return apple.getWeight() >150;
    }
}

但是,该怎么利用ApplePredicate的不同实现呢?我们需要filterApple方法接受ApplePredicate对象,对Apple做条件测试。这就是行为参数化:让方法接受多种行为(策略)作为参数,并在内部使用,来完成不同行为

具体代码如下:

public class Filter {public static ListfilterApple(Listinventory,ApplePredicate predicate){ArrayListresult = new ArrayList<>();
        for (Apple apple:inventory){if(predicate.test(apple)){result.add(apple);
            }
        }
        return result;
    }
}

在这个例子中,唯一重要的代码是test方法的实现,正是它定义了filterApple方法的新行为。但是现在有一个遗憾,由于filterApple方法只接受对象,所以我们必须把代码包裹在ApplePredicate对象里。这种做法类似于内联“传递代码”,因为我们通过实现一个test方法来传递布尔表达式值。再JDK8之后我们可以使用Lambda进一步简化代码,这样子我们就无须定义多个ApplePredicate实现类了,从而去掉不必要的代码

具体代码如下:

public class Main {public static void main(String[] args) {Listresult1 = Filter.filterApple(new ArrayList(), (apple) ->GREEN.equals(apple.getColor()));
        Listresult2 = Filter.filterApple(new ArrayList(), (apple) ->apple.getWeight() >150);
    }
}

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


本文名称:Java进阶高手读书笔记1-行为参数化-创新互联
URL地址:http://www.bluegullmedia.com/article/ioheo.html

其他资讯

让你的专属顾问为你服务

0.4594s