Java设计模式-工厂方法模式和抽象工厂模式

Posted tuke_tuke

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java设计模式-工厂方法模式和抽象工厂模式相关的知识,希望对你有一定的参考价值。

工厂方法模式定义:

即定义一个创建对象的接口(即抽象工厂类),让其子类(具体工厂类)决定实例化哪一个类具体产品类)。“一对一”的关系

1,一抽象工厂类派生出多个具体工厂类;

2,一抽象产品类派生出多个具体产品类

3,每个具体工厂类只能创建一个具体产品类的实例。

UML图:


角色模块:

1,抽象工厂类:工厂方法模式的核心,定义一个创建对象的接口

2,具体工厂类:继承抽象工厂类,实现其工厂方法,实现具体业务逻辑

3,抽象产品类:是工厂方法模式所创建的产品的父类

4,具体产品类:实现抽象产品类的某个具体产品的对象。


工厂方法模式的代码模板

Product.java

package com.hust.factory1;
//抽象产品类
public abstract class Product {
	//产品类的抽象方法,有具体的产品类去实现
      public abstract void method();
}
ConcreteProductA.java

package com.hust.factory1;
//具体产品类A
public class ConcreteProductA extends Product {

	public void method() {
		System.out.println("我是具体产品类A");
	}

<span style="font-size:24px;">}
</span>
ConcreteProductB.java

package com.hust.factory1;
//具体产品类B
public class ConcreteProductB extends Product {

	public void method() {
		System.out.println("我是具体产品类B");
	}

}
Factory.java

package com.hust.factory1;
//抽象工厂类
public abstract class Factory {
	//抽象的工厂方法,具体生产什么有子类去实现
      public abstract <T extends Product> T createProduct(Class<T> clz);
}
ConcreteFactory.java

/**
 * 
 */
package com.hust.factory1;

/**
 * @author tuke
 *
 */
public class ConcreteFactory extends Factory {

	/* 
	 * 需要哪一个类就传入哪一个类的类型
	 */
	public <T extends Product> T createProduct(Class<T> clz) {//传入一个class类要决定生产哪一个产品
		  Product p=null;
		  try {
			p=(Product) Class.forName(clz.getName()).newInstance();//根据类加载器实例化对象
		}  catch (Exception e) {			
			e.printStackTrace();
		}
		return (T) p;
	}

}

Test.java

package com.hust.factory1;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Factory mFactory=new ConcreteFactory();//实例化具体工厂
		Product mProductA=mFactory.createProduct(ConcreteProductA.class);//根据类名初始化具体产品
		mProductA.method();
		Product mProductB=mFactory.createProduct(ConcreteProductB.class);
		mProductB.method();

	}

}
输出:

我是具体产品类A
我是具体产品类B
具体实现例子:由工厂方法生产奥迪Q3,奥迪Q5,奥迪Q7

AudiCar.java

package com.hust.factory2;
//抽象产品类
public abstract class AudiCar {
    //定义一个汽车的行为方法,车可以启动开走  
	public abstract void drive();
	//定义一个汽车的行为方法,车可以自动导航
	public abstract void selfNavigation();
	
}
AudiCarQ3.java

/**
 * 
 */
package com.hust.factory2;

/**
 * @author Administrator
 *
 */
public class AudiQ3 extends AudiCar {

	
	@Override
	public void drive() {		
     System.out.println("Q3启动啦!");
	}
	
	@Override
	public void selfNavigation() {
     System.out.println("Q3启自动导航啦!");
	}

}
AudiCarQ5.java
package com.hust.factory2;

public class AudiQ5 extends AudiCar {

	@Override
	public void drive() {
		System.out.println("Q5启动啦!");
	}

	@Override
	public void selfNavigation() {
		System.out.println("Q5开始巡航啦!");
	}

}
AudiCarQ7.java
package com.hust.factory2;

public class AudiQ7 extends AudiCar{

	@Override
	public void drive() {
		System.out.println("Q7启动啦!");
		
	}

	@Override
	public void selfNavigation() {
		System.out.println("Q7开始巡航啦!");
		
	}

}
AudiCarFactory.java

