【设计模式 - 7】之过滤器模式(Filter)

过滤器模式详解


1      模式简介

过滤器模式(Filter)也叫标准模式(Criteria),这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。

 

2      实例

需求:

Person类有三个属性:姓名(Name)、性别(Gender)和婚姻情况(Marital),我们的系统中的一些功能需要对这些属性进行筛选,比如:

1)        得到所有的男性;

2)        得到所有的女性;

3)        得到所有还单身的人;

4)        得到所有已婚的人。

系统还希望能够将这些条件组合起来进行筛选,比如:

1)        得到所有已婚男性;

2)        得到所有单身女性;

3)        得到所有已婚的人或女性;

 

分析:

要解决这个问题,我们可以使用过滤器模式。使用过滤器模式解决这个问题的UML图如下图所示:

 

代码:

Person类中的代码:

public class Person {
   private String name; // 姓名
   private String gender; // 性别
   private String marital; // 婚姻情况
 
   public Person(String name, String gender, String marital) {
      this.name = name;
      this.gender = gender;
      this.marital = marital;
   }
 
   public String getName() {
      return name;
   }
 
   public void setName(String name) {
      this.name = name;
   }
 
   public String getGender() {
      return gender;
   }
 
   public void setGender(String gender) {
      this.gender = gender;
   }
 
   public String getMarital() {
      return marital;
   }
 
   public void setMarital(String marital) {
      this.marital = marital;
   }
 
   @Override
   public String toString() {
      return "Person [name=" + name + ",gender=" + gender + ", marital=" + marital + "]";
   }
}
Filter接口中的代码:

public interface Filter {
   // 根据传过来的Person列表,根据一定的条件过滤,得到目标集合
   List<Person> filter(List<Person> persons);
}
MaleFilter类中的代码:

public class MaleFilter implements Filter {
 
   @Override
   public List<Person> filter(List<Person> persons) {
      List<Person> result = new ArrayList<>();
      for (Person person : persons) {
         if ("MALE".equalsIgnoreCase(person.getGender())) {
            result.add(person);
         }
      }
      return result;
   }
}
处理“并且”逻辑的过滤器类FilterAnd类中的代码:

public class FilterAnd implements Filter {
   private Filter filter;
   private Filter otherFilter;
 
   public FilterAnd(Filter filter, Filter otherFilter) {
      this.filter = filter;
      this.otherFilter = otherFilter;
   }
 
   @Override
   public List<Person> filter(List<Person> persons) {
      List<Person> tmpList = filter.filter(persons);
      return otherFilter.filter(tmpList);
   }
}
处理“或者”逻辑的过滤器类FilterOr类中的代码:

public class FilterOr implements Filter {
   private Filter filter;
   private Filter otherFilter;
 
   public FilterOr(Filter filter, Filter otherFilter) {
      this.filter = filter;
      this.otherFilter = otherFilter;
   }
 
   @Override
   public List<Person> filter(List<Person> persons) {
      List<Person> tmpList1 = filter.filter(persons);
      List<Person> tmpList2 = otherFilter.filter(persons);
      for (Person person : tmpList2) {
         if (!tmpList1.contains(person)) {
            tmpList1.add(person);
         }
      }
      return tmpList1;
   }
}
测试类Test中的代码:

