Java设计模式之工厂模式

坚强是说给别人听的谎言 提交于 2019-12-13 11:33:29

一、简单工厂模式

1.概述

简单工厂模式也叫静态工厂模式,将所有的创建对象任务交给了一个工厂类来实现,要想使用对象,直接找工厂类即可。

以动物工厂类为例,可以将创建动物对象的任务全放在动物工厂类来实现,在动物工厂类中定义静态方法,根据传递不同的参数类创建不同的动物对象。

要素分析:

  1. 定义抽象类:动物具有共同的属性:吃,因此可以创建一个动物抽象类,定义“吃”的抽象方法
  2. 定义具体的操作类:动物有很多,以猫和狗为例,创建猫类和狗类,继承动物类,实现“吃”的抽象方法
  3. 定义简单工厂:根据传递不同的参数类创建不同的动物对象
  4. 测试类:调用工厂类创建对象

2.实现

1.定义抽象类

public abstract class Animal {
    public abstract void eat();
}

2.定义具体的操作类

public class Cat extends Animal{
    public void eat() {
        System.out.println("猫吃鱼");
    }
}
public class Dog extends Animal {
    public void eat() {
        System.out.println("狗吃肉");
    }
}

3.定义简单工厂

public class Factory {
    public static Animal creatAnimal(String name){
        if("cat".equals(name)){
            return new Cat();
        }else if ("dog".equals(name)){
            return new Dog();
        }
        return null;
    }
}

4.测试类

public static void main(String[] args){
    Animal cat = Factory.creatAnimal("cat");
    Animal dog = Factory.creatAnimal("dog");
    cat.eat();
    dog.eat();
}

二、工厂方法模式

1.简述

在简单工厂模式当中,是根据需要传递响应的参数去调用工厂中的方法创建对象,但开发人员并不知道哪些参数能够传递,这样就造成返回不了自己想要的对象的后果,而工厂方法模式将每个对象都交给各自工厂去创建,避免了这种弊端。

要素分析:

  • 工厂接口:工厂接口是工厂方法模式的核心,与调用者直接交互来提供产品,在实际编程中,有时候也会使用一个抽象类来作为与调用者交互的接口,其本质是一样的。
  • 工厂实现:工厂实现决定如何实例化产品,是实现拓展的途径,需要有多少种产品就需要多少个具体的工厂实现
  • 产品接口:产品接口的主要目的是定义产品的规范,所有的产品实现都必须遵循产品接口定义的规范。产品 接口是调用者最为关心的,产品接口定义的优劣直接决定了调用者代码的稳定性。同样,产品接口也可以用抽象类来代替,但要注意最好不要违反里氏替换原则。
  • 产品实现:实现产品接口的具体类,决定了产品在客户端中的具体行为。

2.实现

(1)工厂接口

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

(2)工厂实现类

public class catFactory implements Factory{
    public Animal createAnimal() {
        return new Cat();
    }
}
public class dogFactory implements Factory {
    public Animal createAnimal() {
        return new Dog();
    }
}

(3)产品接口

public abstract class Animal {
    public abstract void eat();
}

(4)产品实现类

public class Cat extends Animal {
    public void eat() {
        System.out.println("猫吃鱼");
    }
}
public class Dog extends Animal {
    public void eat() {
        System.out.println("狗吃肉");
    }
}

(5)测试类

public class Test {
    public static void main(String[] args){
        Factory catfactory = new catFactory();
        Animal cat = catfactory.createAnimal();
        Factory dogfactory = new dogFactory();
        Animal dog = dogfactory.createAnimal();
        cat.eat();
        dog.eat();
    }
}

三、抽象工厂模式

1.概述

在抽象工厂中,有一个产品族的概念:即位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模型所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。

要素分析:

  • 抽象工厂:声明一组用于创建一族产品的方法,每个方法对应一种对象;在抽象工厂中声明了多个工厂方法, 用于创建不同类型的对象, 抽象工厂可以是接口, 也可以是抽象类或者具体类
  • 具体工厂:具体工厂实现了抽象工厂,每个工厂方法返回一个具体对象,一个具体工厂所创建的具体对象构成一个族
  • 抽象类接口:提供一组所有类都具有的业务方法
  • 抽象类:用于实现抽象接口所定义的业务方法,但是该角色对于抽象接口定义的方法只做抽象实现,即所有实现都被定义为抽象方法,最终的具体实现全部交给具体类实现。引入该角色主要是为了根据声明不同的抽象类,将类区分为不同的等级结构
  • 具体类:该角色继承抽象类,主要用于实现抽象类中声明的抽象方法,完成不同等级结构,不同族的业务方法的具体实现

2.实现

package com.liebrother.designpatterns.abstractfactory;
 
/**
 * 轮胎工厂
 */
interface WheelFacatory {
 
    String createWheel();
}
 
/**
 * 宝马轮胎工厂
 */
class BMWWheelFacatory implements WheelFacatory {
 
