Android中工厂模式
2017-10-20 16:53
162 查看
设计模式系列:
0. Android开发常用设计模式;
1. Android中单例模式;
2. Android中建造者(builder)模式;
3. Android中观察者模式;
4. Android中原型模式;
5. Android中策略模式;
6. Android中工厂模式;
7. Android中代理模式;
8. Android中装饰者模式;
9. Android中适配器模式;
小白:毛毛哥,我最近在看工厂模式的时候一脸懵逼
三毛:”我的白,上次在讲观察者模式的时候我就说你接口不熟了,现在工厂模式中还要用到抽象类,估计你也不熟,你还是把接口和抽象类搞清楚,弄熟在看工厂模式吧,不然晕乎乎,看不懂是正常的”
小白:
给我讲讲嘛,可爱的毛毛哥,甩甩的毛毛哥,裤裤的毛毛哥,风一样的毛毛哥
三毛:
唉,那我就尽量有多简单就多简单给你讲讲吧,谁叫你是我的白呢
欺负我不会其他写法,呜呜~~,我只能像下面那样去写
小白:
三毛:“假设在登陆前,要做10个步骤的操作处理,才能进一步登陆,你上面代码是不是像下面这样”
三毛:“假设有10个界面(或者更多)都要用到登陆,你岂不是要10个界面都写那么多代码,你不累啊”
小白:我没想过登陆前还有可能存在那么多操作,所以就把对象new出来直接用了- -
三毛:“不扯蛋了,进入主题,工厂模式分为下面4种,我们一个一个来解释”
1、静态工厂模式
==>静态工厂和简单工厂其实没啥区别,区别在于是否有static修饰方法
2、简单工厂模式
3、工厂方法模式 —->为了解决某些问题
4、抽象工厂模式 —->为了解决某些问题
1、静态工厂模式(优化小白你的代码)
2、简单工厂模式
三毛:“在上面代码中去掉static修饰方法,就是简单工厂模式了,看,多简单”
小白:
三毛:“
我很认真的在给你讲,要是怀疑你可以去看看大话设计模式中的简单工厂模式”
小白:老哥,我错了
三毛:“静态工厂模式或简单工厂模式如果考虑设计模式的开闭原则(对扩展开放,对修改封闭)就要在进一步优化,相当于升级成工厂方法模式”
小白:完全听不懂啊,为什么还要优化简单工厂模式或静态工厂模式
三毛:”当你把项目的登陆模块做完后,老板和你说QQ和微信登陆还不够,把其他第三方登陆都给我接上去,这时候除了添加ALogin、BLogin、CLogin…外,是不是还要在工厂类里把所有第三方登陆判断给加上去,有没有挺难看?还有最主要一点就是违反了设计模式的开闭原则,当需求变动后你就修改工厂类”
小白:
我觉得不难看哇,就算违反了设计模式的开闭原则,但也没啥影响吧
三毛:“
这个你自己去看看设计模式6大原则中的开闭原则吧,不想和你啰嗦了”
小白:哼,那也得等你给我讲完这个我在去看
3、工厂方法模式
小白:咦,这么简单啊,就把原来工厂类的方法抽取成接口而已啊
三毛:“你以为有多难呢,你说不太懂,肯定是因为你接口和抽象类不太熟而已”
小白:
三毛:”这样不管老板要加几个第三方登陆都没问题了,我们也不用去修改工厂类了,因为一个第三方登陆就是一个工厂类了嘛”
小白:
三毛:“小白,如果我这时候在加多一个需求,每一个第三方登陆都要绑定支付宝支付和微信支付,你会怎么做”
小白:我想到2种办法
1.在每个第三方登陆工厂直接加支付宝支付和微信支付方法,代码如下
三毛:”嗯,这个,确实可以满足新加的需求,但是你都用了工厂模式了,还用这么low的方法,偶的白”
小白:那就用第二种方法
2.多加个支付接口,修改下工厂,如下
三毛:”嗯,这一种方式使用了前面工厂方法模式思想,但是也会有一点点问题”
小白:有啥问题喔
三毛:”现在上面的工厂方法模式是一个第三方登陆对应一个工厂,然后工厂里面实现了初始化登陆和绑定支付的方法,我们也知道10个第三方登陆就有10个工厂类(10个啊,或者更多)”
小白:有点明白了毛毛哥意思了,一个第三方登陆对应一个工厂类虽然管理维护方便了,如果第三方登陆过多,也会造成类爆炸…
三毛:”嗯,如果一开始我们就换个角度去考虑设计的话,就会好很多”
小白:怎样换个角度设计呢
三毛:”一开始我们只考虑到只有初始化登陆(initLogin)一个类型的东西,所以设计成一个第三方登陆对应一个工厂类,现在变成初始化登陆和绑定支付2个类型的东西了,我们可以想象,N个第三方登陆和2个类型(初始化登陆和绑定支付)的东西对比,数量那个多呢”
小白:毛毛哥,那还用问,肯定是N个第三方登陆多啊
三毛:”嗯,因为这时候有初始化登陆(initLogin)和绑定支付2个不同类型的东西,我们可以考虑使用抽象工厂模式(抽象工厂模式思路)”
4、抽象工厂模式
小白:毛毛哥,上面就是抽象工厂模式嘛,我觉得和‘工厂方法模式’没啥区别吖
三毛:“怎么会没区别呢
”
小白:
三毛:“我这里就给你对比一下上面的工厂方法模式和抽象工厂模式区别”
工厂方法模式 抽象工厂方法模式
1.只有一个产品结构(登陆实例和登陆工厂都只有登陆类型) 1.多个产品结构(登陆和支付类型)
2.只有一个抽象产品类(登陆接口) 2.多个抽象产品类(登陆和支付接口)
3.每个具体工厂只能创建一个具体产品(如QQ工厂对应QQ登陆) 3.每个具体工厂可以创建多个具体产品(登陆和支付2个不同类型的产品中的多个登陆和支付)
小白:
三毛:“抽象工厂中如果要添加新的第三方登陆和其他支付,我们就可以在写多个新的接口,在写个新的工厂,像下面,类减少了,也符合对扩展开放,对修改封闭”
2、对扩展开放,对修改封闭;
3、因为使用了很多接口设计,降低了耦合(所有设计模式不基本都为了解耦嘛)
0. Android开发常用设计模式;
1. Android中单例模式;
2. Android中建造者(builder)模式;
3. Android中观察者模式;
4. Android中原型模式;
5. Android中策略模式;
6. Android中工厂模式;
7. Android中代理模式;
8. Android中装饰者模式;
9. Android中适配器模式;
小白:毛毛哥,我最近在看工厂模式的时候一脸懵逼
三毛:”我的白,上次在讲观察者模式的时候我就说你接口不熟了,现在工厂模式中还要用到抽象类,估计你也不熟,你还是把接口和抽象类搞清楚,弄熟在看工厂模式吧,不然晕乎乎,看不懂是正常的”
小白:
给我讲讲嘛,可爱的毛毛哥,甩甩的毛毛哥,裤裤的毛毛哥,风一样的毛毛哥
三毛:
唉,那我就尽量有多简单就多简单给你讲讲吧,谁叫你是我的白呢
一、常见需求场景
三毛:”小白,像平常的第三方登陆,如下面的图,要是给你模拟一下,你打算怎么去做”二、基本解决方法
小白:毛毛哥欺负我不会其他写法,呜呜~~,我只能像下面那样去写
//写个登陆接口 public interface ILogin { void login(); } //QQ登陆 public class QQLogin implements ILogin { @Override public void login() { System.out.println("QQ登陆..."); } } //WeiXin登陆 public class WeiXinLogin implements ILogin { @Override public void login() { System.out.println("WeiXin登陆..."); } } //使用 new QQLogin().login(); new WeiXinLogin().login();
三、基本解决方法存在的问题
三毛:“上面你自己看觉得没啥问题,但是我看漏洞百出喔”小白:
三毛:“假设在登陆前,要做10个步骤的操作处理,才能进一步登陆,你上面代码是不是像下面这样”
//写个登陆接口 public interface ILogin { void login(); } //QQ登陆 public class QQLogin implements ILogin { @Override public void login() { System.out.println("QQ登陆..."); } //操作A、B、C、D....后面其他省略了 public void A(){} } //WeiXin登陆 public class WeiXinLogin implements ILogin { @Override public void login() { System.out.println("WeiXin登陆..."); } //操作A、B、C、D....后面其他省略了 public void A(){} } //使用 QQLogin qqLogin = new QQLogin(); WeiXinLogin weiXinLogin = new WeiXinLogin(); qqLogin.A(); qqLogin.B(); ... qqLogin.login(); weiXinLogin.A(); weiXinLogin.B(); ... weiXinLogin.login();
三毛:“假设有10个界面(或者更多)都要用到登陆,你岂不是要10个界面都写那么多代码,你不累啊”
小白:我没想过登陆前还有可能存在那么多操作,所以就把对象new出来直接用了- -
四、工厂模式写法
工厂模式定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。三毛:“不扯蛋了,进入主题,工厂模式分为下面4种,我们一个一个来解释”
1、静态工厂模式
==>静态工厂和简单工厂其实没啥区别,区别在于是否有static修饰方法
2、简单工厂模式
3、工厂方法模式 —->为了解决某些问题
4、抽象工厂模式 —->为了解决某些问题
1、静态工厂模式(优化小白你的代码)
//多加个工厂类(之前的代码没变) public class LoginFactory { //在你基础上加个包装类,在包装类方法加个static修饰符就是静态工厂模式了(是不是想起了工具类的使用) public static ILogin initLogin(String loginType) { ILogin iLogin = null; switch (loginType) { case "QQ": //如果在登陆前有多余的操作可以在这里完成 iLogin = new QQLogin(); break; case "WeiXin": //如果在登陆前有多余的操作可以在这里完成 iLogin = new WeiXinLogin(); break; default: iLogin = null; break; } return iLogin; } /* 第二种写法(通过反射) public ILogin initLogin2(Class<? extends ILogin> clas) { ILogin iLogin = null; try { iLogin = clas.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return iLogin; }*/ } //使用 ILogin qqLogin = LoginFactory.initLogin("QQ"); ILogin weiXinLogin = LoginFactory.initLogin("WeiXin"); qqLogin.login(); weiXinLogin.login();
2、简单工厂模式
三毛:“在上面代码中去掉static修饰方法,就是简单工厂模式了,看,多简单”
public class LoginFactory { //去掉了static public ILogin initLogin(String loginType) { ILogin iLogin = null; switch (loginType) { case "QQ": //如果在登陆前有多余的操作可以在这里完成 iLogin = new QQLogin(); break; case "WeiXin": //如果在登陆前有多余的操作可以在这里完成 iLogin = new WeiXinLogin(); break; default: iLogin = null; break; } return iLogin; } /* 第二种写法(通过反射) public ILogin initLogin2(Class<? extends ILogin> clas) { ILogin iLogin = null; try { iLogin = clas.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return iLogin; }*/ } //使用 LoginFactory loginFactory = new LoginFactory(); ILogin qqLogin = loginFactory .initLogin("QQ"); ILogin weiXinLogin = loginFactory .initLogin("WeiXin"); qqLogin.login(); weiXinLogin.login();
小白:
三毛:“
我很认真的在给你讲,要是怀疑你可以去看看大话设计模式中的简单工厂模式”
小白:老哥,我错了
三毛:“静态工厂模式或简单工厂模式如果考虑设计模式的开闭原则(对扩展开放,对修改封闭)就要在进一步优化,相当于升级成工厂方法模式”
小白:完全听不懂啊,为什么还要优化简单工厂模式或静态工厂模式
三毛:”当你把项目的登陆模块做完后,老板和你说QQ和微信登陆还不够,把其他第三方登陆都给我接上去,这时候除了添加ALogin、BLogin、CLogin…外,是不是还要在工厂类里把所有第三方登陆判断给加上去,有没有挺难看?还有最主要一点就是违反了设计模式的开闭原则,当需求变动后你就修改工厂类”
小白:
我觉得不难看哇,就算违反了设计模式的开闭原则,但也没啥影响吧
三毛:“
这个你自己去看看设计模式6大原则中的开闭原则吧,不想和你啰嗦了”
小白:哼,那也得等你给我讲完这个我在去看
3、工厂方法模式
//上面其他代码不变,我们只把原来简单工厂模式或静态工厂模式工厂类优化一下 //把原来工厂类的方法抽取成接口(也可以是抽象类) public interface IFactory { ILogin initLogin(); } //QQ工厂类 public class QQFactory implements IFactory{ @Override public ILogin initLogin() { //如果在登陆前有多余的操作可以在这里完成 return new QQLogin(); } } //WeiXin工厂类 public class WeiXinFactory implements IFactory { @Override public ILogin initLogin() { //如果在登陆前有多余的操作可以在这里完成 return new WeiXinLogin(); } } //其他第三方登陆一样的,这里省略... //使用 QQFactory qqFactory = new QQFactory(); WeiXinFactory weiXinFactory = new WeiXinFactory(); qqFactory.initLogin().login(); weiXinFactory.initLogin().login();
小白:咦,这么简单啊,就把原来工厂类的方法抽取成接口而已啊
三毛:“你以为有多难呢,你说不太懂,肯定是因为你接口和抽象类不太熟而已”
小白:
三毛:”这样不管老板要加几个第三方登陆都没问题了,我们也不用去修改工厂类了,因为一个第三方登陆就是一个工厂类了嘛”
小白:
三毛:“小白,如果我这时候在加多一个需求,每一个第三方登陆都要绑定支付宝支付和微信支付,你会怎么做”
小白:我想到2种办法
1.在每个第三方登陆工厂直接加支付宝支付和微信支付方法,代码如下
//QQ工厂类 public class QQFactory implements IFactory{ @Override public ILogin initLogin() { //如果在登陆前有多余的操作可以在这里完成 return new QQLogin(); //在这里加多2个方法支付宝支付和微信支付 public void pay() { System.out.println("支付宝支付..."); } public void pay() { System.out.println("微信支付..."); } } //WeiXin工厂类 public class WeiXinFactory implements IFactory { @Override public ILogin initLogin() { //如果在登陆前有多余的操作可以在这里完成 return new WeiXinLogin(); } //在这里加多2个方法支付宝支付和微信支付 public void aliPay() { System.out.println("支付宝支付..."); } public void weiXinPay() { System.out.println("微信支付..."); } } //其他第三方登陆一样的,这里省略... //使用 QQFactory qqFactory = new QQFactory(); WeiXinFactory weiXinFactory = new WeiXinFactory(); qqFactory.initLogin().login(); weiXinFactory.initLogin().login(); qqFactory.aliPay(); qqFactory.weiXinPay(); weiXinFactory.aliPay(); weiXinFactory.weiXinPay();
三毛:”嗯,这个,确实可以满足新加的需求,但是你都用了工厂模式了,还用这么low的方法,偶的白”
小白:那就用第二种方法
2.多加个支付接口,修改下工厂,如下
//新加个支付接口(也可以是抽象类) public interface IPay { void pay(); } //支付宝支付 public class AliPay implements IPay { @Override public void pay() { System.out.println("支付宝支付..."); } } //微信支付 public class WeiXinPay implements IPay { @Override public void pay() { System.out.println("微信支付..."); } } //---------------------修改下工厂类-----------------// //在工厂方法模式中把原来工厂类的接口修改下(也可以是抽象类) public interface IFactory { ILogin initLogin(); //新加2个支付绑定 IPay bindAliPay(); IPay bindWeiXinPay(); } //QQ工厂类 public class QQFactory implements IFactory{ @Override public ILogin initLogin() { //如果在登陆前有多余的操作可以在这里完成 return new QQLogin(); //实现了新加的2个支付方法 @Override IPay bindAliPay() { return new AliPay(); } @Override IPay bindWeiXinPay() { return new WeiXinPay(); } } //微信工厂类也是一样的,这里省略了... //使用 QQFactory qqFactory = new QQFactory(); WeiXinFactory weiXinFactory = new WeiXinFactory(); qqFactory.initLogin().login(); weiXinFactory.initLogin().login(); //QQ qqFactory.bindAliPay().pay(); qqFactory.bindWeiXinPay().pay(); //微信 weiXinFactory.bindAliPay().pay(); weiXinFactory.bindWeiXinPay().pay();
三毛:”嗯,这一种方式使用了前面工厂方法模式思想,但是也会有一点点问题”
小白:有啥问题喔
三毛:”现在上面的工厂方法模式是一个第三方登陆对应一个工厂,然后工厂里面实现了初始化登陆和绑定支付的方法,我们也知道10个第三方登陆就有10个工厂类(10个啊,或者更多)”
小白:有点明白了毛毛哥意思了,一个第三方登陆对应一个工厂类虽然管理维护方便了,如果第三方登陆过多,也会造成类爆炸…
三毛:”嗯,如果一开始我们就换个角度去考虑设计的话,就会好很多”
小白:怎样换个角度设计呢
三毛:”一开始我们只考虑到只有初始化登陆(initLogin)一个类型的东西,所以设计成一个第三方登陆对应一个工厂类,现在变成初始化登陆和绑定支付2个类型的东西了,我们可以想象,N个第三方登陆和2个类型(初始化登陆和绑定支付)的东西对比,数量那个多呢”
小白:毛毛哥,那还用问,肯定是N个第三方登陆多啊
三毛:”嗯,因为这时候有初始化登陆(initLogin)和绑定支付2个不同类型的东西,我们可以考虑使用抽象工厂模式(抽象工厂模式思路)”
4、抽象工厂模式
//---------------------之前没变的代码区域---------------------// //登陆接口(没变)也可以是抽象类 public interface ILogin { void login(); } //QQ登陆实现(没变) public class QQLogin implements ILogin { @Override public void login() { System.out.println("QQ登陆..."); } } //WeiXin登陆实现(没变) public class WeiXinLogin implements ILogin { @Override public void login() { System.out.println("微信登陆..."); } } //其他第三方登陆同上,省略... //上面定义的支付接口(没变)也可以是抽象类 public interface IPay { void pay(); } //支付宝支付实现(没变) public class AliPay implements IPay { @Override public void pay() { System.out.println("支付宝支付..."); } } //微信支付实现(没变) public class WeiXinPay implements IPay { @Override public void pay() { System.out.println("微信支付..."); } } //其他支付同上,省略... //---------------------之前没变的代码区域end---------------------// //----------------工厂类和工厂接口换个角度设计(彻底改头换脸)----------------// //工厂接口(之前只有登陆一种类型方法,现在从登陆和绑定支付2种类型考虑设计接口)也可以是抽象类 public interface IFactory { // public interface IFactory { ILogin initQQLogin(); //======和之前对比》// ILogin initLogin(); ILogin initWeiXinLogin(); // } IPay bindAliPay(); IPay bindWeiXinPay(); } //工厂实现类 public class FactoryImp implements IFactory{ @Override public ILogin initQQLogin() { return new QQLogin(); } @Override public ILogin initWeiXinLogin() { return new WeiXinLogin(); } @Override public IPay bindAliPay() { return new AliPay(); } @Override public IPay bindWeiXinPay() { return new WeiXinPay(); } } //使用 FactoryImp factoryImp = new FactoryImp(); factoryImp.initQQLogin().login(); factoryImp.initWeiXinLogin().login(); factoryImp.bindAliPay().pay(); factoryImp.bindWeiXinPay().pay();
小白:毛毛哥,上面就是抽象工厂模式嘛,我觉得和‘工厂方法模式’没啥区别吖
三毛:“怎么会没区别呢
”
小白:
三毛:“我这里就给你对比一下上面的工厂方法模式和抽象工厂模式区别”
工厂方法模式 抽象工厂方法模式
1.只有一个产品结构(登陆实例和登陆工厂都只有登陆类型) 1.多个产品结构(登陆和支付类型)
2.只有一个抽象产品类(登陆接口) 2.多个抽象产品类(登陆和支付接口)
3.每个具体工厂只能创建一个具体产品(如QQ工厂对应QQ登陆) 3.每个具体工厂可以创建多个具体产品(登陆和支付2个不同类型的产品中的多个登陆和支付)
小白:
三毛:“抽象工厂中如果要添加新的第三方登陆和其他支付,我们就可以在写多个新的接口,在写个新的工厂,像下面,类减少了,也符合对扩展开放,对修改封闭”
//新加的新浪微博登陆 public class SinaLogin implements ILogin { @Override public void login() { System.out.println("新浪微博登陆..."); } } //新加的银行支付 public class BankPay implements IPay { @Override public void pay() { System.out.println("银行支付..."); } } //新加的接口(也可以是抽象类) public interface INewFactory { ILogin initSinaLogin(); IPay bindBankPay(); } //新加的抽象工厂类,在原来基础上面新加的接口,搞定 public class NewFactoryImp implements IFactory,INewFactory{ @Override public ILogin initQQLogin() { return new QQLogin(); } @Override public ILogin initWeiXinLogin() { return new WeiXinLogin(); } @Override public IPay bindAliPay() { return new AliPay(); } @Override public IPay bindWeiXinPay() { return new WeiXinPay(); } @Override public ILogin initSinaLogin() { return new SinaLogin(); } @Override public IPay bindBankPay() { return new BankPay(); } } //使用还是一样,省略...
五、工厂模式和普通写法区别
1、将对象的创建统一起来便于维护扩展和整体把控;2、对扩展开放,对修改封闭;
3、因为使用了很多接口设计,降低了耦合(所有设计模式不基本都为了解耦嘛)
相关文章推荐
- Android工厂模式
- 当Android遇见工厂模式
- Android设计模式--之工厂方法模式
- Android 进阶之路:常见设计模式之工厂模式
- 《Android之大话设计模式》--设计模式 创建型模式 第一章:简单工厂模式
- Android 工厂模式
- Android设计模式之工厂模式
- android设计模式-工厂模式
- 【Android】三种工厂模式简析
- Android 中设计模式 ----工厂模式
- android的工厂模式
- 第十三篇 Android 系统电话管理机制二--工厂模式
- Android 设计模式学习之工厂模式
- Android设计模式系列(8)--SDK源码之工厂方法模式
- Android 工厂模式,三种工厂模式的理解
- pyserial应用实例——对工厂模式下的Android手机收发AT命令
- 第十二篇 Android 系统电话管理机制一--工厂模式和代理模式
- Android设计模式(3)----工厂模式
- android源码之工厂设计模式
- android 设计模式之Listview不同类型Item利用工厂模式的复用