设计模式-工厂方法模式

工厂方法模式

定义

定义一个用于建立对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类
uml

优势

1. 良好的封装,代码结构清晰
  2,扩展优秀。增长产品类或者对原有工厂实现稍加修改或增长工厂实现就能实现

缺点

产品多的状况会产生过多的产品类以及工厂

实现

假设是一个农场主养多种动物java

  • 动物抽象
public interface Animal {

	void eat();
}
public class Cat implements Animal{

	@Override
	public void eat() {
		System.out.println("猫吃鱼!");
	}
}
public class Sheep implements Animal {

	@Override
	public void eat() {
		System.out.println("羊吃草");
	}
}
  • 抽象工厂
public abstract class AbstractAnimalFactory {

	public abstract Animal create(Class<? extends Animal> animal);

}
  • 工厂的简单实现
public class AnimalFactory extends AbstractAnimalFactory {

	@Override
	public Animal create(Class<? extends Animal> animal) {
		Animal animal1 = null;
		try {
			 animal1 = animal.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return animal1;
	}
}
  • 农场主调用
public class Farmer {

	public static void main(String[] args) {
		AbstractAnimalFactory animalFactory = new AnimalFactory();
		Animal cat = animalFactory.create(Cat.class);
		cat.eat();

		Animal sheep = animalFactory.create(Sheep.class);
		sheep.eat();
	}
}

扩展

模块中只须要一个工厂类
  • uml

多个工厂类实现
  • uml

利用反射替换单例(未加线程安全,须要则参考上一篇单例模式
public class SingleFactory extends AbstractAnimalFactory {

	private static Animal instance = null;



	@Override
	public Animal create(Class<? extends Animal> animal) {

		if(instance == null){
			try {
				Class cl= Class.forName(animal.getName());
				Constructor constructor=cl.getDeclaredConstructor();
				constructor.setAccessible(true);
				instance = (Animal)constructor.newInstance();
				return instance;
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}

		}

		return instance;
	}


}

测试代码安全

package com.lrh.factory.animal;

import com.lrh.factory.animal.single.SingleFactory;

public class Farmer {

	public static void main(String[] args) {
 

		AbstractAnimalFactory singleFactory = new SingleFactory();

		Animal c1 = singleFactory.create(Cat.class);
		Animal c2 = singleFactory.create(Sheep.class);
		c1.eat();
		c2.eat();
		System.out.println(c1.hashCode());
		System.out.println(c2.hashCode());
 
	}
}
延迟初始化
延迟初始化:一个对象被消费完毕后并不马上释放,保持其初始化并等待被再次调用
public class DelayedIntFactory extends AbstractAnimalFactory {

	private final Map<String, Animal>  animalMap = new HashMap();

	@Override
	public synchronized Animal create(Class<? extends Animal> animal) {
		String name = animal.getName();
		if(animalMap.containsKey(name)){
			return animalMap.get(name);
		}else{
			Animal newAnimal = null;
			try {
				newAnimal = animal.newInstance();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
			animalMap.put(name, newAnimal);
			return newAnimal;
		}
	}
}

测试代码ide

package com.lrh.factory.animal;

import com.lrh.factory.animal.single.SingleFactory;

public class Farmer {

	public static void main(String[] args) {
		AbstractAnimalFactory animalFactory = new AnimalFactory();

 

		AbstractAnimalFactory delayedIntFactory = new DelayedIntFactory();
		Animal d1 = delayedIntFactory.create(Cat.class);
		Animal d2 = delayedIntFactory.create(Cat.class);
		Animal d3 = delayedIntFactory.create(Sheep.class);
		System.out.println(d1.hashCode());
		System.out.println(d2.hashCode());
		d1.eat();
		d2.eat();
		d3.eat();

 
	}
}
相关文章
相关标签/搜索