[设计模式]工厂方法模式

工厂方法模式主要是对简单工厂模式的改良.

由于这个简单工厂模式中,工厂类负责的所有对象的创建,那么,当子类不断增多的时候,我们就需要
去修改工厂的代码,这样呢,就违反了一个原则:开闭原则.
(假如真的要创建一个cat,工厂是没有创建cat的功能的.现实情况可能真的有创建cat的需求的,所以这个时候就需要
更改工厂类中的创建对象的方法,就违反了一个原则:开闭原则.一个对象对扩展开放对修改关闭.如果修改的话可能对其他地方会有 影响.)

这个时候怎么办呢?
这个时候就采用另外一种模式:工厂方法模式.

 

场景:
Animal
|--AnimalFactory
动物吃的功能
|--Cat
|--CatFactory
|--Dog
|--DogFactory

这个时候,如果需要有一个新的子类添加,怎么解决呢?
举例:添加一个Pig类.
直接增加一个类,继承动物类.

优点:在工厂方法模式中,客户端不再负责对象的创建,并且当有新的子类添加的时候,
只需要添加一个子类和子类的工厂即可,不需要修改以前的结构,后期更
容易维护,增强了系统的扩展性.
缺点:使用该模式需要额外的编写代码,增加了工作量.

Animal.java

1 public abstract class Animal {
2     public abstract void eat();
3 }

Dog.java

1 public class Dog extends Animal{
2     public void eat() {
3         System.out.println("狗吃骨头");
4     }
5 }

Cat.java

1 public class Cat extends Animal{
2     public void eat() {
3         System.out.println("猫吃鱼");
4     }
5 }

AnimalFactory.java

public interface AnimalFactory {
    public  abstract Animal createAnimal();
}

DogFactory.java

1 public class DogFactory implements AnimalFactory{
2     public Animal createAnimal() {
3         return new Dog();
4     }
5 }

CatFactory.java

1 public class CatFactory implements AnimalFactory{
2     public Animal createAnimal() {
3         return new Cat();
4     }
5 }

如果这个时候根据需求要增加一个子类(Pig),不需要修改动物工厂类的源代码,只需要添加一个类继承工厂方法的接口就可以了.

Pig.java

1 public class Pig extends Animal{
2     public void eat() {
3         System.out.println("猪吃饲料");
4     }
5 }

PigFactory.java

1 public class PigFactory implements AnimalFactory {
2     public Animal createAnimal() {
3         return new Pig();
4     }
5 }

测试类:AnimalTest.java

 1 public class AnimalTest {
 2     public static void main(String[] args) {
 3         AnimalFactory af = new DogFactory();
 4         Animal a = af.createAnimal();
 5         a.eat();
 6 
 7         af = new CatFactory();
 8         a = af.createAnimal();
 9         a.eat();
10         //使用Pig工厂即可
11         af = new PigFactory();
12         a = af.createAnimal();
13         a.eat();
14     }
15 }

 最后附一张讲解图:

原文地址:https://www.cnblogs.com/DreamDrive/p/4084966.html