当前位置:首页 > IT科技类资讯

工厂设计模式案例详解,不服来辩!

本文转载自微信公众号「Java极客技术」,工厂作者鸭血粉丝 。设计转载本文请联系Java极客技术公众号。模式

工厂模式(Factory Pattern)是案例 Java 中最常用的设计模式之一,今天我们一起来彻底解析一下它。详解

一、不服辩介绍

从名称上,工厂顾名思义就是设计创建产品,按类别分为简单工厂模式、模式工厂方法模式、案例抽象工厂模式,详解主要功能都是不服辩帮助我们把对象的实例化操作单独抽取出来,优化系统架构,工厂增强系统的设计扩展性。

下面,模式我们一起来看看各个模式的使用方式。

二、简单工厂模式

简单工厂模式,对象创建管理方式最为简单,因为其仅仅简单的对不同类对象的创建进行了一层薄薄的封装。该模式通过向工厂传递类型来指定要创建的对象。

创建一个接口 public interface Product {     void operation1();    void operation2(); }  创建实现接口的实体类 public class ConcreateProductA implements Product{     @Override    public void operation1() {        System.out.println("产品A,执行任务1");    }    @Override    public void operation2() {        System.out.println("产品A,执行任务2");    } }  public class ConcreateProductB implements Product{     @Override    public void operation1() {        System.out.println("产品B,执行任务1");    }    @Override    public void operation2() {        System.out.println("产品B,执行任务2");    } }  创建一个工厂,香港云服务器生成基于给定信息的实体类的对象 public class SimpleFactory {     //使用 create 方法获取形状类型的对象    public Product create(String productType){        if(productType == null){           return null;       }       if(productType.equalsIgnoreCase("productA")){           return new ConcreateProductA();       }       if(productType.equalsIgnoreCase("productB")){           return new ConcreateProductB();       }       return null;    } }  编写客户端测试类,使用该工厂,通过传递类型信息来获取实体类的对象 public class FactoryPatternDemo {     public static void main(String[] args) {        SimpleFactory simpleFactory = new SimpleFactory();       //获取 productA 的对象       Product productA = simpleFactory.create("productA");       //调用 productA 的 operation1、operation2 方法       productA.operation1();       productA.operation2();       //获取 productB 的对象       Product productB = simpleFactory.create("productB");       //调用 productB 的 operation1、operation2 方法       productB.operation1();       productB.operation2();    } }  执行程序,输出结果: 产品A,执行任务1 产品A,执行任务2 产品B,执行任务1 产品B,执行任务2 

当然,还可以将创建对象方式进行改进,将SimpleFactory类创建对象的方式改成如下方式:

public class SimpleFactory {     //反射机制获取实体类    public <T> T createByClazzName(Class<? extends T> clazz){    T obj = null;   try {     obj = (T) Class.forName(clazz.getName()).newInstance();   } catch (Exception e) {     // TODO Auto-generated catch block    e.printStackTrace();   }   return obj;  } } 

这样做的好处是,当有新的产品加入时,不用修改工厂类,在调用的时候,采用如下方式即可获取对象!

Product product = new SimpleFactory().create("类名.class"); 

三、工厂方法模式

和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂。

创建一个工厂接口 public interface FactoryProduct {     Product create(); }  创建实现接口的实体类 public class ConcreateFactoryA implements FactoryProduct{     @Override    public Product create() {        return new ConcreateProductA();    } }  public class ConcreateFactoryB implements FactoryProduct{     @Override    public Product create() {        return new ConcreateProductB();    } }  编写客户端测试类,使用该工厂,通过传递类型信息来获取实体类的高防服务器对象 public class FactoryPatternDemo {     public static void main(String[] args) {        //获取 productA 的对象       Product productA = new ConcreateFactoryA().create();       //调用 productA 的 operation1、operation2 方法       productA.operation1();       productA.operation2();       //获取 productB 的对象       Product productA = new ConcreateFactoryB().create();       //调用 productB 的 operation1、operation2 方法       productB.operation1();       productB.operation2();    } }  执行程序,输出结果: 产品A,执行任务1 产品A,执行任务2 产品B,执行任务1 产品B,执行任务2 

四、抽象工厂模式

抽象工厂模式主要是应对产品族概念提出来的。提供一个创建一系列相关或相互依赖的对象。

为形状创建一个接口 public interface Shape {     void draw(); }  创建实现接口的实体类 public class Rectangle implements Shape {     @Override    public void draw() {        System.out.println("Inside Rectangle::draw() method.");    } }  public class Square implements Shape {     @Override    public void draw() {        System.out.println("Inside Square::draw() method.");    } }  public class Circle implements Shape {     @Override    public void draw() {        System.out.println("Inside Circle::draw() method.");    } }  为颜色创建一个接口 public interface Color {     void fill(); }  创建实现接口的实体类 public class Red implements Color {     @Override    public void fill() {        System.out.println("Inside Red::fill() method.");    } }  public class Green implements Color {     @Override    public void fill() {        System.out.println("Inside Green::fill() method.");    } }  public class Blue implements Color {     @Override    public void fill() {        System.out.println("Inside Blue::fill() method.");    } }  为 Color 和 Shape 对象创建抽象类来获取工厂 public abstract class AbstractFactory {     public abstract Color getColor(String color);    public abstract Shape getShape(String shape) ; }  创建扩展了 AbstractFactory 的工厂类,基于给定的信息生成实体类的对象 public class ShapeFactory extends AbstractFactory {     @Override    public Shape getShape(String shapeType){        if(shapeType == null){           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;    } }  public class ColorFactory extends AbstractFactory {     @Override    public Shape getShape(String shapeType){        return null;    }    @Override    public Color getColor(String color) {        if(color == null){           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;    } }  创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂 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;    } }  使用 FactoryProducer 来获取 AbstractFactory,通过传递类型信息来获取实体类的对象 public class AbstractFactoryPatternDemo {     public static void main(String[] args) {        //获取形状工厂       AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");       //获取形状为 Circle 的对象       Shape shape1 = shapeFactory.getShape("CIRCLE");       //调用 Circle 的 draw 方法       shape1.draw();       //获取形状为 Rectangle 的对象       Shape shape2 = shapeFactory.getShape("RECTANGLE");       //调用 Rectangle 的 draw 方法       shape2.draw();       //获取形状为 Square 的对象       Shape shape3 = shapeFactory.getShape("SQUARE");       //调用 Square 的 draw 方法       shape3.draw();       //获取颜色工厂       AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");       //获取颜色为 Red 的对象       Color color1 = colorFactory.getColor("RED");       //调用 Red 的 fill 方法       color1.fill();       //获取颜色为 Green 的对象       Color color2 = colorFactory.getColor("Green");       //调用 Green 的 fill 方法       color2.fill();       //获取颜色为 Blue 的源码下载对象       Color color3 = colorFactory.getColor("BLUE");       //调用 Blue 的 fill 方法       color3.fill();    } }  执行程序,输出结果: Inside Circle::draw() method. Inside Rectangle::draw() method. Inside Square::draw() method. Inside Red::fill() method. Inside Green::fill() method. Inside Blue::fill() method. 

五、应用

工厂模式在实际开发中使用非常频繁,例如 JDK 中的日历操作,在国际化的时候,获取本地语言就用到简单工厂模式。

写一个获取测试,如下:

public static void main(String[] args) {      //获取日历操作类     Calendar calendar = Calendar.getInstance();     int year = calendar.get(Calendar.YEAR);     // 取月份要加1     int month = calendar.get(Calendar.MONTH) + 1;     int day = calendar.get(Calendar.DAY_OF_MONTH);     int hour = calendar.get(Calendar.HOUR_OF_DAY);     int minute = calendar.get(Calendar.MINUTE);     int seconds = calendar.get(Calendar.SECOND);     // 1-7分别代表 -- 星期日,星期一,星期二,星期三,星期四,星期五,星期六     int week = calendar.get(calendar.DAY_OF_WEEK);     // 年-月-日     System.out.println("year = " + year);     System.out.println("month = " + month);     System.out.println("day = " + day);     //时-分-秒     System.out.println("hour = " + hour);     System.out.println("minute = " + minute);     System.out.println("seconds = " + seconds);     // 星期     System.out.println("week = " + week); } 

进入getInstance()方法,在获取日历类型的时候,内容如下:

六、小结

工厂模式中,重要的是工厂类,而不是产品类。产品类可以是多种形式,多层继承或者是单个类都是可以的。

但要明确的,工厂模式的接口只会返回一种类型的实例,这是在设计产品类的时候需要注意的,最好是有父类或者共同实现的接口。

上面介绍的三种工厂模式有各自的应用场景,实际应用时能解决问题满足需求即可!

七、参考

1、菜鸟教程 - 工厂模式 

2、博客园 - alpha_panda - 设计模式之工厂模式

分享到:

滇ICP备2023006006号-16