設計模式-工廠方法模式

工廠方法模式

定義

定義一個用於建立對象的接口,讓子類決定實例化哪個類。工廠方法使一個類的實例化延遲到其子類
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();

 
	}
}
相關文章
相關標籤/搜索