ポリシーモードと外観モード


1.ポリシー:異なるアルゴリズムファミリーを定義し、互いに置換することができる.アルゴリズムの変化をアルゴリズムを使用するお客様とは独立させ、オブジェクトの動作を動的に変更します.
2.例:ランダムにペットを生成し、各種ペットの生成数を統計する.
a)抽象類:ペットをランダムに生成するPetCreator.
package context;



import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

import java.util.Random;



public abstract class PetCreator {

	

	private Random rand = new Random(47);

	

	//    ,    ,        

	public abstract List<Class<? extends Pet>> getTypes();

	

	public Pet randomPet() {

		int n = rand.nextInt(getTypes().size());

		try {

			return getTypes().get(n).newInstance();

		} catch (InstantiationException e) {

			e.printStackTrace();

		} catch (IllegalAccessException e) {

			e.printStackTrace();

		}

		return null;

	}

	

	public Pet[] createArray(int size) {

		Pet[] result = new Pet[size];

		for(int i=0; i<result.length; i++) {

			result[i] = randomPet();

		}

		return result;

	}

	

	public List<Pet> createList(int size) {

		List<Pet> result = new ArrayList<Pet>();

		Collections.addAll(result, createArray(size));

		return result;

	}

}


b)ポリシー1:文字列によるペットタイプの生成
package context;



import java.util.ArrayList;

import java.util.List;



public class ForNameCreator extends PetCreator {

	

	private static List<Class<? extends Pet>> types = new ArrayList<Class<? extends Pet>>();

	private static String[] typeNames = {

		"context.Pet",

		"context.Cat",

		"context.Dog",

		"context.Rodent",

		"context.MUTT",

		"context.PUG",

		"context.Manx",

		"context.EgyptianMau",

		"context.Cymric",

		"context.Rat",

		"context.Mouse",

		"context.Hamster"

	};

	

	@SuppressWarnings("unchecked")

	private static void loader() {

		try {

			for(String name : typeNames) {

				types.add((Class<? extends Pet>) Class.forName(name));

			}

		}  catch (ClassNotFoundException e) {

			e.printStackTrace();

		}

	}

	

	static {

		loader();

	}

	

	@Override

	public List<Class<? extends Pet>> getTypes() {

		return types;

	}



}


c)戦略2:classに基づいてペットタイプを生成する
package context;



import java.util.Arrays;

import java.util.Collections;

import java.util.List;



public class LiteralPetCreator extends PetCreator {

	

	@SuppressWarnings("unchecked")

	public static final List<Class<? extends Pet>> allType = Collections.unmodifiableList(Arrays.asList(

			Pet.class, Dog.class, Cat.class, Rodent.class, MUTT.class, PUG.class, Manx.class, 

			EgyptianMau.class, Cymric.class, Rat.class, Mouse.class, Hamster.class));

	

	private static final List<Class<? extends Pet>> types = allType.subList(allType.indexOf(MUTT.class), allType.size());



	@Override

	public List<Class<? extends Pet>> getTypes() {

		return types;

	}

}


d)カウンタ:ランダムに生成されたペットの数を統計する
package context;



import java.util.HashMap;



public class PetCount {

	static class PetConter extends HashMap<String, Integer> {

		

		private static final long serialVersionUID = 1L;



		public void count(String type) {

			Integer num = get(type);

			if(null == num) {

				put(type, 1);

			} else {

				put(type, num + 1);

			}

		}

	}

	

	public static void countPet(PetCreator petCreator) {

		PetConter petConter = new PetConter();

		for(Pet pet : petCreator.createArray(20)) {

			System.out.print(pet.getClass().getSimpleName() + " ");

			if(pet instanceof MUTT) {

				petConter.count("MUTT");

			} 

			if(pet instanceof PUG) {

				petConter.count("PUG");

			} 

			if(pet instanceof EgyptianMau) {

				petConter.count("EgyptianMau");

			} 

			if(pet instanceof Cymric) {

				petConter.count("Cymric");

			}

			if(pet instanceof Manx) {

				petConter.count("Manx");

			} 

			if(pet instanceof Rat) {

				petConter.count("Rat");

			}

			if(pet instanceof Mouse) {

				petConter.count("Mouse");

			}

			if(pet instanceof Hamster) {

				petConter.count("Hamster");

			}

			if(pet instanceof Rodent) {

				petConter.count("Rodent");

			}

			if(pet instanceof Dog) {

				petConter.count("Dog");

			}

			if(pet instanceof Cat) {

				petConter.count("Cat");

			}

			if(pet instanceof Pet) {

				petConter.count("Pet");

			}

		}

		System.out.println();

		System.out.println(petConter);

	}

	

	public static void main(String[] args) {

//		PetCount.countPet(new ForNameCreator());

		PetCount.countPet(Pets.creator);

	}

}


e)外観実装:ポリシー2をデフォルト実装として定義する
package context;



import java.util.List;



public class Pets {

	

	public static final PetCreator creator = new LiteralPetCreator();  //    

	

	public static Pet randomPet() {

		return creator.randomPet();

	}

	

	public static Pet[] createArray(int size) {

		return creator.createArray(size);

	}

	

	public static List<Pet> createList(int size) {

		return creator.createList(size);

	}

}


f)ペット類:
package context;



public class Pet {

	

	private String name;



	public Pet() {

		super();

	}



	public Pet(String name) {

		super();

		this.name = name;

	}



	public String getName() {

		return name;

	}



	public void setName(String name) {

		this.name = name;

	}

	

}



class Dog extends Pet {

	

	public Dog() {

		super();

	}

	

	public Dog(String name) {

		super();

	}

}



class MUTT extends Dog {



	public MUTT() {

		super();

	}



	public MUTT(String name) {

		super(name);

	}

	

}



class PUG extends Dog {



	public PUG() {

		super();

	}



	public PUG(String name) {

		super(name);

	}

	

}



class Cat extends Pet {



	public Cat() {

		super();

	}



	public Cat(String name) {

		super(name);

	}

	

}



class Manx extends Cat {



	public Manx() {

		super();

	}



	public Manx(String name) {

		super(name);

	}

	

}



class EgyptianMau extends Cat {



	public EgyptianMau() {

		super();

	}



	public EgyptianMau(String name) {

		super(name);

	}

	

}



class Cymric extends Manx {



	public Cymric() {

		super();

	}



	public Cymric(String name) {

		super(name);

	}

	

}



class Rodent extends Pet {



	public Rodent() {

		super();

	}



	public Rodent(String name) {

		super(name);

	}

	

}



class Rat extends Rodent {



	public Rat() {

		super();

	}



	public Rat(String name) {

		super(name);

	}

	

}



class Mouse extends Rodent {



	public Mouse() {

		super();

	}



	public Mouse(String name) {

		super(name);

	}

	

}



class Hamster extends Rodent {



	public Hamster() {

		super();

	}



	public Hamster(String name) {

		super(name);

	}

	

}