package com.hust.factory2;
//具体工厂类
public class AudiCarFactory extends AudiFactory {
    //实现工厂方法,如果要实现扩展多功能,可以在抽象类里增加抽象方法,在具体类中实现,这样就可以生产多个产品
	@Override
	public <T extends AudiCar> T createAudiCar(Class<T> clz) {
	     AudiCar mAudiCar=null;
	     try {
			mAudiCar=(AudiCar) Class.forName(clz.getName()).newInstance();
		}  catch (Exception e) {
			e.printStackTrace();
		}
		return (T) mAudiCar;
	}

}
AudiFactory.java
package com.hust.factory2;

public abstract class AudiFactory {
     public abstract <T extends AudiCar> T createAudiCar(Class<T> clz);
}

AudiCarFactory.java
package com.hust.factory2;
//具体工厂类
public class AudiCarFactory extends AudiFactory {
    //实现工厂方法,如果要实现扩展多功能,可以在抽象类里增加抽象方法,在具体类中实现,这样就可以生产多个产品
	@Override
	public <T extends AudiCar> T createAudiCar(Class<T> clz) {
	     AudiCar mAudiCar=null;
	     try {
			mAudiCar=(AudiCar) Class.forName(clz.getName()).newInstance();
		}  catch (Exception e) {
			e.printStackTrace();
		}
		return (T) mAudiCar;
	}

}
Test.java

package com.hust.factory2;

public class TestAudiCar {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
	   AudiFactory mAudiFactory=new AudiCarFactory();//构造一个工厂对象
	   
	   //工厂根据具体产品类的类类型生产产品,这里是上转型对象
	   AudiCar Q3=mAudiFactory.createAudiCar(AudiQ3.class);
	   AudiCar Q5=mAudiFactory.createAudiCar(AudiQ5.class);
	   AudiCar Q7=mAudiFactory.createAudiCar(AudiQ7.class);
	   
	   Q3.drive();
	   Q3.selfNavigation();
	   
	   Q5.drive();
	   Q5.selfNavigation();
	   
	   Q7.drive();
	   Q7.selfNavigation();

	}

}
输出

Q3启动啦!
Q3启自动导航啦!
Q5启动啦!
Q5开始巡航啦!
Q7启动啦!
Q7开始巡航啦!

抽象工厂模式的定义:

为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

1,一个抽象工厂类,派生出多个具体工厂类;

2,多个抽象产品类,派生出多个具体产品类;

3,每个具体工厂类可创建多个具体产品类的实例。
UML图:



抽象工厂代码模板:

package com.hust.model;


//抽象工厂类
public abstract class AbstractFactory {
	//A和B是一组或相互依赖的对象
       public abstract AbstractProductA createProductA();//生产产品A的抽象方法
       public abstract AbstractProductB createProductB();//生产产品B的抽象方法
}
package com.hust.model;
//具体工厂1 生产具体类A1,B1
public class ConcreteFactory1 extends AbstractFactory {

	public AbstractProductA createProductA() {
		
		return new ConcreteProductA1();
	}

	public AbstractProductB createProductB() {
		
		return new ConcreteProductB1();
	}

}
package com.hust.model;
//具体工厂2 生产具体类A2,B2
public class ConcreteFactory2 extends AbstractFactory {

	public AbstractProductA createProductA() {
		
		return new ConcreteProductA2();
	}

	public AbstractProductB createProductB() {
		
		return new ConcreteProductB2();
	}

}

/**
 * 
 */
package com.hust.model;

/**
 * @author tuke
 *
 */
//抽象产品类A
public abstract class AbstractProductA {
       public abstract void method();
}

package com.hust.model;
//具体产品类A1
public class ConcreteProductA1 extends AbstractProductA {

	public void method() {
	  System.out.println("具体产品A1的方法");
	}

}
package com.hust.model;
//具体产品类A2
public class ConcreteProductA2 extends AbstractProductA {

	public void method() {
		 System.out.println("具体产品A2的方法");

	}

}

package com.hust.model;


//抽象产品类B
public abstract class AbstractProductB {
	 public abstract void method();
}
package com.hust.model;
//具体产品类B1
public class ConcreteProductB1 extends AbstractProductB {

	public void method() {
		 System.out.println("具体产品B1的方法");

	}

}
package com.hust.model;
//具体产品类B2
public class ConcreteProductB2 extends AbstractProductB {

	public void method() {
		 System.out.println("具体产品B2的方法");
	}

}

