设计模式之工厂模式
关于设计模式(主要是思想方面)
001.定义:
是一套反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结
002.目的:
为了可重用代码、让代码更容易被他人理解、保证代码可靠性
设计模式之工厂模式:
定义:
实例化对象,用工厂方法来代替new操作(创建我们需要的事物供我们使用)
分类:
工厂方法模式、抽象工厂模式
设计意图:
定义一个用于创建对象的接口,让子类决定实例化哪一些类。工厂方法使一个类的实例化延迟到其子类
特点:
将创建实例的工作与使用实例的工作分离开,低耦合
何时使用:
01.有一组类似的对象需要创建
02.编码时不能预见那种类型的对象需要创建实例
03.系统需要考虑扩展性,不应依赖于产品类实例如何被创建、组合和表达的细节
动机:
代码之间实现松耦合,一个对象的依赖对象的变化与本身无关
具体产品与客户端剥离,责任分割
生活场景:
01.比如你想做一两兰博基尼,你只需要告诉你的工厂我需要兰博基尼,工厂就会完成复杂的建造过程,最终把产品给你,也可以构建其他汽车,你只要告诉工长你需要什么车即可;
02.比如早晨起来刷牙洗脸,你用到的毛巾,你想要什么样的毛巾,你只需要去告诉工厂即可,它会返回你想要的毛巾,其他过程不用处理
工厂方法模式类图:
分析 ----> 客户端下命令需要生产水果,creator就负责生产水果(利用factory生产Iproduct水果,水果下面就有很多水果:product1、product2),具体是由客户端决定创建什么水果
抽象工厂模式类图:
分析 ----> 客户端发命令,我需要什么产品,工厂有两个类系,他们都能创建客户端的产品,可以理解为家族与系列产品
两种的区别与联系:
分析 ----> 抽象工厂模式是工厂方法模式的扩展
一个具体的工程可以生产一个对应的产品族,即工厂方法模式,多个工厂(产品族)就是抽象工厂模式
代码实现工厂方法模式:
Factory:
/** * 发型工厂:生成发型,不用客户端显式的调用 */ public class HairFactory { /** * 根据类型来创建对象 * * @param hair * @return */ public HairInterface getHair(String hair) { if ("left".equals(hair)) { return new LeftHair(); } else if ("right".equals(hair)) { return new RightHair(); } return null;//两种情况都不符合返回空 } /** * 根据类名生产对象 * * @param className * @return */ public HairInterface getHairByClass(String className) { try { //利用反射生成类的名称 HairInterface hair = (HairInterface) Class.forName(className).newInstance(); return hair;//获取成功 } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null;//获取失败返回null } }
产品(发型)接口:
/** * 发型接口:左偏分、右偏分等等 */ public interface HairInterface { //实现了:绘制发型 void draw(); }
具体的产品1(左偏分)
/** * 左偏分发型 */ public class LeftHair implements HairInterface { private static final String TAG = "LeftHair"; //画了一个左偏分发型 @Override public void draw() { Log.i(TAG, "draw: " + "左偏分发型"); } }
具体的产品2(右偏分)
/** * 有偏分发型 */ public class RightHair implements HairInterface { private static final String TAG = "RightHair"; //画了一个右偏分发型 @Override public void draw() { Log.i(TAG, "draw: " + "右偏分发型"); } }
创建实例:
private void showHair() { // 1.0:普通方法:每次需要一个发型都会创建一个新的hair,而且在客户端显式的调用,这样的 // 的代码既不利于维护也不利于管理 HairInterface left = new LeftHair(); left.draw(); //2.0:工厂模式创建:集中到HairFactory工厂中管理,产品的实现与客户端分离(不用显式的调用), // 现在只要告诉我需要左偏分或右偏分HairFactory就可以帮我创建 // 缺点:每多一种发型就要进行判断生成对应的发型,不能智能的根据发型的类型帮我们创建 HairFactory factory = new HairFactory(); HairInterface left = factory.getHair("left"); if (left != null) { left.draw(); } //3.0利用类的对象创建对象:如果我们再增加发型,我们只需要增加发型的类并且告知客户端我们有这个类, //我们就可以用这个类做事情 HairFactory factory = new HairFactory(); HairInterface left = factory.getHairByClass("com.test.okamiy.factorymode.myotee.LeftHair");//包名全路径 if (null != left) { left.draw(); } }
代码实现抽象工厂模式:
抽象工厂:PersonFactory
/** * 人物的实现接口 */ public interface PersonFactory { //男孩接口 public Boy getBoy(); //女孩接口 public Girl getGirl(); }
新年系类工厂:
/** * 新年系列加工厂 */ public class HNFactory implements PersonFactory { @Override public Boy getBoy() { return new HNBoy(); } @Override public Girl getGirl() { return new HNGirl(); } }
新年系列的具体对象(新年系列的女子)
/** * 新年系列的女孩子 */ public class HNGirl implements Girl { @Override public void drawWomen() { System.out.println("-----------------新年系列的女孩子--------------------"); } }
新年系列的具体对象(新年系列的男子)
/** * 新年系列的男孩子 */ public class HNBoy implements Boy { @Override public void drawMan() { System.out.println("-----------------新年系列的男孩子--------------------"); } }
圣诞系类工厂
/** * 圣诞系列加工厂 */ public class MCFctory implements PersonFactory { @Override public Boy getBoy() { return new MCBoy(); } @Override public Girl getGirl() { return new MCGirl(); } }
圣诞系列的具体对象(圣诞系列的女子)
/** * 圣诞系列的女孩 */ public class MCGirl implements Girl { @Override public void drawWomen() { System.out.println("-----------------圣诞系列的女孩--------------------"); } }
圣诞系列的具体对象(圣诞系列的男子)
/** * 圣诞系列的男孩子 */ public class MCBoy implements Boy { @Override public void drawMan() { System.out.println("-----------------圣诞系列的男孩子--------------------"); } }
女孩接口
/** * 女孩 */ public interface Girl { public void drawWomen(); }
男孩接口
/** * 男孩 */ public interface Boy { public void drawMan(); }
最终的测试:
private void test() { PersonFactory facoty = new HNFactory(); Boy boy = facoty.getBoy(); boy.drawMan(); }打印“-----------------新年系列的男孩子--------------------”
总结:通过以上两组代码做出分析
分析一:从两种工厂模式对比
a. 工厂方法模式是一种极端的抽象工厂模式,而抽象工厂模式可以看成是工厂模式的推广
b. 工厂方法模式用来创建一个产品的等级结构,而抽象工厂模式是用来创建多个产品的等级结构
c. 工厂方法模式只有一个抽象类,而抽象工厂模式有多个抽象产品类
d. 工厂模式方法是有一个抽象的父类定义的公共接口,子类负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类当中完成
e. 抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类,它针对的是有多个产品的等级结构,而工厂方法模式针对的是一个产品的等级结构
分析二:从工厂模式优点
a. 系统可以在不修改具体工厂角色的情况下引进新的产品
b. 客户端不必关心对象的创建,明确职责
c. 更好的理解面向对象的原则、面向接口编程,而不是面向实现编程
分析三:从工厂模式使用场景
a. 一个系统应当不依赖于产品实例的创建、组成和表示细节,这对于所有形态的工厂模式都是很重要的
b. 这个系统的产品有至少一个产品族
c. 同属于一个产品族的产品是设计在一起使用的,这一约束必须得在系统的设计中提现出来
d. 不同的产品以一系列的接口的面貌出现,从而使得系统不依赖与接口的实现细节
Last:本篇参照慕课网视频学习,有不懂的可以去慕课网看视频学习!
欢迎探讨学习,真心希望大家推荐好文共同成长!