工厂模式(Factory Pattern)属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。术业有专攻就能很好的解释工厂模式,工厂模式就是专业生产商,我们拿来用就好了,不需要自己粗制乱遭,也不需要购买假冒伪劣产品,正规渠道拿货,质量有保障,安全,放心。
简单工厂模式简单工厂模式不属于23种设计模式。他是由一个工厂实例来创建我们所需要的实例,适用于工厂类创建对象较少的场景。客户端只需要传入合适的参数就能获取所需对象,不需要关心对象的创建逻辑。
代码示例:
/** * @description: 水果产品接口 * @author: lmc * @create: 2019-03-19 21:28 **/ public interface IFruits { /** * 水果名称 */ void getName(); /** * 水果颜色 */ void getColor(); /** * 水果味道 */ void getTaste(); } /** * @description: 苹果 * @author: lmc * @create: 2019-03-19 21:33 **/ public class Apple implements IFruits { @Override public void getName() { System.out.println(" 我是苹果,水果的一种"); } @Override public void getColor() { System.out.println(" 苹果是红色的"); } @Override public void getTaste() { System.out.println(" 苹果馋起来很甜很脆"); } } /** * @description: 香蕉 * @author: lmc * @create: 2019-03-19 21:33 **/ public class Banana implements IFruits { @Override public void getName() { System.out.println(" 我是香蕉,水果的一种"); } @Override public void getColor() { System.out.println(" 香蕉是黄色的"); } @Override public void getTaste() { System.out.println(" 香蕉馋起来很甜很滑"); } } /** * @description: 橙子 * @author: lmc * @create: 2019-03-19 21:33 **/ public class Orange implements IFruits { @Override public void getName() { System.out.println(" 我是橙子,水果的一种"); } @Override public void getColor() { System.out.println(" 橙子是橙色的"); } @Override public void getTaste() { System.out.println(" 橙子馋起来很甜水分足"); } }上面的代码 创建了一个水果接口,并且创建了三种水果分别实现了水果接口。
/** * @description: 水果工厂 * @author: lmc * @create: 2019-03-19 21:38 **/ public class FruitsFactory { /** * @description: * @param fruitsName * @return com.lmc.gp12380.pattern.factory.fruits.IFruits * @date 2019/5/23 15:44 * @author lmc */ public IFruits product(String fruitsName){ if(null != fruitsName && fruitsName != ""){ System.out.println("客户需求的水果是"+fruitsName); if("苹果".equals(fruitsName)){ System.out.println("水果工厂生产了苹果"); return new Apple(); } if("橙子".equals(fruitsName)){ System.out.println("水果工厂生产了橙子"); return new Orange(); } if("香蕉".equals(fruitsName)){ System.out.println("水果工厂生产了香蕉"); return new Banana(); } return null; }else{ return null; } } }简单工厂测试类
/** * @description: 水果工厂测试类 * @author: lmc * @create: 2019-03-19 21:50 **/ public class SimpleFactoryTest { public static void main(String[] args) { IFruits ifruits=null; FruitsFactory ifruitsFactory =new FruitsFactory(); ifruits = ifruitsFactory.product("香蕉"); getFruitsName(ifruits,"香蕉"); ifruits = ifruitsFactory.product("苹果"); getFruitsName(ifruits,"苹果"); ifruits = ifruitsFactory.product("橙子"); getFruitsName(ifruits,"橙子"); ifruits = ifruitsFactory.product("草莓"); getFruitsName(ifruits,"草莓"); } public static void getFruitsName(IFruits ifruits,String ifruitsName){ if(null != ifruits){ ifruits.getName(); }else{ if(null == ifruitsName || ifruitsName==""){ System.out.println("未指定水果让水果工厂生产"); }else{ System.out.println("水果工厂暂时无法生产"+ifruitsName); } } } }测试结果
客户需求的水果是香蕉 水果工厂生产了香蕉 我是香蕉,水果的一种 客户需求的水果是苹果 水果工厂生产了苹果 我是苹果,水果的一种 客户需求的水果是橙子 水果工厂生产了橙子 我是橙子,水果的一种 客户需求的水果是草莓 水果工厂暂时无法生产草莓上面的代码很简单,客户传入不同的参数,就能获取工厂对象能够生产的产品。业务需求中,工厂实例创建对象的业务逻辑往往是复杂的,运用简单工厂模式,客户端就不需要关心业务了,只要创建工厂对象,传入参数调用就能获取所需对象。
利:客户端调用简单,对于简单的业务逻辑清晰明了。
弊:
需要传参,容易出错。
传一个草莓参数,或者其他乱七八糟的参数,就得不到所需对象,出问题了
业务需要新的对象,需要更改工厂类,违背了开闭原则。
就像上面那样,我要一个草莓对象,工厂类暂时无法创建,需要修改代码。
工厂类的职责过重,不利于扩展复杂的产品结构(产品族和产品等级结构的概念后面会有说到)。
随着要生产的对象越来越多,工厂类变成了万能工厂了,违背了单一原则,不利于扩展和维护。