    @Override
    public String createWheel() {
        System.out.println("宝马轮胎工厂生产轮胎");
        return "宝马轮胎";
    }
}
 
/**
 * 奔驰轮胎工厂
 */
class MercedesWheelFacatory implements WheelFacatory {
 
    @Override
    public String createWheel() {
        System.out.println("奔驰轮胎工厂生产轮胎");
        return "奔驰轮胎";
    }
}
 
/**
 * 方向盘工厂
 */
interface SteeringWheelFacatory {
 
    String createSteeringWheel();
}
 
/**
 * 宝马方向盘工厂
 */
class BMWSteeringWheelFacatory implements SteeringWheelFacatory {
 
    @Override
    public String createSteeringWheel() {
        System.out.println("宝马方向盘工厂生产方向盘");
        return "宝马方向盘";
    }
}
 
/**
 * 奔驰方向盘工厂
 */
class MercedesSteeringWheelFacatory implements SteeringWheelFacatory {
 
    @Override
    public String createSteeringWheel() {
        System.out.println("奔驰方向盘工厂生产方向盘");
        return "奔驰方向盘";
    }
}

/**
 * 汽车抽象工厂
 */
interface AbstractCarFactory {
 
    void installWheel();
    void installSteeringWheel();
}
 
/**
 * 宝马工厂
 */
class BMWCarFactory implements AbstractCarFactory {
 
    @Override
    public void installWheel() {
        WheelFacatory wheelFacatory = new BMWWheelFacatory();
        String wheel = wheelFacatory.createWheel();
        System.out.println("安装轮胎:" + wheel);
    }
 
    @Override
    public void installSteeringWheel() {
        SteeringWheelFacatory steeringWheelFacatory = new BMWSteeringWheelFacatory();
        String steeringWheel = steeringWheelFacatory.createSteeringWheel();
        System.out.println("安装方向盘:" + steeringWheel);
    }
}
 
/**
 * 奔驰工厂
 */
class MercedesCarFacatory implements AbstractCarFactory {
 
    @Override
    public void installWheel() {
        WheelFacatory wheelFacatory = new MercedesWheelFacatory();
        String wheel = wheelFacatory.createWheel();
        System.out.println("安装轮胎:" + wheel);
    }
 
    @Override
    public void installSteeringWheel() {
        SteeringWheelFacatory steeringWheelFacatory = new MercedesSteeringWheelFacatory();
        String steeringWheel = steeringWheelFacatory.createSteeringWheel();
        System.out.println("安装方向盘:" + steeringWheel);
    }
}
 

public class AbstractFactoryTest {
 
    public static void main(String[] args) {
        // 宝马员工安装轮胎和方向盘
        AbstractCarFactory bmwCarFacatory = new BMWCarFactory();
        bmwCarFacatory.installWheel();
        bmwCarFacatory.installSteeringWheel();
        // 奔驰员工安装轮胎和方向盘
        AbstractCarFactory mercedesCarFacatory = new MercedesCarFacatory();
        mercedesCarFacatory.installWheel();
        mercedesCarFacatory.installSteeringWheel();
    }
 
}

三、总结

1.工厂模式优点

  • 工厂模式可以使代码结构清晰,有效的封装变化,在编程中,产品类的实例化有时候是比较复杂和多变的,通过工厂模式,将产品的实例化封装起来,使得调用者根本无需关心产品的实例化过程,只需依赖工厂即可得到自己想要的产品。
  • 对调用者屏蔽具体的产品类。如果使用工厂模式,调用者只关心产品的接口就可以了,至于具体的实现,调用者根本无需关心。即使变更了具体的实现,对调用者来说没有任何影响。
  • 降低耦合度。产品类的实例化通常来说是很复杂的,它需要依赖很多的类,而这些类对于调用者来说根本无需知道,如果使用了工厂方法,我们需要做的仅仅是实例化好产品类,然后交给调用者使用。对调用者来说,产品所依赖的类都是透明的。

2.工厂模式适用场景

  • 在任何需要生成复杂对象的地方,都可以使用工厂模式;而对于简单对象,只需要通过new就可以完成创建的对象就无需使用工厂模式
  • 工厂模式是一种典型的解耦模式,迪米特法则在工厂模式中表现的尤为明显。假如调用者自己组装产品需要增加依赖关系时,可以考虑使用工厂模式。将会大大降低对象之间的耦合度
  • 由于工厂模式是依靠抽象架构的,它把实例化产品的任务交由实现类完成,扩展性比较好。也就是说,当需要系统有比较好的扩展性时,可以考虑工厂模式,不同的产品用不同的实现工厂来组装

3.三种模型的区别

  • 简单工厂只有三个要素,没有工厂接口,并且得到产品的方法一般是静态的,其拓展性要稍弱,可以算是工厂方法模式的简化版
  • 抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相关依赖的对象
  • 工厂方法模式针对的是一个产品等级结构;抽象工厂模式针对多个产品等级结构
  • 工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类;抽象工厂模式所提供的产品则是衍生自不同的接口或抽象
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!