最近看Android源码用到的一些设计模式,做一个简单的记录。设计模式分为创建型模式、结构型模式、行为模式。创建型模式提供了如何创建对象的方法,而不涉及对象的内部结构和对象之间的交互。工厂模式为创建型模式。
作用:将对象的创建逻辑封装在一个工厂类中,而不是在客户端代码中直接实例化对象
简单工厂模式(Simple Factory Pattern):
不是一种设计模式,而是一种编程习惯的总结,是工厂模式的基础。
包含的角色:
- 抽象产品 :定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品 :实现或继承抽象产品的子类
- 具体工厂 :提供创建产品的方法,调用者通过该方法来获取产品
案例
需求:设计一款手机制造系统,可以制造安卓和苹果两种机型
思路:
- 抽象产品 :创建一个手机接口 规范
- 具体产品 :分别创建安卓和苹果分别继承手机接口
- 具体工厂 :提供创建手机的方法,该方法会根据用户的输入的手机类型创建出对应的手机
interface Phone{ void creatSoft(); void creatHard(); void assemble(); } class Android implements Phone{ @Override public void creatSoft() { System.out.println("Android creatSoft"); } @Override public void creatHard() { System.out.println("Android creatHard"); } @Override public void assemble() { System.out.println("Android assemble"); } } class Ios implements Phone{ @Override public void creatSoft() { System.out.println("Ios creatSoft"); } @Override public void creatHard() { System.out.println("Ios creatHard"); } @Override public void assemble() { System.out.println("Ios assemble"); } }Android android = new Android(); android.creatSoft();
优点:对象的创建和业务逻辑分开,避免修改客户端代码,易扩展
缺点:新增产品时,类爆炸
工厂方法模式(Factory Method Pattern):
工厂方法模式定义了一个创建对象的接口,但由子类决定实例化哪个类。工厂方法将对象的创建延迟到子类。
案例
需求:设计一款手机制造系统,可以制造安卓和苹果两种车型
思路:
- 抽象产品 :创建一个手机接口 规范
- 具体产品 :分别创建安卓和苹果分别继承手机接口
- 抽象工厂: 提供了创建手机的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
- 具体工厂 :提供创建手机的方法,该方法会根据用户的输入的手机类型创建出对应的手机
interface Phone{ void creatSoft(); void creatHard(); void assemble(); } class Android implements Phone{ @Override public void creatSoft() { System.out.println("Android creatSoft"); } @Override public void creatHard() { System.out.println("Android creatHard"); } @Override public void assemble() { System.out.println("Android assemble"); } } class Ios implements Phone{ @Override public void creatSoft() { System.out.println("Ios creatSoft"); } @Override public void creatHard() { System.out.println("Ios creatHard"); } @Override public void assemble() { System.out.println("Ios assemble"); } } class PhoneFactory{ public Phone getPhone(String phoneType){ if(phoneType == null){ return null; } if (phoneType.equalsIgnoreCase("ios")){ return new Ios(); }else if(phoneType.equalsIgnoreCase("ios")){ return new Android(); } return null; } }PhoneFactory phoneFactory = new PhoneFactory() {}; Phone phone1 = phoneFactory.getPhone("Android"); phone1.creatSoft();
优点:用户只需知道具体工厂名就可以拿到产品,无需知道产品的具体创建过程
缺点:类爆炸
创建者模式:
将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。
角色:
- 抽象建造者类(Builder):这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的部件对象的创建。
- 具体建造者类(ConcreteBuilder):实现 Builder 接口,完成复杂产品的各个部件的具体 创建方法。在构造过程完成后,提供产品的实例。
- 产品类(Product):要创建的复杂对象。
- 指挥者类(Director):调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产 品的信息,只负责保证对象各部分完整创建或按某种顺序创建。
案例:
SQL查询生成器
//产品类 class SqlQuery { private String select; private String from; public SqlQuery (String select, String from) { this.from = from; this.select = select; } @Override public String toString() { StringBuffer sb = new StringBuffer(); sb.append("SELECT").append(select).append("FROM").append(from); return sb.toString(); } } //抽象创建者 abstract class SqlQueryBuilder{ protected SqlQuery sqlQuery; public void creatsqlQuery(String select, String from){ sqlQuery = new SqlQuery(select, from); } public SqlQuery getSqlQuery(){ return sqlQuery; } abstract void buildwhere(); } //具体创建者 class MysqlQueryBuilder extends SqlQueryBuilder{ @Override void buildwhere() { System.out.println(" MysqlQueryBuilder buildwhere"); } } class Mysql2QueryBuilder extends SqlQueryBuilder{ @Override void buildwhere() { System.out.println(" Mysql2QueryBuilder buildwhere"); } } //指挥者 class SqlQueryDirector{ private SqlQueryBuilder sqlQueryBuilder; public void setSqlQueryBuilder(SqlQueryBuilder sqlQueryBuilder){ this.sqlQueryBuilder = sqlQueryBuilder; } public void buildSqlBuildQuery(String select, String from){ sqlQueryBuilder.creatsqlQuery(select,from); sqlQueryBuilder.buildwhere(); } } class Client{ public static void main(String[] args){ SqlQueryBuilder mysqlquerybuild = new MysqlQueryBuilder(); SqlQueryBuilder mysql2QueryBuilder = new Mysql2QueryBuilder(); SqlQueryDirector sqlQueryDirector = new SqlQueryDirector(); sqlQueryDirector.setSqlQueryBuilder(mysqlquerybuild); sqlQueryDirector.buildSqlBuildQuery("*","table"); System.out.println("MySql Query" + mysqlquerybuild.getSqlQuery()); sqlQueryDirector.setSqlQueryBuilder(mysql2QueryBuilder); sqlQueryDirector.buildSqlBuildQuery("*","table1"); System.out.println("MySql2 Query" + mysqlquerybuild.getSqlQuery()); } }
建造者和工厂模式
区别:1、创建对象的复杂度
2、创建过程的分步和顺序