還記得前面講到過的簡單工廠模式嗎?
在客戶端(main中)的時候依然需要用到AnimalFactory.getAnimale(0)
來對動物種類進行選擇,則當新增加動物種類的時候,不能不在原工廠類AnimalFactory
中進行代碼的改動,這相當于在后臺進行改
動。
現在我們要解決的就是去掉Factory中的switch語句和任何判斷的邏輯,僅僅利用繼承或多態在客戶端實現對動物的選擇。
首先定義動物的基本性質(吃,叫,跑,睡)。
interface Animal{
public void eat();
public void shout();
public void run();
public void sleep();
}
然后實現物種多樣化
class Dog implements Animal{
@Override
public void eat() {
System.out.println("dog eat");
}
@Override
public void shout() {
System.out.println("dog shout");
}
@Override
public void run() {
System.out.println("dog run");
}
@Override
public void sleep() {
System.out.println("dog sleep");
}
}
class Cat implements Animal{
@Override
public void eat() {
System.out.println("cat eat");
}
@Override
public void shout() {
System.out.println("cat shout");
}
@Override
public void run() {
System.out.println("cat run");
}
@Override
public void sleep() {
System.out.println("cat sleep");
}
}
至此,與簡單工廠模式沒有任何區分。重點以下:
將工廠虛擬化,使得具體的工廠生產具體的動物,而所有的具體工廠都應當具有抽象工廠的特性(屬性或方法)。這個抽象的工廠以下:
interface Factory{
public Animal getAnimal();
}
對上述的動物,需要有對應的動物工廠:
class DogFactory implements Factory{
@Override
public Animal getAnimal() {
return new Dog();
}
}
class CatFactory implements Factory{
@Override
public Animal getAnimal() {
return new Cat();
}
}
終究,客戶端所要實現的東西即為:
public static void main(String[] args){
Factory dogFac = new DogFactory();
Animal dog = dogFac.getAnimal();
Factory catFac = new CatFactory();
Animal cat = catFac.getAnimal();
}
而不是簡單工廠方法中的:
public static void main(String[] args){
List<Animale> zoo = new ArrayList<Animale>();
for(int i=0;i<4;i++)
zoo.add(AnimalFactory.getAnimale(0));
for(int i=0;i<2;i++)
zoo.add(AnimalFactory.getAnimale(1));
for(int i=0;i<4;i++)
zoo.add(AnimalFactory.getAnimale(2));
for(int i=0;i<2;i++)
zoo.add(AnimalFactory.getAnimale(3));
for(Animale animale:zoo){
//animale....
}
}
這樣做的好處是,充分體現了面向接口編程而不是面向實現編程。面向接口,相當于將具體的實現插入到了這個接口。即使實現的東西有問題(DogFactory or CatFactory
),直接把它替換掉,或修改對應的實現類便可;如果需要增加新的物種(山羊,母雞等等),只需要在Factory接口上插入GoatFactory或ChickenFactory便可。
其實依照這個思路,Animal
這個接口的實現也能夠理解為在Animal的接口上插入各種具體的動物。
打個比方:就好比計算機的主板上本身有各種各樣的插口,內存的、硬盤的、cpu的等等,這些都是接口;接口上插的是對應的實現,比如內存條,硬盤和不同規格的cpu。當這些實現壞了,就直接拔下來換個好的插上,就相當于上述例子中
Factory
接口上的DogFactory
有問題,那末直接修改DogFactory便可,而不用動CatFactory,更不用動主板main方法。
試想如果計算機的主板上不是插口,而是直接焊接的各種原件,那末當任何1個壞掉以后,都需要對主板進行修理,那末這個損失將是巨大的。換言之,在簡單工廠模式中,改動任何1個動物(增加、刪除)都會使得Factory
類進行修改同時,客戶端main中的邏輯也可能需要修改。
綜上所述,工廠模式的的確確很好的體現了面向接口編程的思想,也更好的利用多態,將類和類之間有效的解耦,是1款經典的設計模式。