工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
工厂模式是创建型设计模式,使用工厂模式使编程者不在关心具体的对象创建过程,而在对象根据实际情况变动,对象信息复杂,需要面对不同情况创建不同实例时,使用工厂模式的代码更加健壮。
工厂方法模式分为三种:
- 简单工厂模式
https://www.runoob.com/design-pattern/factory-pattern.html
此处引用菜鸟教程实例
步骤 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();
}
}
getShape方法可以实现为静态方法,此方法实现简单逻辑清晰
但是在增加对象类型需要修改代码,当情况变复杂传入的参数也会变复杂,而传入参数需要人为添加,难免出错。
- 静态工厂方法模式(常用)
public class SendFactory {
public static Sender produceMail(){
return new MailSender();
}
public static Sender produceSms(){
return new SmsSender();
}
}
public class FactoryTest {
public static void main(String[] args) {
Sender sender = SendFactory.produceMail();
sender.Send();
}
}
此种方法比较常用,比简单工程扩展性强,添加方法即可。不需要使用传入参数进行判断,调用需要方法即可。但是面对不同的实例还是需要对代码进行修改,不符合开闭原则。
- 抽象工厂模式
此种方法较为抽象,直接看例子:
public interface Sender {
public void Send();
}
两个实现类:
public class MailSender implements Sender {
@Override
public void Send() {
System.out.println("this is mailsender!");
}
}
public class SmsSender implements Sender {
@Override
public void Send() {
System.out.println("this is sms sender!");
}
}
在提供一个接口:
public interface Provider {
public Sender produce();
}
两个工厂类:
public class SendMailFactory implements Provider {
@Override
public Sender produce(){
return new MailSender();
}
}
public class SendSmsFactory implements Provider{
@Override
public Sender produce() {
return new SmsSender();
}
}
测试类:
public class Test {
public static void main(String[] args) {
Provider provider = new SendMailFactory();
Sender sender = provider.produce();
sender.Send();
}
}
这个方法将工厂创建对象的方法抽象为接口方法,具体工厂为接口的实现。这样在添加不同的实例类型的时候可以选择的创建具体的类,也可以兼容上面两种方法。我看这个方法有很重的装饰者模式的影子,或者说就是使用装饰模式来避免违反开闭原则。
后两个实例引用:
https://blog.csdn.net/zhangerqing/article/details/8194653