java设计模式之工厂设计模式(简单工厂设计模式、工厂设计模式、抽象设计模式)...

工厂设计模式分为三种:

1、简单工厂设计模式(Simple Factory

2、工厂设计模式(Factory Method

3、抽象设计模式(Abstract Factory

 

这三种工厂设计模式都属于创建型设计模式,都是将对象的实例化部分取出来,优化系统架构,增强系统的扩展性。

 

1、简单工厂模式:

 

又叫静态工厂,是工厂模式三中状态中结构最为简单的。主要有一个静态方法,用来接受参数,并根据参数来决定返回实现同一接口的不同类的实例

 

角色:

1、工厂类角色(SimpleFactory):根据逻辑不同,产生不同的产品ConcreteProduct;

2、抽象产品角色(Product):接口或抽象类,

3、具体产品角色(ConcreteProduct):工厂类创建的具体实例对象。

 

类图:




 
 

实现代码

 

 

/**
 * 产品接口
 * @author zzj
 *
 */
public interface IProduct {
	void act();
}

/**
 * 具体实现类
 * 相当于ConcreteProductA
 * @author zzj
 *
 */
public class Washer implements IProduct {
	public Washer(){
		System.out.println("Washer is produced");
	}

	@Override
	public void act() {
	    System.out.println("Wash the clothes!");
	}
}

/**
 * 具体实现类
 * 相当于ConcreteProductB
 * @author zzj
 *
 */
public class AirCondition implements IProduct {
	public AirCondition(){
		System.out.println("AirCondition is produced");
	}

	@Override
	public void act() {
		System.out.println("Cool down!");
	}
}

/**
 * 生产工厂类
 * @author zzj
 *
 */
public class SimpleFactory {
	public static IProduct createFactory(String productName) throws Exception{
		if("washer".equals(productName)){
			return new Washer();
		}else if("airCondition".equals(productName)){
			return new AirCondition();
		}else{
			throw new Exception();
		}
	}
}

/**
 * 简单工厂客户端
 * @author zzj 
 * 2017/6/3
 */
public class Client {
	public static void main(String[] args){
		try {
			SimpleFactory.createFactory("washer");
			SimpleFactory.createFactory("airCondition");
			//冰箱
			SimpleFactory.createFactory("Icebox");
		} catch (Exception e) {
			System.out.println("no product");
		}
	}
}

 

 

输出结果:

 

 

Washer is produced
AirCondition is produced
no product

 
优点:客户端可以免除直接创建产品对象的责任,而仅仅负责消费对象就可以了,这种做法就实现了对职责权利的分割,有利于优化结构

 

缺点:

1、每次想要增加一种新产品的时候,都必须修改SimpleFactory的原代码
2、如果产品过多,代码逻辑很复杂,整个系统都依赖SimpleFactory,一旦SimpleFactory出现问题,系统将不能工作。这点在工厂模式进行了改进。

 

 

2、工厂设计模式

 

工厂方法为工厂类定义了接口,用多态来削弱了工厂类的职能

 

又叫虚拟构造器模式或多态工厂,在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。

 

角色:

1、抽象工厂角色(IFactory):抽象类或接口,

2、具体工厂角色(ConcreteFactory):和业务逻辑有关,创建具体的产品对象ConcreteProduct,

3、抽象产品角色(IProduct):抽象类或接口,

4、具体产品角色(ConcreteProduct):工厂类创建的具体实例对象。

 

类图:



 

 

实现代码:

 

 

/**
 * 产品接口
 * @author zzj
 *
 */
public interface IProduct {
	void act();
}

/**
 * 具体实现类
 * 相当于ConcreteProductA
 * @author zzj
 *
 */
public class Washer implements IProduct {
	public Washer(){
		System.out.println("Washer is produced");
	}

	@Override
	public void act() {
	    System.out.println("Wash the clothes!");
	}

}

/**
 * 具体实现类
 * 相当于ConcreteProductB
 * @author zzj
 *
 */
public class AirCondition implements IProduct {
	public AirCondition(){
		System.out.println("AirCondition is produced");
	}

	@Override
	public void act() {
		System.out.println("Cool down!");
	}
}

/**
 * 工厂接口
 * @author zzj
 *
 */
public interface IFactory {
	IProduct create();

}

/**
 * 具体实现类
 * 相当于ConcreteFactoryA
 * @author zzj
 *
 */
public class WasherFactory implements IFactory {

	@Override
	public IProduct create() {
		return new Washer();
	}

}

/**
 * 具体实现类
 * 相当于ConcreteFactoryB
 * @author zzj
 *
 */
public class AirConditionFactory implements IFactory {

	@Override
	public IProduct create() {
		return new AirCondition();
	}

}

/**工厂方法客户端
 * @author zzj 
 * 2017/6/3
 */
public class Client {
	public static void main(String[] args){
		IProduct product;
		product = new WasherFactory().create();
		product.act();
		product = new AirConditionFactory().create();
		product.act();
	}

}

 

 

输出结果:

 

 

Washer is produced
Wash the clothes!
AirCondition is produced
Cool down!

 

 

在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去完成,这就允许系统在不修改工厂角色的情况下,创建新的产品。符合开闭原则

 

优点:每个产品都有自己对应的工厂类,互不干涉,增加或修改都不影响其他的产品

缺点:产品越多,需要创建的工厂类越多

 

3、抽象工厂设计模式

抽象工厂设计模式是对产品族而言的。给客户端提供一个接口,可以创建多个产品族中的产品对象。

 

适用条件:

1.系统中有多个产品族,而系统一次只可能消费其中一族产品
2.同属于同一个产品族的产品以其使用。

 

角色:

1、抽象工厂角色(IFactory):抽象类或接口,

2、具体工厂角色(ConcreteFactory):和业务逻辑有关,创建具体的产品对象ConcreteProduct,

3、抽象产品角色(IProduct):抽象类或接口,

4、具体产品角色(ConcreteProduct):工厂类创建的具体实例对象。

 

类图:

 



 

 

实现代码:

 

 

/**
 * 相当于AbstractProductA
 * @author zzj
 *
 */
public interface Vehicle {
	void run();
}

/**
 * 相当于ProductA1
 * @author zzj
 *
 */
public class Car implements Vehicle {

	public Car(){
		System.out.println("car construct");
	}
	@Override
	public void run() {
		System.out.println("run car");
	}

}

/**
 * 相当于ProductA2
 * @author zzj
 *
 */
public class Plane implements Vehicle {

	public Plane(){
		System.out.println("plane construct");
	}
	@Override
	public void run() {
		System.out.println("run plane");
	}

}

/**
 * 相当于AbstractProductB
 * @author zzj
 *
 */
public interface Food {
	void eat();
}

/**
 * 相当于ProductB1
 * @author zzj
 *
 */
public class Apple implements Food {
	
	public Apple(){
		System.out.println("apple construct");
	}

	@Override
	public void eat() {
		System.out.println("eating apple");
	}

}

/**
 * 相当于ProductB2
 * @author zzj
 *
 */
public class Water implements Food {

	public Water(){
		System.out.println("water construct");
	}
	
	@Override
	public void eat() {
		System.out.println("drinking water");
	}

}

/**
 * 抽象工厂接口
 * @author zzj
 *
 */
public interface IFactory {
	Vehicle createVehicle();
	Food createFood();

}

/**
 * 具体工厂类
 * 相当于ConcreteFactory1
 * 生产汽车和苹果
 * @author zzj
 *
 */
public class ConcreteFactory1 implements IFactory {

	@Override
	public Vehicle createVehicle() {
		return new Car();
	}

	@Override
	public Food createFood() {
		return new Apple();
	}

}

/**
 * 具体工厂类
 * 相当于ConcreteFactory2
 * 生产飞机和水
 * @author zzj
 *
 */
public class ConcreteFactory2 implements IFactory {

	@Override
	public Vehicle createVehicle() {
		return new Plane();
	}

	@Override
	public Food createFood() {
		return new Water();
	}

}

/**
 * 抽象工厂设计模式客户端
 * @author zzj
 * 2017/6/10
 */
public class Client {
	public static void main(String[] args){
		IFactory factory1 = new ConcreteFactory1();
		factory1.createVehicle().run();
		factory1.createFood().eat();
		
		IFactory factory2 = new ConcreteFactory2();
		factory2.createVehicle().run();
		factory2.createFood().eat();
	}

}

 

 

输出结果:

 

 

car construct
run car
apple construct
eating apple
plane construct
run plane
water construct
drinking water

 

 

优点:增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”

缺点:增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类。

 

 

三者区别:

简单工厂模式:

生成同一等级中的任何产品

创建工厂,工厂的作用就是创建接口

工厂类包含必要逻辑判断,根据客户端的选择动态实例化相关类

但是对于增加的新产品,需要修改工厂类。

违背开闭原则。

工厂方法:

生成统一等级结构中的固定产品

只有一个抽象产品类,可以派生出多个具体的产品类

每个具体工厂类创建一个具体产品类的实例

把简单工厂的内部逻辑判断移到客户端来实现,若要增加功能,修改客户端代码

新增加产品,增加对应的产品和具体工厂类即可

符合开封原则,保持封装对象创建过程的优点

抽象工厂:

用抽象工厂创建产品

生产不同产品族的全部产品

有多个抽象产品类,每个抽象产品类可以派生出多个具体的产品类

每个具体工厂类创建多个具体产品类的实例

 

 


简单工厂设计模式是工厂设计模式的一种特例。

抽象工厂和工厂设计模式的区别在于创建对象的复杂性上:

工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。   
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

 

工厂类设计模式对新增加的类,修改比较多,所以采用反射的机制。

 

 

4、反射+简单工厂设计模式

 

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制

 

 

实现代码:

 

/**
 * 抽象产品
 * @author zzj
 *
 */
public interface Fruit {
	void eat();
}


/**
 * 具体产品
 * @author zzj
 *
 */
public class Apple implements Fruit {

	@Override
	public void eat() {
		System.out.println("eat apple");
	}

}

/**
 * 具体产品
 * @author zzj
 *
 */
public class Orange implements Fruit {

	@Override
	public void eat() {
		System.out.println("eat orange");
	}

}

/**
 * 工厂类,创建实例
 * @author zzj
 *
 */
public class Factory {
	public static Fruit getInstance(String className){
		Fruit fruit = null;
		try {
			fruit = (Fruit) Class.forName(className).newInstance();
		} catch (Exception e) {
			System.out.println(e);
		}
		return fruit;
	}

}

/**
 * 工厂设计模式与反射结合
 * @author zzj
 * 2017/6/10
 */
public class Client {
	public static void main(String[] args){
		Fruit fruit = null;
		fruit = Factory.getInstance("com.zzj.factory.reflectFactory.Apple");
		if(fruit!=null){
			fruit.eat();
		}else{
			System.out.println("no apple");
		}
		
		fruit = Factory.getInstance("com.zzj.factory.reflectFactory.Orange");
		if(fruit!=null){
			fruit.eat();
		}else{
			System.out.println("no orange");
		}
		
		fruit = Factory.getInstance("com.zzj.factory.reflectFactory.Banana");
		if(fruit!=null){
			fruit.eat();
		}else{
			System.out.println("no banana");
		}
	}

}

 

 

 输出结果:

 

 

eat apple
eat orange
java.lang.ClassNotFoundException: com.zzj.factory.reflectFactory.Banana
no banana
 

 

优点:这样无论增加多少个子类,工厂类都不用做任何的修改。

 

可以要把实例的类写在配置文件中,在属性文件中使用apple和orange表示完整的包.类名称

 

在使用时工厂就会根据配置文件所提供的实现类反射出对象,而我们如果要切换实现类,只需要修改一下配置文件即可,但不需要修改源代码。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值