文章目录
一、工厂方法
工厂方法定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
1、工厂法法模式结构图:
工厂方法抽象出一个工厂接口,这个接口只有一个方法,就是创建抽象产品的工厂方法,所有要生产具体类的工厂就去实现这个接口。当需要创建新对象的工厂时,就不需要更改原有的工厂类,只需要增加相应的工厂类。
产品抽象类 Product
public abstract class Product {
protected String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
具体产品类 ConcreteProductA
public class ConcreteProductA extends Product{
public ConcreteProductA(){
super();
this.name = "具体产品 A";
}
}
具体产品类 ConcreteProductB
public class ConcreteProductB extends Product{
public ConcreteProductB(){
super();
this.name = "具体产品 B";
}
}
抽象工厂接口 Factory
public interface Factory {
public Product createProduct();
}
创建 ConcreteProductA 的工厂类 ConcreteProductAFactory
public class ConcreteProductAFactory implements Factory{
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
创建 ConcreteProductB 的工厂类 ConcreteProductBFactory
public class ConcreteProductBFactory implements Factory{
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
效果测试类
public class FactoryMethodTest {
public static void main(String[] args) {
Factory factoryA = new ConcreteProductAFactory();
Factory factoryB = new ConcreteProductBFactory();
Product productA = factoryA.createProduct();
Product productB = factoryB.createProduct();
System.out.println(productA.getName());
System.out.println(productB.getName());
}
}
2、工厂方法模式的优缺点
工厂方法模式具有良好的封装性,代码结构清晰。如果一个调用者需要一个具体的产品对象,只要知道这个产品的类名,不用知道创建对象的艰辛过程,降低模块间的耦合,并且拓展性好。但缺点也是相对的,每增加一个产品,就需要加一个产品的工厂类,增加了额外的开发量。
二、抽象工厂模式
抽象工厂模式定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
1、抽象工厂模式结构图
AbstractProductA 和 AbstractProductB 是两个抽象产品,而ProductA1和ProductA2、ProductB1、ProductB2就是对两个抽象产品的具体实现。
AbstractFactory是一个抽象工厂接口,它里面包含所有产品创建的抽象方法。而ConcreteFactory1 和ConcreteFactory2就是具体的工厂了。
抽象产品类 AbstractProductA
public abstract class AbstractProductA {
protected String type = "A型产品";
protected String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/** 每个产品具体实现该方法 */
public abstract void doSomething();
}
抽象产品类 AbstractProductB
public abstract class AbstractProductB {
protected String type = "B型产品";
protected String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/** 每个产品具体实现该方法 */
public abstract void doSomething();
}
A型具体产品 ProductA1
public class ProductA1 extends AbstractProductA{
public ProductA1(){
super();
this.name = "产品A1";
}
@Override
public void doSomething() {
System.out.println(this.name + " doSomething");
}
}
A型具体产品 ProductA2
public class ProductA2 extends AbstractProductA{
public ProductA2(){
super();
this.name = "产品A2";
}
@Override
public void doSomething() {
System.out.println(this.name + " doSomething");
}
}
B型具体产品 ProductB1
public class ProductB1 extends AbstractProductB{
public ProductB1(){
super();
this.name = "产品B1";
}
@Override
public void doSomething() {
System.out.println(this.name + " doSomething");
}
}
B型具体产品 ProductB2
public class ProductB2 extends AbstractProductB{
public ProductB2(){
super();
this.name = "产品B2";
}
@Override
public void doSomething() {
System.out.println(this.name + " doSomething");
}
}
抽象工厂接口 AbstractFactory
public interface AbstractFactory {
public AbstractProductA createProductA();
public AbstractProductB createProductB();
}
创建1系列产品的工厂类 ConcreteFactory1
public class ConcreteFactory1 implements AbstractFactory{
@Override
public AbstractProductA createProductA() {
return new ProductA1();
}
@Override
public AbstractProductB createProductB() {
return new ProductB1();
}
}
创建2系列产品的工厂类 ConcreteFactory2
public class ConcreteFactory2 implements AbstractFactory{
@Override
public AbstractProductA createProductA() {
return new ProductA2();
}
@Override
public AbstractProductB createProductB() {
return new ProductB2();
}
}
效果测试类
public class AbstractFactoryTest {
public static void main(String[] args) {
AbstractFactory factory = new ConcreteFactory1();
AbstractProductA productA = factory.createProductA();
AbstractProductB productB = factory.createProductB();
productA.doSomething();
productB.doSomething();
System.out.println("=========切换产品系列工厂=========");
factory = new ConcreteFactory2();
productA = factory.createProductA();
productB = factory.createProductB();
productA.doSomething();
productB.doSomething();
}
}
输出:
产品A1 doSomething
产品B1 doSomething
=切换产品系列工厂=
产品A2 doSomething
产品B2 doSomething
由此可见,切换工厂类,即可对获取的产品系列进行切换
2、抽象工厂模式的优缺点
抽象工厂最大的好处是便于切换产品系列,其次是它让具体的创建实例过程与客户端分离,客户端是通过抽象接口获取实例,依赖的产品也是抽象的,而不是具体的产品类。
抽象工厂的缺点是产品族的拓展非常困难,如果增加了一个产品,抽象工厂类中需要增加创建该产品的抽象方法,具体工厂类中也得去实现,涉及到的改动多。