抽象工厂模式的简单实现:

还拿工厂生产奥迪Q3和Q7,是一个车系,但是零部件差别很大,Q3的发动机是国产的,Q7的发动机是原装进口的,Q3的轮胎是普通轮胎,Q7的轮胎是全尺寸越野轮胎,Q3使用的是比较普通的制动系统,而Q7是使用制动性能极好的制动系统。

虽然是一个车系,但是发动机,轮胎,制动系统对应的是一系列零部件。

汽车工厂需要生产轮胎,发动机,制动系统这3个零部件

抽象车厂类

package com.hust.audi;
//一个抽象工厂,只声明生产哪一类产品,具体的产品有子工厂去实现
public abstract class CarFactory {
    public abstract ITire createITire();//生产轮胎
    public abstract IEngine createIEngine();//生产发动机
    public abstract IBrake createIBrake();//生产制动系统
}
具体Q3子工厂

package com.hust.audi;

public class Q3Factory extends CarFactory {

	public ITire createITire() {		
		return new NormalTire();
	}

	public IEngine createIEngine() {	
		return new DomesticEngine();
	}

	public IBrake createIBrake() {		
		return new NormalBrake();
	}

}
具体Q7子工厂

package com.hust.audi;

public class Q7Factory extends CarFactory {

	public ITire createITire() {	
		return new SUVTire();
	}

	public IEngine createIEngine() {		
		return new ImportEngine();
	}

	public IBrake createIBrake() {	
		return new SeniorBrake();
	}

}
轮胎相关类

/**
 * 
 */
package com.hust.audi;

/**
 * 轮胎
 *
 */
public interface ITire {
      void tire();
}
package com.hust.audi;

public class NormalTire implements ITire {

	public void tire() {
		System.out.println("普通轮胎");
	}
}
package com.hust.audi;

public class SUVTire implements ITire {

	public void tire() {
		System.out.println("越野轮胎");
	}

}

发动机相关类

/**
 * 
 */
package com.hust.audi;

/**
 * 发动机
 *
 */
public interface IEngine {
    void engine();
}
package com.hust.audi;

public class DomesticEngine implements IEngine {

	public void engine() {
		System.out.println("国产发动机");
	}

}
package com.hust.audi;

public class ImportEngine implements IEngine {

	public void engine() {
		System.out.println("进口发动机");

	}

}

制动系统相关类

/**
 * 
 */
package com.hust.audi;

/**
 * 制动系统
 *
 */
public interface IBrake {
      void brake();
}
package com.hust.audi;

public class NormalBrake implements IBrake {

	public void brake() {
	System.out.println("普通制动");
	}

}
package com.hust.audi;

public class SeniorBrake implements IBrake {

	public void brake() {
		System.out.println("高级制动");

	}

}
Test.java

package com.hust.audi;

public class Test {

/**
* Q3工厂生产:
普通轮胎
国产发动机
普通制动
-------------------
Q7工厂生产:
越野轮胎
进口发动机
高级制动
*/
	public static void main(String[] args) {
		//构造一个Q3工厂
		CarFactory mQ3Factory=new Q3Factory();
		System.out.println("Q3工厂生产:");
		mQ3Factory.createITire().tire();
		mQ3Factory.createIEngine().engine();
		mQ3Factory.createIBrake().brake();
		System.out.println("-------------------");
		//构造一个Q7工厂
		CarFactory mQ7Factory=new Q7Factory();
		System.out.println("Q7工厂生产:");
		mQ7Factory.createITire().tire();
		mQ7Factory.createIEngine().engine();
		mQ7Factory.createIBrake().brake();

	}

}

抽象工厂模式与工厂方法模式的区别:

抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象
他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构
在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。
在抽象工厂模式中,有一个产品族的概念:所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构



以上是关于Java设计模式-工厂方法模式和抽象工厂模式的主要内容,如果未能解决你的问题,请参考以下文章

关于简单工厂模式工厂方法模式和抽象工厂模式的解析

Java设计模式(创建型:工厂方法模式+抽象工厂模式)

java中抽象工厂模式详解和使用方法

java设计模式 -------- 创建模式 之 抽象工厂模式

Java设计模式学习记录-抽象工厂模式

设计模式--10工厂方法和抽象工厂模式