-
2021-01-26 19:20:35
目录
java工厂模式
开篇声明,此理解为作者自身理解,不一定正确,如有错误请大佬们指正。
工厂模式,在作者看来,从现实生活来说,就是一个工厂,里面有N个车间,
每个车间会生产不同的产品,而租户只需要告诉这个工厂的老板我需要一个
什么产品,老板会去找到对应的车间返回给租户使用。
画个图理解:
如果使用java语言来描述则是,对具有相同动作,不同动作执行过程的一
类方法抽象出一个接口类,然后不同的实现类对接口类中的接口进行不同的
实现,并且编写一个工厂类,根据传入获取不同的实现类实例返回给调用者,调用者使用得到的实例
执行具体的方法。画个图(简单的加减乘除做示例,没怎么画过UML图,如果有错误,请见谅):
TestServiceImpl为业务逻辑实现类,MathFactory为工厂类,MathOperation为算法抽象接口类,
xxxOpreation为算法具体实现类,Class为java原生类,主要是要使用反射机制,会用到
工厂模式其实又分为三种
1.简单工厂模式:
不提供工厂接口只有工厂,提供实例的接口与实现
简单工厂模式(非静态)
就是提供一个接口interface,然后不同的实现类实现interface,再提供一个
工厂类,在工厂类中通过if条件判断,new出具体的实现类给调用者使用。
算法抽象接口
public interface MathOperation { double apply(int a, int b); }
算法抽象接口实现 (顺序-加减乘除):
import com.liu.test.factory.simplefactory.MathOperation; public class AddOperation implements MathOperation { @Override public double apply(int a, int b) { return (double) a + b; } }
import com.liu.test.factory.simplefactory.MathOperation; public class SubOperation implements MathOperation { @Override public double apply(int a, int b) { return (double) a - b; } }
import com.liu.test.factory.simplefactory.MathOperation; public class MultiplyOperation implements MathOperation { @Override public double apply(int a, int b) { return (double) a * b; } }
import com.liu.test.factory.simplefactory.MathOperation; public class DivideOperation implements MathOperation { @Override public double apply(int a, int b) { return (double) a / b; } }
工厂类:
import com.liu.test.factory.simplefactory.operation.AddOperation; import com.liu.test.factory.simplefactory.operation.DivideOperation; import com.liu.test.factory.simplefactory.operation.MultiplyOperation; import com.liu.test.factory.simplefactory.operation.SubOperation; public class MatchFactory { /** * 获得具体的操作类型 * @author kevin * @param operator : * @return java.util.Optional<com.liu.test.math.MathOperation> * @date 2021/1/25 11:36 */ public static Optional<MathOperation> getOperation(String operator) { MathOperation result = null; if("add".equals(operator)){ result = new AddOperation(); }else if("sub".equals(operator)){ result = new SubOperation(); }else if("multiply".equals(operator)){ result = new MultiplyOperation(); }else if("divide".equals(operator)){ result = new DivideOperation(); } return Optional.ofNullable(result); } }
使用类
MathOperation operation = MathFactory.getOperation(operator).orElseThrow(() -> new IllegalArgumentException("未知的操作")); result = operation.apply(first, second); return result;
简单工厂模式(静态):
就是在第一步的基础之上,将new的动作提出来,放到static块中执行,然后
将产生的实现类实例存放到静态的map中,用户调用的时候,直接从map中get对应的实例。
此模式不符合java的闭环原则(对扩展开放,对修改关闭)
静态只需调整工厂类即可,其他不变
import com.liu.test.factory.simplefactory.operation.AddOperation; import com.liu.test.factory.simplefactory.operation.DivideOperation; import com.liu.test.factory.simplefactory.operation.MultiplyOperation; import com.liu.test.factory.simplefactory.operation.SubOperation; import java.lang.reflect.InvocationTargetException; import java.util.Optional; import java.util.HashMap; import java.util.Map; public class MatchFactory { static Map<String, MathOperation> operationMap = new HashMap<>(); static { operationMap.put("add", new AddOperation()); operationMap.put("sub", new SubOperation()); operationMap.put("multiply", new MultiplyOperation()); operationMap.put("divide", new DivideOperation()); } public static Optional<Operation> getOperation(String operator) { return Optional.ofNullable(operationMap.get(operator)); } }
简单工厂模式(反射):
就是在第一步的基础之上,将new的动作去掉,换成反射的方式实现,将接口实现类统一放
在一个包中,然后统一命名规范,最后根据传入反射产生实例对象;用户调用的时候,直接传入
调用类型即可(统一实现类命名规范xxxOperation);只需调整工厂类即可,其他不变:
import java.lang.reflect.InvocationTargetException; import java.util.Optional; /** * * <p>Title:工厂类</p > * <p>ClassName:MatchFactory</p > * @author kevin * @date 2021/1/26 */ public class MathFactory { private MathFactory() { //do nothing } /** * 获得具体的操作类型 * @author kevin * @param operator : * @return java.util.Optional<com.liu.test.math.MathOperation> * @date 2021/1/26 11:36 */ public static Optional<MathOperation> getOperation(String operator) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { //因为类名首字母大写,所以转换操作类型为类名格式 String operate = operator.substring(0,1).toUpperCase() + operator.substring(1).toLowerCase(); Class<?> operation = Class.forName("com.liu.test.math.operation." + operate+"Operation"); return Optional.of((MathOperation)operation.getDeclaredConstructor().newInstance()); } }
2.工厂方法模式:
工厂提供接口与实现,实例提供接口与实现
为了解决第一种简单工厂模式的缺陷,产生了工厂方法模式,把工厂方法再次进行抽象,
为不同的实现类,提供不同的工厂,通过实现抽象工厂接口类的方法,实现不同工厂获取
业务实现类的不同实例,调用的时候,通过判断,使用不同的工厂(在简单工厂模式基础上)
抽象一个工厂接口:
import java.util.Optional; public interface MathFactoryInterface { Optional<MathOperation> getOperation(String operator) ; }
工厂接口实现(顺序-加减乘除):
import com.liu.test.factory.simplefactory.MathOperation; import com.liu.test.factory.factorymethod.MathFactoryInterface; import com.liu.test.factory.simplefactory.operation.AddOperation; import java.util.Optional; public class AddFactory implements MathFactoryInterface { @Override public Optional<MathOperation> getOperation() { return Optional.of(new AddOperation()); } }
import com.liu.test.factory.simplefactory.MathOperation; import com.liu.test.factory.factorymethod.MathFactoryInterface; import com.liu.test.factory.simplefactory.operation.SubOperation; import java.util.Optional; public class SubFactory implements MathFactoryInterface { @Override public Optional<MathOperation> getOperation() { return Optional.of(new SubOperation()); } }
import com.liu.test.factory.factorymethod.MathFactoryInterface; import com.liu.test.factory.factorymethod.operation.MultiplyOperation; import com.liu.test.factory.simplefactory.MathOperation; import java.util.Optional; public class MultiplyFactory implements MathFactoryInterface { @Override public Optional<MathOperation> getOperation() { return Optional.of(new MultiplyOperation()); } }
import com.liu.test.factory.factorymethod.MathFactoryInterface; import com.liu.test.factory.factorymethod.operation.DivideOperation; import com.liu.test.factory.simplefactory.MathOperation; import java.util.Optional; public class DivideFactory implements MathFactoryInterface { @Override public Optional<MathOperation> getOperation() { return Optional.of(new DivideOperation()); } }
将原有的工厂类MathFactory删除,使用类中调整-增加方法:
/** * 工厂方法模式 * @author kevin * @param operator : * @return com.liu.test.math.factorymethod.MathFactoryInterface * @date 2021/1/26 18:41 */ private MathFactoryInterface getFactory(String operator){ MathFactoryInterface result = null; if("add".equals(operator)){ result = new AddFactory(); }else if("sub".equals(operator)){ result = new SubFactory(); }else if("multiply".equals(operator)){ result = new MultiplyFactory(); }else if("divide".equals(operator)){ result = new DivideFactory(); } return Optional.ofNullable(result).orElseThrow(() -> new IllegalArgumentException("未知的操作")); }
使用类中调整-更改调用方式:
double result; MathFactoryInterface factory = getFactory(operator); MathOperation operation = factory.getOperation().orElseThrow(() -> new IllegalArgumentException("未知的操作")); result = operation.apply(first, second); return String.valueOf(result);
3.抽象工厂模式:
提供工厂的接口与实现,提供实例的接口与实现,有不同类型的实例(每个类型下有多个实例)
就是将操作归类,然后分别提供接口,同类下的具体事物实现同一个接口。然后抽象一个工厂接口,
按照不同类别,提供不同的待实现工厂方法;再提供具体的工厂实现类,实现抽象的工厂接口,并在不
同的方法(同一类事物的获取方法)中根据入参返回同类事物中具体的事物,最后给到调用者执行。
比如,阿里与百度都有开发人员与产品人员:
首先定义开发人员接口、产品人员接口:
/** * * <p>Title:开发人员</p > * <p>ClassName:IDeveloper</p > * @author kevin * @date 2021/1/27 */ public interface IDeveloper { String work(); String skill(); }
/** * * <p>Title:产品人员</p > * <p>ClassName:IProductor</p > * @author kevin * @date 2021/1/27 */ public interface IProductor { String work(); String skill(); }
开发人员接口实现:
import com.liu.test.factory.abstractfactory.cases.IDeveloper; public class AliDeveloper implements IDeveloper { @Override public String work() { return "我是阿里开发人员,我的工作是:为阿里服务!"; } @Override public String skill() { return "我是阿里开发人员,我的技能是:java、python、vue、react、js、c、c++、c#......无所不能!"; } }
import com.liu.test.factory.abstractfactory.cases.IDeveloper; public class BaiduDeveloper implements IDeveloper { @Override public String work() { return "我是百度开发人员,我的工作是:为百度服务!"; } @Override public String skill() { return "我是百度开发人员,我的技能是:人工智能、java、python、vue、react、js、c、c++、c#......我也无所不能!"; } }
产品人员接口实现:
import com.liu.test.factory.abstractfactory.cases.IProductor; public class AliProductor implements IProductor { @Override public String work() { return "我是阿里产品,我的工作是:为阿里提供优秀的产品!"; } @Override public String skill() { return "我是阿里产品,我的技能是:需求与利益的平衡能力,缜密的逻辑思维和较高的业务理解能力!"; } }
import com.liu.test.factory.abstractfactory.cases.IProductor; public class BaiduProductor implements IProductor { @Override public String work() { return "我是百度产品,我的工作是:为百度提供优秀的产品!"; } @Override public String skill() { return "我是百度产品,我的技能是:需求与利益的平衡能力,缜密的逻辑思维和较高的业务理解能力!"; } }
定义工厂接口:
import com.liu.test.factory.abstractfactory.cases.IDeveloper; import com.liu.test.factory.abstractfactory.cases.IProductor; import java.lang.reflect.InvocationTargetException; public interface IFactory { IProductor getProductor(String type) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException; IDeveloper getDeveloper(String type) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException; }
阿里工厂接口实现(反射获得实例):
import com.liu.test.factory.abstractfactory.IFactory; import com.liu.test.factory.abstractfactory.cases.IDeveloper; import com.liu.test.factory.abstractfactory.cases.IProductor; import java.lang.reflect.InvocationTargetException; import java.util.Optional; public class AliFactory implements IFactory { @Override public IProductor getProductor(String type) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //因为类名首字母大写,所以转换操作类型为类名格式 String operate = type.substring(0,1).toUpperCase() + type.substring(1).toLowerCase(); Class<?> operation = Class.forName("com.liu.test.factory.abstractfactory.cases.impl." + operate + "Productor"); return Optional.of((IProductor)operation.getDeclaredConstructor().newInstance()).orElseThrow(() -> new IllegalArgumentException("未知的公司")); } @Override public IDeveloper getDeveloper(String type) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //因为类名首字母大写,所以转换操作类型为类名格式 String operate = type.substring(0,1).toUpperCase() + type.substring(1).toLowerCase(); Class<?> operation = Class.forName("com.liu.test.factory.abstractfactory.cases.impl." + operate + "Developer"); return Optional.of((IDeveloper)operation.getDeclaredConstructor().newInstance()).orElseThrow(() -> new IllegalArgumentException("未知的公司")); } }
百度工厂接口实现(反射获得实例):
import com.liu.test.factory.abstractfactory.IFactory; import com.liu.test.factory.abstractfactory.cases.IDeveloper; import com.liu.test.factory.abstractfactory.cases.IProductor; import java.lang.reflect.InvocationTargetException; import java.util.Optional; public class BaiduFactory implements IFactory { @Override public IProductor getProductor(String type) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //因为类名首字母大写,所以转换操作类型为类名格式 String operate = type.substring(0,1).toUpperCase() + type.substring(1).toLowerCase(); Class<?> operation = Class.forName("com.liu.test.factory.abstractfactory.cases.impl." + operate + "Productor"); return Optional.of((IProductor)operation.getDeclaredConstructor().newInstance()).orElseThrow(() -> new IllegalArgumentException("未知的公司")); } @Override public IDeveloper getDeveloper(String type) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //因为类名首字母大写,所以转换操作类型为类名格式 String operate = type.substring(0,1).toUpperCase() + type.substring(1).toLowerCase(); Class<?> operation = Class.forName("com.liu.test.factory.abstractfactory.cases.impl." + operate + "Developer"); return Optional.of((IDeveloper)operation.getDeclaredConstructor().newInstance()).orElseThrow(() -> new IllegalArgumentException("未知的公司")); } }
通过调用不同的抽象工厂的实现获得具体的实例,执行方法得到想要的结果。
String result = ""; //获得具体的工厂(反射) String operate = operator.substring(0,1).toUpperCase() + operator.substring(1).toLowerCase(); Class<?> operation = Class.forName("com.liu.test.factory.abstractfactory.factory." + operate + "Factory"); IFactory factory = (IFactory)operation.getDeclaredConstructor().newInstance(); //通过工厂获得公司开发人员 IDeveloper developer = factory.getDeveloper(operate); result += developer.work() +"\n"; result += developer.skill() +"\n"; //通过工厂获得公司产品人员 IProductor productor = factory.getProductor(operate); result += productor.work() +"\n"; result += productor.skill() +"\n"; return result;
更多相关内容 -
java 工厂模式的讲解及优缺点的介绍
2020-08-29 14:02:53主要介绍了java 工厂模式的讲解及优缺点的介绍的相关资料, 简单工厂模式,又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式,需要的朋友可以参考下 -
Java工厂模式
2021-09-11 15:08:37Java工厂模式 介绍 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,...Java工厂模式
介绍
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
实例: 1、您需要一辆奥迪汽车,可以直接从奥迪工厂里面提货,而不用去管这辆奥迪汽车是怎么做出来的,以及这个汽车里面的具体实现。
优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个新的产品,只要扩展一个新工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点: 每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
注意事项: 在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 几次对象就不用了, 这种情况,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
普通工厂
定义:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类
工厂方法让类的实例化推迟到子类中进行我们将创建一个 Shape 接口和实现 Shape 接口的实体类。下一步是定义工厂类 ShapeFactory。
然后使用FactoryPatternDemo类,来访问 ShapeFactory 来获取 Shape 对象。 以便获取它所需对象的类型。
从这张图我们可以看出来 Circle(圆形), Square(方形) ,Rectangle(矩形) 这 三个类都继承了Shape(形状)接口 而 这些类都交给ShapeFactory类来管理
我们使用FactorypattemDemo类来测试 访问ShapeFactory形状工厂 获取想要的 形状对象
接口Shape
public interface Shape { void draw(); }
实现类 Circle
public class Circle implements Shape { @Override public void draw() { System.out.println("Inside Circle::draw() method."); } }
实现类Rectangle
public class Rectangle implements Shape { @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); } }
实现类 Square
public class Square implements Shape { @Override public void draw() { System.out.println("Inside Square::draw() method."); } }
工厂ShapeFactory
public class ShapeFactory { //使用 getShape 方法获取形状类型的对象 public static Shape getShape(String shapeType){ //如果传入的字符串为空 if(shapeType == null||shapeType.trim().equals("")){ return null; } // 更具 传进来的 名称 来获取 对应的对象 if(shapeType.equalsIgnoreCase("CIRCLE")){ return new Circle(); } else if(shapeType.equalsIgnoreCase("RECTANGLE")){ return new Rectangle(); } else if(shapeType.equalsIgnoreCase("SQUARE")){ return new Square(); } return null; } }
测试FactoryPatternDemo
public class FactoryPatternDemo { public static void main(String[] args) { //获取 Circle 的对象,并调用它的 draw 方法 Shape shape1 = ShapeFactory.getShape("CIRCLE"); //调用 Circle 的 draw 方法 shape1.draw(); //获取 Rectangle 的对象,并调用它的 draw 方法 Shape shape2 = ShapeFactory.getShape("RECTANGLE"); //调用 Rectangle 的 draw 方法 shape2.draw(); //获取 Square 的对象,并调用它的 draw 方法 Shape shape3 = ShapeFactory.getShape("SQUARE"); //调用 Square 的 draw 方法 shape3.draw(); } }
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.抽象工厂
从上面案例中我们可以发现 工厂模式是 挺好用的 但是会暴露一个问题就是 随着业务的增多 那么工厂也对应增多 造成了难以管理
如何解决这个问题呢 ? 可以使用 抽象工厂来管理所有的工厂
从这张图我们可以看出来有 2个工厂 一个是形状工厂 一个是颜色工厂 而这些工厂 都交给了 AbstractFactory这个大抽象工厂来管理
既然是抽象工厂 我们需要子类FactoryProducer(工厂生产)来实现 然后通过AbstractFactoryPatternDemo 测试类来 访问FactoryProducer 生产我们需要的工厂(形状工厂或者颜色工厂) 然后在通过对应的工厂生产指定的对象
抽象工厂AbstractFactory
public abstract class AbstractFactory { public abstract Color getColor(String color); public abstract Shape getShape(String shape) ; }
形状工厂
接口Shape
public interface Shape { void draw(); }
实现类 Circle
public class Circle implements Shape { @Override public void draw() { System.out.println("Inside Circle::draw() method."); } }
实现类Rectangle
public class Rectangle implements Shape { @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); } }
实现类 Square
public class Square implements Shape { @Override public void draw() { System.out.println("Inside Square::draw() method."); } }
工厂 ShapeFactory
public class ShapeFactory extends AbstractFactory { //使用 getShape 方法获取形状类型的对象 @Override public Shape getShape(String shapeType){ //如果传入的字符串为空 if(shapeType == null||shapeType.trim().equals("")){ return null; } // 更具 传进来的 名称 来获取 对应的对象 if(shapeType.equalsIgnoreCase("CIRCLE")){ return new Circle(); } else if(shapeType.equalsIgnoreCase("RECTANGLE")){ return new Rectangle(); } else if(shapeType.equalsIgnoreCase("SQUARE")){ return new Square(); } return null; } @Override public Color getColor(String color) { return null; } }
颜色工厂
接口Color
public interface Color { void fill(); }
实现类Red
public class Red implements Color { @Override public void fill() { System.out.println("Inside Red::fill() method."); } }
实现类Green
//绿色 public class Green implements Color { @Override public void fill() { System.out.println("Inside Green::fill() method."); } }
实现类Blue
public class Blue implements Color { @Override public void fill() { System.out.println("Inside Blue::fill() method."); } }
工厂ColorFactory
public class ColorFactory extends AbstractFactory { @Override public Color getColor(String color) { if(color == null||color.trim().equals("")){ return null; } if(color.equalsIgnoreCase("RED")){ return new Red(); } else if(color.equalsIgnoreCase("GREEN")){ return new Green(); } else if(color.equalsIgnoreCase("BLUE")){ return new Blue(); } return null; } @Override public Shape getShape(String shape) { return null; } }
生产工厂类 FactoryProducer
public class FactoryProducer { public static AbstractFactory getFactory(String choice){ if(choice.equalsIgnoreCase("SHAPE")){ return new ShapeFactory(); } else if(choice.equalsIgnoreCase("COLOR")){ return new ColorFactory(); } return null; } }
测试AbstractFactoryPatternDemo
public class AbstractFactoryPatternDemo { public static void main(String[] args) { //获取形状工厂 AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE"); //获取形状为 Circle 的对象 Shape shape1 = shapeFactory.getShape("CIRCLE"); //调用 Circle 的 draw 方法 shape1.draw(); //获取颜色工厂 AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR"); //获取颜色为 Blue 的对象 Color color1 = colorFactory.getColor("BLUE"); //调用 Blue 的 fill 方法 color1.fill(); } }
Inside Circle::draw() method.
Inside Blue::fill() method.点赞 -收藏-关注-便于以后复习和收到最新内容 有其他问题在评论区讨论-或者私信我-收到会在第一时间回复 如有侵权,请私信联系我 感谢,配合,希望我的努力对你有帮助^_^ -
Java设计模式之工厂模式(Factory模式)介绍
2020-09-03 21:51:45主要介绍了Java设计模式之工厂模式(Factory模式)介绍,本文讲解了为何使用工厂模式、工厂方法、抽象工厂、Java工厂模式举例等内容,需要的朋友可以参考下 -
java工厂模式
2021-02-12 08:51:50java工厂模式分三种:简单工厂模式、工厂方法模式、抽象工厂模式。简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建...java工厂模式分三种:简单工厂模式、工厂方法模式、抽象工厂模式。
简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
简单工厂模式就是通过一个"全能类",根据外界传递的信息来决定创建哪个具体类的对象。如下图(懒得写demo了,知乎上截了一个。):
通过一个简单工厂类,根据name创建相应的产品对象。
关于简单类如过还有不明白,更多的资料可以参考http://blog.csdn.net/weiwenlongll/article/details/6918164。
简单工厂模式严重违背了“开闭原则”,难以拓展,由此产生了工厂方法模式。
工厂方法模式(FACTORY METHOD)是对简单工厂模式进行了抽象化,符合“开闭原则”,实现了可扩展。
工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
工厂方法模式使用场景:
如组装手机的代工厂。从手机原料工厂获取外壳、显示屏、主板、按键、电池等配件进行组装。组装手机工厂只负责手机的装配,而不负责配件的生产,也不需要关心从手机原料工厂出来的配件是否改变,只要手机各个配置衔接的接口不变就行。比如原料工厂显示屏从TFT的换成了UFB的显示屏,对于组装手机的代工厂来说,只要接口没变,只需要继续装配就行。
如下图,首先建立一个原料工厂接口,原料工厂接口分别定义了创建外壳、显示屏、主板、电池的方法。
LB手机原料工厂负责提供LB手机需要的配件,电池、TFT显示屏、主板、皮革外壳。
下面是手机装配厂的接口,装配厂只负责从原料工厂获取配件并装配成新的手机,其他的概不负责。
LB手机装配厂,负责装配LB原料工厂提供的配件。当然,偶尔也接接私活,装配其它手机厂的手机。
LB手机销量很火,在全国各地都有了装配厂。有一天LB手机的屏幕突然要进行更换了,从TFT显示屏变更成UFT显示屏。牵一发而动全身,这时候就体现出了工厂方法模式的好处。无论LB手机的配置如何变更,对于装配厂来说,createDisplay()接口依然不变。这样只需要原材料工厂的显示屏从提供TFT显示屏更换为UFT显示屏就行。
工厂模式的好处就在于提供创建的产品接口给使用者就行,无论产品的类型如何变化,只要根据接口创建的产品的功能没有变化,使用者就无须做任何变动。
很多介绍工厂方法模式的都是将工厂模式的用法列出来,而并没有具体介绍何时使用。初看时觉得工厂方法模式属于多余,增加了繁杂性,后来慢慢熟悉了工厂方法模式的用处,又重新翻阅了一遍《Head First Design Patterns》巩固一下。特模拟一个场景结合理论记录下来,希望能巩固理解。
-
Java工厂模式定义与用法实例分析
2020-08-25 19:00:18主要介绍了Java工厂模式定义与用法,结合具体实例形式分析了java工厂模式定义、使用相关操作技巧,并总结了类图原理,需要的朋友可以参考下 -
Java设计模式:工厂模式——图文+代码示例(通俗易懂)
2020-12-21 04:52:14工厂模式: 每一种设计模式都有它要解决的问题: 工厂模式最主要解决的问题就是创建者和调用者的耦合,那么代码层面其实就是取消对new的使用。 工厂模式有三种: 1. 简单工厂模式 2. 工厂方法模式 3. 抽象方法模式 ... -
Java中工厂模式案例
2019-01-17 16:36:011.简单工厂模式(simple factory)2.工厂方法模式(factory mathoud)3.抽象工厂模式(abstract factory) -
深入理解java三种工厂模式
2020-09-02 06:30:38下面小编就为大家带来一篇深入理解java三种工厂模式。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 -
设计模式之java工厂模式
2021-03-09 21:52:50创建者模式中的工厂模式 -
Java 工厂模式
2021-01-09 20:32:13因为在简单工厂模式中用于创建实例的方法是静态方法,因此简单工厂模式又被称为静态工厂方法模式,它属于类创建型模式。 简单工厂模式的要点在于,当我们需要什么,只需要传入一个正确的参数,就可以获取我们所需要...简单工厂模式详解
简单工厂模式用来定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态方法,因此简单工厂模式又被称为静态工厂方法模式,它属于类创建型模式。
简单工厂模式的要点在于,当我们需要什么,只需要传入一个正确的参数,就可以获取我们所需要的对象,而无需知道其创建细节。简单工厂模式结构比较简单,其核心是工厂类的设计,其机构如图所示:
在简单工厂模式结构图中包含如下几个角色。
- Factory(工厂角色):工厂角色即工厂类,它是简单共产模式的核心,负责实现所创建的所有产品实例的内部逻辑;工厂类可以被外界直接调用,创建所需的产品对象;在工厂类中提供了静态的工厂方法,它的返回类型为抽象产品类型。
- Product(抽象产品角色):它是工厂类所创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入将提高系统的灵活性,使得在工厂类中只需定义一个通用的工厂方法,因为所有创建的具体产品对象都是其子类对象。
- ConcreteProduct(具体产品角色):它是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法。
下面来看一个汽车与工厂实例,具体代码如下:
/** * 交通工具(简单工厂模式) */ public class SimpleFactoryPattern { public static void main(String[] args) { // 根据需要传入相关的交通工具名称,获取交通工具实例 Vehicle vehicle = Factory.produce("car"); vehicle.run(); } } /** * 交通工具(抽象类) */ interface Vehicle{ void run(); } /** * 汽车(具体类) */ class Car implements Vehicle{ @Override public void run() { System.out.println("car run..."); } } /** * 公交车(具体类) */ class Bus implements Vehicle{ @Override public void run() { System.out.println("bus run..."); } } /** 1. 自行车(具体类) */ class Bicycle implements Vehicle{ @Override public void run() { System.out.println("bicycle run..."); } } /** 2. 工厂类 */ class Factory{ // 静态方法,生成交通工具 public static Vehicle produce(String type){ Vehicle vehicle = null; if (type.equals("car")){ vehicle = new Car(); return vehicle; } if (type.equals("bus")){ vehicle = new Bus(); return vehicle; } if (type.equals("bicycle")){ vehicle = new Bicycle(); return vehicle; } return vehicle; } }
在上述代码中,交通工具都被抽象为Vehicle类,而Car、Bus、Bicycle类是Vehicle类的实现类,并实现Vehicle的run方法,打印输出相关的信息。Factory是工厂类,类中的静态方法produce根据传入的不同的交通工具的类型,生产相关的交通工具,返回抽象产品类Vehicle。上述代码的类结构图如图所示:
简单工厂模式的主要优点如下:
- 工厂类包含必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的职责,而仅仅“消费”产品,简单工厂实现了对象创建和使用分离。
- 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过工厂模式可以在一定程度减少使用者的记忆量。
简单工厂模式的主要缺点如下:
- 由于工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都会受到影响。
- 使用简单工厂模式势必会增加系统中类的个数(引入了新的工厂类),增加了系统的复杂度和理解难度。
- 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
- 简单工厂模式由于使用静态工厂方法,造成工厂角色无法基于继承的等级结构。
工厂方法模式详解
在简单工厂模式中只提供一个工厂类,它需要知道每一个产品对象的创建细节,并决定何时实例化哪一个产品类。闻单工厂模最大的缺点是当有新产品要加入到系统中时,必须修改工厂类,需要在其中加入必要的业务逻辑,这违背了“开闭原则”。此外,在简单工厂模式中,所有的产品都由同一个工厂创建,工厂类职责较重,业务逻辑较为复杂。具体产品与工厂类之间的耦合度高,严重影啊了系统的灵活性和扩展性,而工厂方法模式则可以很好地解决这一问题。
在工厂方法模式中,不再提供一个统一的工厂类来创建所有的产品对象,而是针对不同的产品提供不同的工厂,系统提供一个与产品等级结构对应的工厂等级结构,
工厂方法模式的定义:工厂方法模式(Factory Method Pattem)用来定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法模式又简称为工厂模式 (Factory Pattern),还可称作虚拟构造器模式(Virtual ConstructorPattern)或多态工厂模式(Polymorphic Factory Pattern)。 工厂方法模式是一种类创建型模式。
工厂方法模式提供一个抽象工厂接口来声明抽象工厂方法,而由其子类来具体实现工厂方法,创建具体的产品对象。工厂方法模式结构下图所示。
在工厂方法模式的结构图中包含如下几个角色。- Product(抽象产品类):它是定义产品的接口,是工厂方法模式所创建对象的超类型,
也就是产品对象的共同父类。 - ConcreteProduct(具体产品类):它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品之间—一对应。
- Factory(抽象工厂类):在抽象工厂类中,声明了工厂方法(Factory Method),用于返回一个产品。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
- ConcreteFactory(具体工厂类):它是抽象工厂类的子类,实现了抽象工厂定义的工厂方法,并可由客户端调用,返回一个具体产品类的实例。
下面来看一个汽车与工厂实例,具体代码如下:/** * 汽车与工厂(工厂方法模式) */ public class FactoryMethodPattern { public static void main(String[] args) { // 生产汽车 Factory2 carFactory = new CarFactory(); Vehicle2 car = carFactory.produce(); car.run(); // 生产公交车 Factory2 busFactory = new BusFactory(); Vehicle2 bus = busFactory.produce(); bus.run(); // 生产自行车 Factory2 bicycleFactory = new BicycleFactory(); Vehicle2 bicycle = bicycleFactory.produce(); bicycle .run(); } } /** * 抽象工厂类 */ interface Factory2{ // 生产 Vehicle2 produce(); } /** * 交通工具 */ interface Vehicle2{ void run(); } /** * 汽车 */ class Car2 implements Vehicle2{ @Override public void run() { System.out.println("car run..."); } } /** * 汽车工厂 */ class CarFactory implements Factory2{ @Override public Vehicle2 produce() { return new Car2(); } } /** * 公交车 */ class Bus2 implements Vehicle2{ @Override public void run() { System.out.println("bus run..."); } } /** * 公交车工厂 */ class BusFactory implements Factory2{ @Override public Vehicle2 produce() { return new Bus2(); } } /** * 自行车 */ class Bicycle2 implements Vehicle2{ @Override public void run() { System.out.println("bicycle run..."); } } /** * 自行车工厂 */ class BicycleFactory implements Factory2{ @Override public Vehicle2 produce() { return new Bicycle2(); } }
在上述代码中,Vehicle类是抽象产品类而Car、Bus、Bicycle类是具体产品类,并且实现Vehicle类的run方法。每一种具体产品类都有一一对应的工厂类CarFactory、BusFactory、BicycleFactory等,所有的工厂都有共同的抽象父类 Factory。汽车与工厂具体的类结构如下图所示。
与简单工厂模式相比,工厂方法模式最重要的区别是引入了抽象工厂角色,抽象工厂可以是接口,也可以是抽象类或者具体类。在抽象工厂中声明了工厂方法但并未实现工厂方法,具体产品对象的创建由其子类负责,客户端针对抽象工厂编程,可在运行时再指定具体工厂类,具体工厂类实现了工厂方法,不同的具体工厂可以创建不同的具体产品。
-
java设计模式之工厂模式实例详解
2020-08-29 08:12:31主要介绍了java设计模式之工厂模式,结合具有实例形式分析了java工厂模式的概念、原理、实现与使用方法,需要的朋友可以参考下 -
java 工厂模式简单介绍及例子
2021-03-06 19:27:14java中工厂模式在java ee中经常碰见,是一种常见的模式,其可分为三种:静态工厂模式、工厂方法模式、抽象工厂模式。一下做一简单讲述和例子。静态工厂模式:顾名思义就知道他是用静态方法实现的,其创建的对象具有... -
轻松掌握Java工厂模式、抽象工厂模式
2020-09-01 11:45:01主要帮助大家轻松掌握Java工厂模式、抽象工厂模式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
JAVA工厂模式工厂方法模式.pdf
2021-12-12 22:17:24JAVA工厂模式工厂方法模式.pdf -
Java设计模式之工厂模式实现方法详解
2020-08-28 13:31:34主要介绍了Java设计模式之工厂模式实现方法,结合实例形式较为详细的分析了工厂模式的分类、原理、实现方法与相关注意事项,需要的朋友可以参考下 -
java 工厂模式的实例详解
2020-08-29 11:53:26主要介绍了java 工厂模式的实例详解的相关资料,这里举例说明该如何实现工厂模式,需要的朋友可以参考下 -
23种设计模式(2) java工厂模式
2020-08-28 21:52:04主要为大家详细介绍了23种设计模式之java工厂模式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
Java设计模式编程中简单工厂与抽象工厂模式的使用实例
2020-09-02 11:58:31主要介绍了Java设计模式编程中简单工厂与抽象工厂模式的使用实例,简单工厂与抽象工厂都可以归类于设计模式中的创建型模式,需要的朋友可以参考下 -
java工厂模式.pdf
2021-08-09 16:39:39java工厂模式.pdf -
JAVA中常用的设计模式:单例模式,工厂模式,观察者模式
2020-08-19 09:30:03设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段... -
java 工厂模式龟兔赛跑《赋》FactoryMethodTest.java
2020-09-21 16:42:12java设计模式 之 工厂模式,通过小游戏龟兔赛跑,帮你快速理解工厂模式设计。通俗易懂,适合新入门小白观摩。 -
Java设计模式-工厂模式
2021-08-06 09:27:36Java设计模式-工厂模式 什么是工厂模式? 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在工厂模式中,我们在创建对象时不会... -
Java工厂模式.pdf
2021-12-15 17:26:18Java工厂模式.pdf