【設計模式】(十八)–結構型模式–過濾器模式
過濾器模式定義
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;
}
}
結果
實現解讀
通過過濾器模式實現王者榮耀中部分英雄列表的過濾。