工厂模式的产生思想或思路
我们在创建类的时候,会用到很多功能特性相似的类,比如现在有很多动物类,猫,狗,猪……而这些动物有相同的行为,比如eat(),这时候我们就会抽取一个共同的抽象父类Animal,里面写个抽象方法eat(),然后由Cat类和Dog类去继承Animal类,各自实现格子的eat()方法。在调用时,我们可以直接Dog dog = new Dog(); Cat cat = new Cat(); 这样做本身是没有问题的。
但是在实际开发中,new Dog()和new Cat() 这些构造函数本身在初始化的时候,需要执行很多代码。这样直接导致new 对象这件事情变得很复杂。这样就会出现,调用处执行的是一种逻辑,需要了某个对象,结果在调用处创建对象的时候,做了一些其他的事情(虽然这很有必要),调用处的代码逻辑变得不清晰、连贯,而我们应该在调用处仅仅是获取对象调用对象方法即可,而不应该去考虑对象是如何被创建的。(体现了面向对象的六大原则之一单一职责原则)这样的话,工厂类的概念就被引出来了。
简单工厂模式
创建工厂类的方法:
1.创建类私有化构造方法或者创建抽象类
2.向外提供相应的静态方法
public class AnimalFactory {
private AnimalFactory(){}
public static Dog createDog(){
return new Dog();
}
public static Cat createCat(){
return new Cat();
}
}
这样调用处的代码就可以是:
Dog dog = AnimalFactory.createDog();
Cat cat = AnimalFactory.createCat();
但是上述代码还是有个麻烦就是,我们的动物可不止猫和狗,还有猪牛羊,如果我们想从AnimalFactory中提取到猪牛羊的对象,我们就得先创建猪牛羊的类,再修改AnimalFactory的代码,添加功能。而在实际开发中,我们应该是仅仅创建我们的新动物类,而不需要改动我们的工厂类。这就需要用到面向对象的六大原则中的另一个原则:开闭原则:对修改关闭,对扩展开放。也就是说可以增加新的类型去处理功能,但不能修改内部的代码逻辑。
所以上面代码中的工厂其实设计的不好。
所以工厂类可以做如下修改:
public class AnimalFactory {
private AnimalFactory(){}
public static Dog createDog(){
return new Dog();
}
public static Cat createCat(){
return new Cat();
}
public static Animal createAnimal(String type){
if(type.equals("cat")){
return new Cat();
}else if (type.equals("dog")){
return new Dog();
}
return null;
}
}
而调用的地方也变成了:
Animal animal = AnimalFactory.createAnimal("dog");
animal.eat();
animal = AnimalFactory.createAnimal("cat");
animal.eat();
当然,这里用到了多态。当然简单工厂模式其实并没有解决我们上述创建修改的问题,但是如果在工厂设计前期设计的好,还是会减少修改的。
工厂方法模式
其实就是对应创建对象的子父类,我们都去创建对应的工厂类,Animal类创建Animal类的工厂,Dog类创建Dog类的工厂,Cat类创建Cat类的工厂,子类的工厂类和父类的工厂类是子父类关系。这样,如果有新的类型加入,我们不需要改动现有的,直接创建继承自Animal类的对象类,创建继承自AnimalFactory类的对象工厂类。符合了开闭原则。
public abstract class AnimalFactory {
//private AnimalFactory(){}
public abstract Animal createAnimal();
public static Dog createDog(){
return new Dog();
}
public static Cat createCat(){
return new Cat();
}
public static Animal createAnimal(String type){
if(type.equals("cat")){
return new Cat();
}else if (type.equals("dog")){
return new Dog();
}
return null;
}
}
public class DogFactory extends AnimalFactory{
@Override
public Animal createAnimal() {
return new Dog();
}
}
调用者:
Animal animal = AnimalFactory.createAnimal("dog");
animal.eat();
animal = AnimalFactory.createAnimal("cat");
animal.eat();
AnimalFactory animalFactory = new DogFactory();
Animal animal1 = animalFactory.createAnimal();
animal1.eat();