2.2简单/静态工厂模式
现在宠物店生意不好做啊,号称“什么宠物都有",这吹过头了~~于是店主只卖两种常见的宠物了。
- 既然就只有两种宠物的话,那就没必要有”猫厂“、”狗厂“了,一个猫狗厂就行了!
所以我们的工厂是这样子的:
public class AnimalFactory { public static Dog createDog() { return new Dog(); } public static Cat createCat() { return new Cat(); } // 外界想要猫要狗,这里创建就好了 public static Animal createAnimal(String type) { if ("dog".equals(type)) { return new Dog(); } else if ("cat".equals(type)) { return new Cat(); } else { return null; } } }
三个实体还是没变(动物、猫、狗)….
那么Java3y去宠物店买猫狗的时候,告诉老板我要猫、我要狗:
// 拿到狗 Animal A = AnimalFactory.createAnimal("dog"); A.eat(); // 拿到猫 Animal C = AnimalFactory.createAnimal("cat"); C.eat();
现在问题来了:
- 1:我想要一个猪,可是我的工厂类没有猪
- 2:我就去改代码,写可以创建猪对象的
- 3:接着,我又要其他的动物
- 4:我还是得改代码
- 5……………….
- 6:这就是简单工厂类的缺点:当需求改变了,我就要改代码.
简单工厂类的优点也很明显:我就一个具体的工厂来创建对象,代码量少。
2.3抽象工厂模式
抽象工厂模式就比较复杂了,我们一般的应用都写不到。我首先来简述一下需求吧:
- 现在非常流行在猫狗届也吹起了一股“性别风”
- 有的喜欢公的
- 有的喜欢母的
那我们的猫和狗都是有性别的,不是公的就是母的~~
- 我们之前在工厂方法模式下是每个动物都开一个工厂,如果动物过多的话,那么就有很多的工厂~
- 那现在我们可以抽取出来:每个动物不是公的就是母的~
- 所以我们有两个工厂就足够了!
具体的代码是这样的:
我们的最大工厂还是定义了创建什么动物
public interface AnimalFactory { Animal createDog(); Animal createCat(); }
创建母猫和母狗的工厂:
public class FemaleAnimalFactory implements AnimalFactory { // 生产母狗和母猫 @Override public Animal createDog() { return new FemaleDog(); } @Override public Animal createCat() { return new FemaleCat(); } }
创建公猫和公狗的工厂:
public class MaleAnimalFactory implements AnimalFactory { // 生产公狗和公猫 @Override public Animal createDog() { return new MaleDog(); } @Override public Animal createCat() { return new MaleCat(); } }
这是所有动物都拥有的普遍行为:
public abstract class Animal { // 所有的动物都会吃东西 public abstract void eat(); // 所有的动物都有性别 public abstract void gender(); }
这是猫都拥有的普遍行为:
public abstract class Cat extends Animal { // 猫喜欢吃鱼 @Override public void eat() { System.out.println("猫吃鱼"); } }
这是狗都拥有的普遍行为:
public abstract class Dog extends Animal { // 狗喜欢吃肉 @Override public void eat() { System.out.println("狗吃肉"); } }
猫分为公猫、母猫。狗分为公狗和母狗:
public class FemaleCat extends Cat { public void gender() { System.out.println("I am a female Cat"); } }
…..
简单来说:工厂方法模式的工厂是创建出一种产品,而抽象工厂是创建出一类产品。
- 一类的产品我们称之为产品族。
- 猫是一类的,狗也是一类的。所以AnimalFactory定义了两类产品--->
Animal createDog();
和Animal createCat();
- 产品的继承结构称之为产品等级。
- 所有的狗都是会吃肉的,所以Dog实现了
eat()
方法
- 狗又分成了公狗和母狗,所以定义了两个类FemaleDog和MaleDog继承了Dog,实现了
gender()
方法
- 所有的猫都是会吃鱼的,所以Cat实现了
eat()
方法
- 猫又分成了公猫和母猫,所以定义了两个类FemaleCat和MaleCat继承了Cat,实现了
gender()
方法
- 具体的工厂是面向多个产品等级结构进行生产。
- 所以FemaleAnimalFactory定义了
createDog()
和createCat()
生产母狗和母猫 - 所以MaleAnimalFactory定义了
createDog()
和createCat()
生产公狗和共猫
- 找到母工厂就可以创建母猫和母狗,找到公工厂就可以创建公猫和公狗
public static void main(String[] args) { // 需要性别为母的就去找母工厂 AnimalFactory af = new FemaleAnimalFactory(); // 需要一只母猫 af.createCat().gender(); // 需要一只母狗 af.createDog().gender(); System.out.println("-------------关注公众号:Java3y-------------------------"); // 需要性别为公的就去找公工厂 AnimalFactory aff = new MaleAnimalFactory(); // 需要一只公狗 aff.createDog().gender(); // 需要一只公猫 aff.createCat().gender(); }
效果:
这是抽象工厂模式的类图:
抽象工厂模式说到底就是多了一层抽象,减少了工厂的数量。
抽象工厂缺点也很明显:
- 难以扩展产品族--->如果我再要宠物猪的话
- 那我要修改AnimalFactory、FemaleAnimalFactory、MaleAnimalFactory这些类了~
三、总结
总的来说我们用简单工厂模式比较多,工厂方式模式的话代码量会比较大,抽象工厂模式的话需要业务比较大的情况下才会用到(如果有更好的理解方式不妨在评论区留言,一起交流交流涨涨见识~~)
工厂模式配合反射来使用也是极好的~