欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java设计模式之工厂模式(2)

程序员文章站 2024-01-21 17:47:58
...

往期博客-----> Java设计模式之单例模式(1)

工厂模式也是我们经常使用的23种模式之一,之前我们使用Mybatis时获取SqlSession对象就使用到了工厂模式,接下来我们学习一下工厂模式.

1.字面意思

  • 既然翻译过来是工厂模式,那么肯定其核心思想和工厂这个事务有些千丝万缕的关系,工厂就是产生产品的地方,我们给它原材料,然后加工给我们产品,这就是工厂干的事.

2.总体认识工厂模式的三种分类

类型 意义
简单工厂 一个工厂类根据传入的参量决定创建出哪一种产品类的实例
抽象工厂 创建相关或依赖对象的家族,而无需明确指定具体类。
工厂方法 定义一个创建对象的接口,让子类决定实例化那个类

3.简单工厂模式(静态工厂方法模式)

  • 定义:

在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

  • 通俗小故事来解释:

我们定义一个动物基因工厂,给我们动物的基因我们就可以产生对应动物的个体出来,比如一条狗的基因给我工厂加工,会产生一条狗,一只猫的基因产生一只猫,我们可以通过不同的参数(动物基因)来返回对应的实例(具体一个动物),但一般我们创建的都有一个共同父类(动物)

  • 具体代码实现:
  • 我们定义一个接口Ieat里面有一个eat()方法,因为动物都会吃,然后我们定义三种动物dog,cat,mouse三个类来实现这个接口:
interface Ieat{
    void eat();
}

class Dog implements Ieat{

    @Override
    public void eat() {
        System.out.println("狗狗啃骨头");
    }
}

class Cat implements Ieat{

    @Override
    public void eat() {
        System.out.println("猫咪吃老鼠");
    }
}

class Mouse implements Ieat{

    @Override
    public void eat() {
        System.out.println("老鼠吃大米");
    }
}
  • OK,重点来了,我们的基因工厂根据输入的参数来生产对应的实例产品,现在我们来写工厂类:
class GeneFactory{

    //根据传入的动物来返回对应的动物对象实例
    public Ieat getEat(String animalType){
        if (animalType==null){
            return null;
        }
        if (animalType.equalsIgnoreCase("DOG")){
            return new Dog();
        } else if(animalType.equalsIgnoreCase("CAT")){
            return new Cat();
        } else if (animalType.equalsIgnoreCase("MOUSE")){
            return new Mouse();
        }
        return null;
    }
}
  • 接下来我们使用简单工厂模式来测试一下:
public class Mytest02 {
    public static void main(String[] args) {
        Ieat dog = new GeneFactory().getEat("dog");
        dog.eat();
        Ieat cat = new GeneFactory().getEat("cat");
        cat.eat();
        Ieat mouse = new GeneFactory().getEat("mouse");
        mouse.eat();
    }
}
  • 结果实现截图:
    Java设计模式之工厂模式(2)

4.抽象工厂模式(Abstract Factory Pattern)

  • 定义:

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

  • 通俗解释一波:

还是基因工厂,简单工厂只是产生狗,猫这些大种类动物,没有产生哈士奇,拉布拉多等具体的狗种类,而超级基因工厂会先产生一个关于狗基因的工厂,再通过这个狗基因工厂来生产出特定的狗品种,比如哈士奇,拉布拉多.

  • 代码实现.
  • 首先我们的抽象工厂可以产生狗基因工厂(DogGeneFactory)和猫基因工厂(CatGeneFactory),然后基因工厂有一个方法获取特定种类的品种方法,狗工厂为getDogType(),猫工厂getCatType().对应工厂再根据传入的参数生产对应的对象实例.
  • 第一步,创建所有狗都会的吃骨头的接口Ieatbone,和猫会吃老鼠的接口Ieatmouse:
interface Ieatbone{
    void etaBone();
}

interface Ieatmouse{
    void eatmouse();
}
  • 第二步,写一个哈士奇类和拉布拉多类实现这个吃骨头接口,以及波斯猫和短耳猫实现吃老鼠接口.
class Husky implements Ieatbone{

    @Override
    public void etaBone() {
        System.out.println("哈士奇吃骨头");
    }
}

class Labrador implements Ieatbone{
    @Override
    public void etaBone() {
        System.out.println("拉布拉多吃骨头");
    }
}

class Persian implements Ieatmouse{

    @Override
    public void eatmouse() {
        System.out.println("波斯猫吃老鼠");
    }
}
class ShortCat implements Ieatmouse{

    @Override
    public void eatmouse() {
        System.out.println("短耳猫吃老鼠");
    }
}
  • 第三步:定义超级基因工厂(SuperGeneFactory抽象类),定义两个抽象方法获取对应基因工厂的方法:
abstract class SuperGeneFactory{
    public abstract Ieatbone getDogType(String dogtype);
    public abstract Ieatmouse getCatType(String cattype);
}
  • 第四步:写狗基因工厂和猫基因工厂来继承抽象类,实现方法:

class DogGeneFactory extends SuperGeneFactory{

    @Override
    public Ieatbone getDogType(String dogtype) {
        if (dogtype == null){
            return null;
        } else if(dogtype.equalsIgnoreCase("Husky")){
            return new Husky();
        } else if (dogtype.equalsIgnoreCase("Labrador")){
            return new Labrador();
        }
        return null;
    }

    @Override
    public Ieatmouse getCatType(String cattype) {
        return null;
    }
}

class CatGeneFactory extends SuperGeneFactory{

    @Override
    public Ieatbone getDogType(String dogtype) {
        return null;
    }

    @Override
    public Ieatmouse getCatType(String cattype) {
        if (cattype == null){
            return null;
        } else if(cattype.equalsIgnoreCase("Persian")){
            return new Persian();
        } else if (cattype.equalsIgnoreCase("ShortCat")){
            return new ShortCat();
        }
        return null;
    }
}
  • 第五步:通过工厂生成器(FactoryBuild)来获取指定种类的基因工厂:
class FactoryBuild{
    public static SuperGeneFactory getFactoryType(String factoryTppe){
        if (factoryTppe == null){
            return null;
        } else if (factoryTppe.equalsIgnoreCase("DOG")){
            return new DogGeneFactory();
        } else if(factoryTppe.equalsIgnoreCase("Cat")){
            return new CatGeneFactory();
        }
        return null;
    }
}
  • 第六步:测试:
public class Mytest02 {
    public static void main(String[] args) {
        //1.获取狗基因工厂
        SuperGeneFactory dogFactory = FactoryBuild.getFactoryType("dog");
        //2.获取猫基因工厂
        SuperGeneFactory catFactory = FactoryBuild.getFactoryType("cat");
        //3.生产哈士奇
        Ieatbone husky = dogFactory.getDogType("husky");
        husky.etaBone();
        //4.生产拉布拉多
        Ieatbone labrador = dogFactory.getDogType("Labrador");
        labrador.etaBone();
        //5.生产波斯猫
        Ieatmouse persian = catFactory.getCatType("Persian");
        persian.eatmouse();
        //6.生产短耳猫
        Ieatmouse shortCat = catFactory.getCatType("ShortCat");
        shortCat.eatmouse();
    }
}
  • 结果:
    Java设计模式之工厂模式(2)
  • 缺点和优点:
优点 缺点
当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。 产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

5.工厂方法模式

  • 创建抽象工厂类,定义具体工厂的公共接口;
  • 创建抽象产品类 ,定义具体产品的公共接口;
  • 创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
  • 创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
  • 外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例.