【设计模式】(十八)–结构型模式–过滤器模式
过滤器模式定义
Filter pattern or Criteria pattern is a design pattern that enables developers to filter a set of objects using different criteria and chaining them in a decoupled way through logical operations.
意思是:过滤器模式或“标准”模式是一种设计模式,使开发人员可以使用不同的标准过滤一组对象,并通过逻辑操作以解耦的方式链接它们。
过滤器模式结合多个标准来获得单一标准,通常有如下个元素
- Criteria 抽象过滤条件的接口
- Concrete Criteria 根据需要实现过滤条件接口的具体过滤条件
- Need Filter Object 需要过滤的对象
过滤器模式虽然不是我们常说的二十三种设计模式之一,但是在在应用中广泛使用。
过滤器模式的优点
过滤器模式结构清晰,解耦合
过滤器模式的使用场景
- 对大量类似对象有相同的过滤逻辑
过滤器模式的简单实现
类图
实现
public class Test {
public static void main(String[] args) {
List<Hero> heroList = getHeroList();
Criteria price8888Criteria = new Price8888Criteria();
Criteria price13888Criteria = new Price13888Criteria();
Criteria marksmanCriteria = new MarksmanCriteria();
Criteria price8888AndMarksmanCriteria = new AndCriteria(price8888Criteria, marksmanCriteria);
Criteria price8888OrPrice13888Criteria = new OrCriteria(price8888Criteria, price13888Criteria);
System.out.println("所有英雄列表");
printHeroInfo(heroList);
System.out.println("13888英雄");
List<Hero> price13888HeroList = price13888Criteria.meetCriteria(heroList);
printHeroInfo(price13888HeroList);
System.out.println("8888英雄");
List<Hero> price8888HeroList = price8888Criteria.meetCriteria(heroList);
printHeroInfo(price8888HeroList);
System.out.println("所有射手英雄");
List<Hero> marksmanList = marksmanCriteria.meetCriteria(heroList);
printHeroInfo(marksmanList);
System.out.println("价格为8888的射手英雄");
List<Hero> price8888MarksmanList = price8888AndMarksmanCriteria.meetCriteria(heroList);
printHeroInfo(price8888MarksmanList);
System.out.println("价格为8888或者13888的英雄");
List<Hero> price8888Or13888List = price8888OrPrice13888Criteria.meetCriteria(heroList);
printHeroInfo(price8888Or13888List);
}
private static List<Hero> getHeroList() {
List<Hero> heroList = new ArrayList<>();
heroList.add(new Hero("鲁班七号", 8888, Profession.MARKSMAN));
heroList.add(new Hero("狄仁杰", 8888, Profession.MARKSMAN));
heroList.add(new Hero("黄忠", 13888, Profession.MARKSMAN));
heroList.add(new Hero("王昭君", 8888, Profession.MAGE));
heroList.add(new Hero("马可波罗", 13888, Profession.MARKSMAN));
heroList.add(new Hero("貂蝉", 13888, Profession.MAGE));
heroList.add(new Hero("曜", 13888, Profession.ASSASSIN));
heroList.add(new Hero("老夫子", 8888, Profession.FIGHTER));
heroList.add(new Hero("李元芳", 13888, Profession.MARKSMAN));
return heroList;
}
private static void printHeroInfo(List<Hero> heroList) {
StringBuffer heroBuffer = new StringBuffer();
for (Hero hero : heroList) {
heroBuffer.append(hero.getName());
heroBuffer.append(";");
}
System.out.println(" " + heroBuffer.toString());
}
}
public interface Criteria {
List<Hero> meetCriteria(List<Hero> heroList);
}
public class Hero {
private String name;
private int price;
private Profession profession;
public Hero(String name, int price, Profession profession) {
this.name = name;
this.price = price;
this.profession = profession;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public Profession getProfession() {
return profession;
}
public void setProfession(Profession profession) {
this.profession = profession;
}
}
public enum Profession {
MAGE("mege", "法师"),
ASSASSIN("assassin","刺客"),
FIGHTER("fighter","战士"),
SUPPORT("support","辅助"),
TANK("tank","坦克"),
MARKSMAN("marksman", "射手");
private String profession;
private String zhName;
private Profession(String profession, String zhName) {
this.profession = profession;
this.zhName = zhName;
}
}
public class Price8888Criteria implements Criteria {
private static final int PRICE_8888 = 8888;
@Override
public List<Hero> meetCriteria(List<Hero> heroList) {
List<Hero> price8888 = new ArrayList<>();
for (Hero hero : heroList) {
if (PRICE_8888 == hero.getPrice()) {
price8888.add(hero);
}
}
return price8888;
}
}
public class Price13888Criteria implements Criteria {
private static final int PRICE_13888 = 13888;
@Override
public List<Hero> meetCriteria(List<Hero> heroList) {
List<Hero> price13888 = new ArrayList<>();
for (Hero hero : heroList) {
if (PRICE_13888 == hero.getPrice()) {
price13888.add(hero);
}
}
return price13888;
}
}
public class MarksmanCriteria implements Criteria {
@Override
public List<Hero> meetCriteria(List<Hero> heroList) {
List<Hero> maksmanList = new ArrayList<>();
for (Hero hero : heroList) {
if (Profession.MARKSMAN == hero.getProfession()) {
maksmanList.add(hero);
}
}
return maksmanList;
}
}
public class AndCriteria implements Criteria {
private Criteria criteria;
private Criteria otherCriteria;
public AndCriteria(Criteria criteria, Criteria otherCriteria) {
this.criteria = criteria;
this.otherCriteria = otherCriteria;
}
@Override
public List<Hero> meetCriteria(List<Hero> heroList) {
List<Hero> firstCriteriaPersons = criteria.meetCriteria(heroList);
return otherCriteria.meetCriteria(firstCriteriaPersons);
}
}
public class OrCriteria implements Criteria {
private Criteria criteria;
private Criteria otherCriteria;
public OrCriteria(Criteria criteria, Criteria otherCriteria) {
this.criteria = criteria;
this.otherCriteria = otherCriteria;
}
@Override
public List<Hero> meetCriteria(List<Hero> heroList) {
List<Hero> firstCriteriaItems = criteria.meetCriteria(heroList);
List<Hero> otherCriteriaItems = otherCriteria.meetCriteria(heroList);
for (Hero hero : otherCriteriaItems) {
if (!firstCriteriaItems.contains(hero)) {
firstCriteriaItems.add(hero);
}
}
return firstCriteriaItems;
}
}
结果
实现解读
通过过滤器模式实现王者荣耀中部分英雄列表的过滤。