設計模式|簡單工廠、工廠方法、抽象工廠
阿新 • • 發佈:2018-12-15
簡單工廠
概念
-
定義:
由一個工廠物件決定創建出哪一種產品類的例項
-
型別:
建立型,但不屬於GOF23種設計模式
-
使用場景
-
優點
-
缺點
案例一
動物的抽象類
public abstract class Animal {
public abstract void eat();
}
public class Cat extends Animal {
public void eat() {
System.out.println("Cat is eating");
}
}
public class Dog extends Animal {
public void eat() {
System.out.println("Dog is eating");
}
}
public class Demo {
@Test
public void demo1(){
Animal cat = new Cat();
cat.eat();
Animal dog = new Dog();
dog.eat();
}
}
缺點:應用層依賴具體的實現類
思路:讓應用層不依賴具體的實現類
重構
簡單工廠demo1
public class AnimalFactory {
public Animal getAnimal(String name){
Animal animal = null;
if ("cat".equalsIgnoreCase(name)){
animal = new Cat();
}else if ("dog".equalsIgnoreCase(name)){
animal = new Dog();
}
return animal;
}
}
測試
@Test
public void demo2(){
AnimalFactory animalFactory = new AnimalFactory();
Animal cat = animalFactory.getAnimal("cat");
if (cat == null){
return;
}
cat.eat();
}
缺點:當需要新增一個實現時,需要破壞animalFactory原有的程式碼,不符合開閉原則。
簡單工廠demo2
在AnimalFactory工廠類中,重寫getAnimal方法
public Animal getAnimal(Class<Cat> c){
Animal animal = null;
try {
animal = (Animal) Class.forName(c.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return animal;
}
測試
@Test
public void demo3(){
AnimalFactory animalFactory = new AnimalFactory();
Animal cat = animalFactory.getAnimal(Cat.class);
if (cat == null){
return;
}
cat.eat();
}
測試成功
工廠方法
概念
- 定義:定義一個建立物件的介面,但讓實現這個介面的類來決定例項化哪個類。工廠方法讓類的例項化推遲到子類中進行。
- 型別:建立型
- 使用場景
- 建立物件需要大量重複的程式碼
- 應用層不依賴與產品類例項如何被建立、實現等細節。
- 一個類通過其子類來指定建立哪個物件
- 優點
- 使用者只需要關心所需要物件對應的工廠,無需關心建立的細節。
- 加入新的功能是複合開閉原則,提高擴充套件性
- 缺點
- 類的個數容易過多,增加複雜度
- 增加了系統的抽象性和理解難度
案例二
安裝工廠方法的定義,對上面的案例一進行重構
- 將AnimalFactory定義成抽象類,定義一個建立物件的抽象方法。
public abstract class AnimalFactory {
public abstract Animal getAnimal();
}
AnimalFactory只是定義一種規範,不定義具體的實現。完全交給子類來實現。
public class CatFactory extends AnimalFactory {
public Animal getAnimal() {
return new Cat();
}
}
public class DogFactory extends AnimalFactory {
public Animal getAnimal() {
return new Dog();
}
}
應用層呼叫
public class Demo {
@Test
public void demo4(){
AnimalFactory catFactory = new CatFactory();
Cat cat = (Cat) catFactory.getAnimal();
cat.eat();
}
}
這樣擴充套件性增加了。
應用
Collection中的iterator方法
java.util.Collection
介面中定義了一個抽象的 iterator()
方法,該方法就是一個工廠方法。
對於 iterator()
方法來說 Collection
就是一個根抽象工廠,下面還有 List
等介面作為抽象工廠,再往下有 ArrayList
等具體工廠。
java.util.Iterator
介面是根抽象產品,下面有 ListIterator
等抽象產品,還有 ArrayListIterator
等作為具體產品。
使用不同的具體工廠類中的 iterator
方法能得到不同的具體產品的例項。