工厂模式和抽象工厂模式
Posted K_artorias
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工厂模式和抽象工厂模式相关的知识,希望对你有一定的参考价值。
工厂模式
工厂模式,我的理解就是对象的生产工厂,能通过一个工厂类,生产多种类的实例对象,也就是说,每当人们想新生成某种类的一个对象时,不通过new来做,而是通过工厂类的一个生产对象的函数来生产出新的对象,我们在创建对象时就不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
如果想要实现这个模式,就需要该工厂能生产的所有类都有一个共同的父类,因为当通过工厂生产某类的对象时候,需要通过父类声明,然后通过参数确定子类,这样就能实现“批量生产对象”。(例如:Shape shape1 = shapeFactory.getShape("CIRCLE"); shape就是父类,通过父类声明,再通过工厂方法的参数生产特定子类的对象)通过学习,我理解这可以有两种情况:
1 工厂能生产的类都是相似类,例如,形状(shape)作为父类,而圆形(circle)、正方形(square)和矩形(rectangle)作为子类继承shape,这样在调用时候,就可以通过shape来声明。
2 工厂生产的类不是相似类,因为必须需要一个父类,那么我们就强制定义一个空父类Bean,然后不管新定义什么类,都继承这个新的父类,这样,即使是想要生产的对象的类到底是不是相似的,都可以通过Bean来声明。
说起来比较抽象,由于1和2两种情况只是理解上有所不同,但是实现是相同方式的,所以,下边以第一种方式的代码展现给大家,上代码:
步骤 1
创建一个接口。
Shape.java
public interface Shape { void draw(); }
步骤 2
创建实现接口的实体类。
Rectangle.java
public class Rectangle implements Shape { @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); } }
Square.java
public class Square implements Shape { @Override public void draw() { System.out.println("Inside Square::draw() method."); } }
Circle.java
public class Circle implements Shape { @Override public void draw() { System.out.println("Inside Circle::draw() method."); } }
步骤 3
创建一个工厂,生成基于给定信息的实体类的对象。
ShapeFactory.java
public class ShapeFactory { //使用 getShape 方法获取形状类型的对象 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; } }
步骤 4
使用该工厂,通过传递类型信息来获取实体类的对象。
FactoryPatternDemo.java
public class FactoryPatternDemo { public static void main(String[] args) { ShapeFactory shapeFactory = new ShapeFactory(); //获取 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(); } }
步骤 5
验证输出。
Inside Circle::draw() method. Inside Rectangle::draw() method. Inside Square::draw() method.
以上就是我学习工厂模式的心得体会,下面介绍一下由工厂模式发展而来的抽象工厂模式。
抽象工厂模式
我理解的超级工厂模式,就是这个工厂包含了很多的小工厂,每个小工厂都是类似于上边介绍的那种正常的工厂模式。这样,不论你想有什么类别的对象产生,都可以通过同一个超级工厂找到相关的工厂,生产出你想要的对象类型。
假设有两种类别的对象需求,分别是颜色(color)和形状(shape),那么我们可以分别建立color和shape的工厂类,然后再放到一个抽象超级工厂中。然后超级工厂作为工厂的工厂,可以创建分别创建形状和颜色的工厂类继承超级工厂,然后每次调用的时候都用超级工厂声明,需要哪个子工厂类,就在超级工厂的参数上做改变就OK了。
直接上代码:
步骤 1
为形状创建一个接口。
Shape.java
public interface Shape { void draw(); }
步骤 2
创建实现接口的实体类。
Rectangle.java
public class Rectangle implements Shape { @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); } }
Square.java
public class Square implements Shape { @Override public void draw() { System.out.println("Inside Square::draw() method."); } }
Circle.java
public class Circle implements Shape { @Override public void draw() { System.out.println("Inside Circle::draw() method."); } }
步骤 3
为颜色创建一个接口。
Color.java
public interface Color { void fill(); }
步骤4
创建实现接口的实体类。
Red.java
public class Red implements Color { @Override public void fill() { System.out.println("Inside Red::fill() method."); } }
Green.java
public class Green implements Color { @Override public void fill() { System.out.println("Inside Green::fill() method."); } }
Blue.java
public class Blue implements Color { @Override public void fill() { System.out.println("Inside Blue::fill() method."); } }
步骤 5
为 Color 和 Shape 对象创建抽象类来获取工厂。
AbstractFactory.java
public abstract class AbstractFactory { abstract Color getColor(String color); abstract Shape getShape(String shape) ; }
步骤 6
创建扩展了 AbstractFactory 的工厂类,基于给定的信息生成实体类的对象。
ShapeFactory.java
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 Color getColor(String color) { return null; } }
ColorFactory.java
public class ColorFactory extends AbstractFactory { @Override public Shape getShape(String shapeType){ return null; } @Override 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; } }
步骤 7
创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂。
FactoryProducer.java
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; } }
步骤 8
使用 FactoryProducer 来获取 AbstractFactory,通过传递类型信息来获取实体类的对象。
AbstractFactoryPatternDemo.java
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(); } }
步骤 9
验证输出。
Inside Circle::draw() method. Inside Rectangle::draw() method. Inside Square::draw() method. Inside Red::fill() method. Inside Green::fill() method. Inside Blue::fill() method.
代码来源:感谢菜鸟教程提供的实例代码
以上是关于工厂模式和抽象工厂模式的主要内容,如果未能解决你的问题,请参考以下文章