分散式事務的兩階段提交(2PC)和三階段提交(3PC)是分散式系統中常用的事務管理協議,它們各自有優缺點。 兩階段提交(2PC) 流程: 準備階段(Prepare Phase): 協調者向所有參與者發送請求,詢問是否可以提交事務。 每個參與者執行本地事務操作,但不提交(僅預提交),並返回成功或失敗的 ...
過濾器模式(Filter Pattern)或標準模式(Criteria Pattern)是一種設計模式,這種模式允許開發人員使用不同的標準來過濾一組對象,通過邏輯運算以解耦的方式把它們連接起來。這種類型的設計模式屬於結構型模式,它結合多個標準來獲得單一標準。 雙龍物流
概要
意圖
用於將對象的篩選過程封裝起來,允許使用不同的篩選標準動態地篩選對象。
主要解決的問題
當需要根據多個不同的條件或標準來篩選一組對象時,過濾器模式提供了一種靈活的方式來定義這些條件,避免在客戶端代碼中硬編碼篩選邏輯。
使用場景
- 當對象集合需要根據不同的標準進行篩選時。
- 當篩選邏輯可能變化,或者需要動態地組合多個篩選條件時。
實現方式
- 定義篩選介面:創建一個篩選介面,定義一個篩選方法。
- 實現具體篩選器:為每個篩選標準實現篩選介面,封裝具體的篩選邏輯。
- 組合篩選器:允許篩選器之間進行組合,形成複雜的篩選邏輯。
關鍵代碼
- 篩選介面:定義篩選方法,如
matches()
。 - 具體篩選器類:實現篩選介面,封裝具體的篩選邏輯。
- 組合篩選器:實現篩選器的組合邏輯,如邏輯與(AND)、邏輯或(OR)等。
應用實例
- 圖書管理系統:根據作者、出版年份、類別等不同標準篩選圖書。
- 線上購物平臺:根據價格、品牌、用戶評分等條件篩選商品。
優點
- 封裝性:篩選邏輯被封裝在獨立的篩選器對象中。
- 靈活性:可以動態地添加、修改或組合篩選條件。
- 可擴展性:容易添加新的篩選標準,無需修改現有代碼。
缺點
- 複雜性:隨著篩選條件的增加,系統可能變得複雜。
- 性能問題:如果篩選器組合過於複雜,可能會影響性能。
使用建議
- 當篩選邏輯可能變化或需要根據不同標準動態篩選對象時,考慮使用過濾器模式。
- 在設計時,確保篩選器的介面和實現保持一致,以便於組合和擴展。
註意事項
- 確保篩選器的組合邏輯正確無誤,避免引入邏輯錯誤。
- 在實現時,考慮性能影響,特別是在處理大量數據時。
概要
過濾器模式包含以下幾個主要角色:
-
過濾器介面(Filter/Criteria):定義一個介面,用於篩選對象。該介面通常包含一個方法,用於根據特定條件過濾對象。
-
具體過濾器類(Concrete Filter/Concrete Criteria):實現過濾器介面,具體定義篩選對象的條件和邏輯。
-
對象集合(Items/Objects to be filtered):要被過濾的對象集合。這些對象通常是具有共同屬性的實例,例如一組人、一組產品等。
-
客戶端(Client):使用具體過濾器類來篩選對象集合。客戶端將對象集合和過濾器結合起來,以獲得符合條件的對象。
實現
我們將創建一個 Person 對象、Criteria 介面和實現了該介面的實體類,來過濾 Person 對象的列表。CriteriaPatternDemo 類使用 Criteria 對象,基於各種標準和它們的結合來過濾 Person 對象的列表。
步驟 1
創建一個類,在該類上應用標準。
Person.java
public class Person { private String name; private String gender; private String maritalStatus; public Person(String name,String gender,String maritalStatus){ this.name = name; this.gender = gender; this.maritalStatus = maritalStatus; } public String getName() { return name; } public String getGender() { return gender; } public String getMaritalStatus() { return maritalStatus; } }步驟 2
為標準(Criteria)創建一個介面。
Criteria.java
import java.util.List; public interface Criteria { public List<Person> meetCriteria(List<Person> persons); }步驟 3
創建實現了 Criteria 介面的實體類。
CriteriaMale.java
import java.util.ArrayList; import java.util.List; public class CriteriaMale implements Criteria { @Override public List<Person> meetCriteria(List<Person> persons) { List<Person> malePersons = new ArrayList<Person>(); for (Person person : persons) { if(person.getGender().equalsIgnoreCase("MALE")){ malePersons.add(person); } } return malePersons; } }CriteriaFemale.java
import java.util.ArrayList; import java.util.List; public class CriteriaFemale implements Criteria { @Override public List<Person> meetCriteria(List<Person> persons) { List<Person> femalePersons = new ArrayList<Person>(); for (Person person : persons) { if(person.getGender().equalsIgnoreCase("FEMALE")){ femalePersons.add(person); } } return femalePersons; } }CriteriaSingle.java
import java.util.ArrayList; import java.util.List; public class CriteriaSingle implements Criteria { @Override public List<Person> meetCriteria(List<Person> persons) { List<Person> singlePersons = new ArrayList<Person>(); for (Person person : persons) { if(person.getMaritalStatus().equalsIgnoreCase("SINGLE")){ singlePersons.add(person); } } return singlePersons; } }AndCriteria.java
import java.util.List; 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<Person> meetCriteria(List<Person> persons) { List<Person> firstCriteriaPersons = criteria.meetCriteria(persons); return otherCriteria.meetCriteria(firstCriteriaPersons); } }OrCriteria.java
import java.util.List; 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<Person> meetCriteria(List<Person> persons) { List<Person> firstCriteriaItems = criteria.meetCriteria(persons); List<Person> otherCriteriaItems = otherCriteria.meetCriteria(persons); for (Person person : otherCriteriaItems) { if(!firstCriteriaItems.contains(person)){ firstCriteriaItems.add(person); } } return firstCriteriaItems; } }步驟4
使用不同的標準(Criteria)和它們的結合來過濾 Person 對象的列表。