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); } }