版权声明:本文为博主原创文章,未经允许不得转载。 https://blog.csdn.net/qq_24672657/article/details/83046641
简单工厂
概念
-
定义:
由一个工厂对象决定创建出哪一种产品类的实例
-
类型:
创建型,但不属于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
方法能得到不同的具体产品的实例。
【参考】JDK中的工厂方法模式