抽象工厂模式提供了一个接口,用于创建相关或者依赖对象的家族,而不需要指定具体实现类。
抽象工厂模式允许客户使用抽象接口来创建一组相关的产品,客户类和工厂类分开,客户需要任何产品的时候,只需要向工厂请求即可,客户无须修改就可以获得新产品。这样一来,客户就从具体产品中解耦。
代码实现:
抽象产品:
package com.demo.abstractfactory.product;
public abstract class AbstractProduct1 {
public abstract void show();
}
package com.demo.abstractfactory.product;
public abstract class AbstractProduct2 {
public abstract void show();
}
package com.demo.abstractfactory.product;
public abstract class AbstractProduct3 {
public abstract void show();
}
具体产品:
package com.demo.abstractfactory.product;
public class Product1 extends AbstractProduct1 {
@Override
public void show() {
System.out.println("This is product1.");
}
}
package com.demo.abstractfactory.product;
public class Product2 extends AbstractProduct2 {
@Override
public void show() {
System.out.println("This is product2.");
}
}
package com.demo.abstractfactory.product;
public class Product3 extends AbstractProduct3 {
@Override
public void show() {
System.out.println("This is product3.");
}
}
抽象工厂:
package com.demo.abstractfactory.factory;
import com.demo.abstractfactory.product.AbstractProduct1;
import com.demo.abstractfactory.product.AbstractProduct2;
import com.demo.abstractfactory.product.AbstractProduct3;
public interface IFactory {
public AbstractProduct1 createProduct1();
public AbstractProduct2 createProduct2();
public AbstractProduct3 createProduct3();
}
具体工厂:
package com.demo.abstractfactory.factory;
import com.demo.abstractfactory.product.AbstractProduct1;
import com.demo.abstractfactory.product.AbstractProduct2;
import com.demo.abstractfactory.product.AbstractProduct3;
import com.demo.abstractfactory.product.Product1;
import com.demo.abstractfactory.product.Product2;
import com.demo.abstractfactory.product.Product3;
public class FactoryImpl implements IFactory {
@Override
public AbstractProduct1 createProduct1() {
return new Product1();
}
@Override
public AbstractProduct2 createProduct2() {
return new Product2();
}
@Override
public AbstractProduct3 createProduct3() {
return new Product3();
}
}
客户类:
package com.demo.abstractfactory.client;
import com.demo.abstractfactory.factory.IFactory;
import com.demo.abstractfactory.product.AbstractProduct1;
import com.demo.abstractfactory.product.AbstractProduct3;
public class Client1 {
public IFactory factory;
public Client1(IFactory factory) {
this.factory = factory;
}
public AbstractProduct1 getProduct1() {
System.out.println("Client1 gets the product1");
return factory.createProduct1();
}
public AbstractProduct3 getProduct3() {
System.out.println("Client1 gets the product3");
return factory.createProduct3();
}
}
package com.demo.abstractfactory.client;
import com.demo.abstractfactory.factory.IFactory;
import com.demo.abstractfactory.product.AbstractProduct2;
import com.demo.abstractfactory.product.AbstractProduct3;
public class Client2 {
private IFactory factory;
public Client2(IFactory factory) {
this.factory = factory;
}
public AbstractProduct2 getProduct2() {
System.out.println("Client1 gets the product2");
return factory.createProduct2();
}
public AbstractProduct3 getProduct3() {
System.out.println("Client1 gets the product3");
return factory.createProduct3();
}
}
测试代码:
package com.demo.abstractfactory;
import com.demo.abstractfactory.client.Client1;
import com.demo.abstractfactory.client.Client2;
import com.demo.abstractfactory.factory.FactoryImpl;
import com.demo.abstractfactory.factory.IFactory;
public class MainApp {
public static void main(String[] args) {
IFactory factory = new FactoryImpl();
Client1 client1 = new Client1(factory);
client1.getProduct1().show();
client1.getProduct3().show();
System.out.println();
Client2 client2 = new Client2(factory);
client2.getProduct2().show();
client2.getProduct3().show();
}
}
结果输出:
Client1 gets the product1
This is product1.
Client1 gets the product3
This is product3.
Client1 gets the product2
This is product2.
Client1 gets the product3
This is product3.
抽象工厂模式和工厂方法模式的区别:
1) 工厂方法模式通过继承的方式实现应用程序的解耦,而抽象工厂模式则通过对象组合的方式实现应用程序的解耦。
2) 工厂方法模式用来创建一个抽象产品,具体工厂实现工厂方法来创建具体产品,而抽象工厂模式用来创建一个产品家族的抽象类型。
使用抽象工厂模式的适合场景:
1) 创建产品家族,相关产品集合在一起使用的时候;
2) 想要提供一个产品类库,并只想显示其接口而不是实现时;
3) 通过组合的方式使用工厂时。