public class Test {
   public static void main(String[] args) {
      // 初始化数据
      List<Person> persons = new ArrayList<>();
      persons.add(new Person("霍一", "FEMALE", "MARRIED"));
      persons.add(new Person("邓二", "MALE", "MARRIED"));
      persons.add(new Person("张三", "MALE", "SINGLE"));
      persons.add(new Person("李四", "FEMALE", "MARRIED"));
      persons.add(new Person("王五", "MALE", "SINGLE"));
      persons.add(new Person("赵六", "FEMALE", "SINGLE"));
      persons.add(new Person("孙七", "MALE", "SINGLE"));
      persons.add(new Person("罗八", "MALE", "MARRIED"));
      persons.add(new Person("刘九", "FEMALE", "SINGLE"));
      persons.add(new Person("史十", "FEMALE", "SINGLE"));
      // 打印出所有男性的信息
      System.out.println("---------------------所有男性---------------------");
      List<Person> maleList = new MaleFilter().filter(persons);
      printList(maleList);
      // 打印出所有单身的信息
      System.out.println("---------------------所有单身---------------------");
      List<Person> singleList = new SingleFilter().filter(persons);
      printList(singleList);
      // 打印出所有已婚女性的信息
      System.out.println("--------------------所有已婚女性-------------------");
      List<Person> marriedFemaleList = new FilterAnd(new MarriedFilter(), new FemaleFilter()).filter(persons);
      printList(marriedFemaleList);
      // 打印出所有单身或女性的信息
      System.out.println("-------------------所有单身或女性------------------");
      List<Person> singleOrFemaleList = new FilterOr(new SingleFilter(), new FemaleFilter()).filter(persons);
      printList(singleOrFemaleList);
   }
 
   // 打印列表中的数据信息
   private static void printList(List<Person> list) {
      for (Person person : list) {
         System.out.println(person.toString());
      }
   }
}
测试代码如下图所示:


最后贴出过滤器模式的GitHub代码:【GitHub - Filter】


### 解决无法打开 MySQL MSI 文件的问题 如果遇到无法执行 MySQL 的 `.msi` 安装文件的情况,可能是由于以下几个原因引起的:系统权限不足、MSI Installer 组件损坏或缺失、或者安装包本身存在问题。以下是针对该问题的具体解决方案: #### 1. **检查系统权限** 确保当前运行的账户具有管理员权限。右键单击 `.msi` 文件并选择“以管理员身份运行”。如果没有看到此选项,则可能是因为系统的 UAC(用户帐户控制)被禁用[^1]。 #### 2. **验证 Windows Installer 是否正常工作** 有时,Windows Installer 可能会因为某些错误而失效。可以通过以下方法修复: - 打开命令提示符(以管理员身份运行),输入 `msiexec /unregister` 并回车。 - 接着再输入 `msiexec /regserver` 来重新注册 Windows Installer[^1]。 #### 3. **尝试使用命令行方式安装** 如果双击 `.msi` 文件无响应,可以尝试通过命令行手动触发安装过程。具体操作如下: ```cmd msiexec /i mysql_installer_community_V5.6.21.1_setup.1418020972.msi ``` 这一步可以帮助确认是否是图形界面加载失败导致的问题[^1]。 #### 4. **下载最新版本的 MySQL Installer** 旧版的 `.msi` 文件可能存在兼容性问题。建议访问官方站点下载最新的 MySQL Community Installer,并测试其安装效果。新版本通常会对已知问题进行修复[^2]。 #### 5. **清理残留的 MySQL 数据和配置** 如果有之前的未完全卸载的 MySQL 实例,可能会干扰新的安装流程。按照以下步骤彻底清除遗留数据: - 卸载现有的 MySQL 软件; - 删除 `%PROGRAMDATA%\MySQL` 和 `C:\Program Files\MySQL` 下的相关文件夹; - 如果存在自定义的数据目录(如 Data 文件夹),可以根据需求决定保留还是删除[^2]。 #### 6. **检查 .msi 文件完整性** 最后一种可能性是下载过程中出现了中断或其他异常情况,致使 `.msi` 文件受损。重新从可信源获取完整的安装程序副本是一个简单有效的办法[^1]。 --- ### 配置 my.ini 文件恢复原有数据库 当需要迁移原有的 MySQL 数据至新环境中时,可通过编辑 `my.ini` 文件实现这一点。例如,假设原数据存储于默认路径之外的位置,则需调整 datadir 参数指向实际地址。示例代码片段如下所示: ```ini [mysqld] datadir=D:/CustomData/MySQL/data/ port=3306 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES ``` 完成更改之后记得重启 MySQL 服务以便应用更新后的设置[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值