Java设计模式之工厂模式

前言
在23中设计模式中,工厂方法属于创建型的设计模式,只有工厂方法和抽象工厂两种,但是实际我们常与简单工厂混淆,因为简单工厂模式违背了开闭原则。

什么是开闭原则:
开闭原则就是说对扩展开放对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。

所以简单工厂不属于设计模式内的,但是并不是说简单工厂是错误的,只是根据具体情况使用而已。

下面我就针对简单工厂、工厂方法、抽象工厂结合Demo演示给大家。
正文
如图,就是工厂模式的划分。

简单工厂


概念:一个工厂类根据传入的参量决定创建出那一种产品类的实例。

想象一下汽车生产厂生产汽车,有两个工厂,分别是宝马和奔驰,客户想要买这两种车,就要分别去这两个工厂去买,结合在代码里就是客户分别传递不同的参数才可以得到不同的对象。

首先我们需要一个接口, 用来返回不同品牌的汽车。

public interface Car {
    void produce();
}

然后我们需要两个汽车

public class Benz implements Car {
    public void produce() {
        System.out.println("生产一辆奔驰");
    }
}

public class BMW implements Car {
    public void produce() {
        System.out.println("生产一辆宝马");
    }
}

接下来就是工厂,这个工厂就是根据客户传过来的不同参数返回不同的汽车。

public class CarFactory {
    public Car produce(String type) {
        if ("bmw".equals(type)) {
            return new BMW();
        } else if ("benz".equals(type)) {
            return new Benz();
        }else{
            System.out.printIn("类型错误");
        }
        return null;
    }
}

最后来了一个顾客说是要买宝马,让我们来测试一下吧

public class SimpleFactoryTest {

      public static void main(StringD args) {

      CarFactory factory = new CarFactory();
      Car car = factory.produce("bmw");
      car.produce();
     }
}

大家看代码可以得知,现在是两个车,就要写两个if去判断,如果以后出现很多个产品我个么就就要在1工厂方法里写多个if,这样就会造成拓展业务需要修改原有代码来实现,这样的写法可以实现,但是很low,建议同学们尝试以下两种。

工厂方法模式

概念:定义一个创建对象的接口,让子类决定实例化那个类。

工厂模式细分的话有两种,我在代码里会讲解一种,另一种在示例代码中体现,被我注释掉的就是普通工厂方法,大家一看便知。

与简单工厂重复的代码我就贴在一个代码块中了。

public interface Car {
    void produce();
}

public class Benz implements Car {
    public void produce() {
        System.out.println("生产一辆奔驰");
    }
}
public class BMW implements Car {
    public void produce() {
        System.out.println("生产一辆宝马");
    }
}

不同的地方就是工厂的写法,我们一个汽车品牌就新建一个工厂 方法。

public class BenzCarFactory {
/**
*工厂方法
* @return
*/
// public Car produceBenz() {
//  return new Benz();
// }
/**
*静态工厂方法
*
* @return
*/

public static Car produceBenz() [
    return new Benz();
 }
}
public class BMWCarFactory{
/**
*工厂方法
*@return
*/
// public Car produceBMW(){
//  return new BMW();
//}

/**
* 静态工厂方法
* @return
*/
public static Car produceBMW() {
    return new BMW();
 }
}

因为只静态的方法,那么在jvm加载时就已经创建了,所以我们在引|用的时候就不用new工厂对象了,这也是普通工厂方法与静态工厂方法的区别所在。

让我们看一下客户是怎么购买汽车的。

public class FactoryMethodTest {
//psvm .
  public static void main(StringD args) {
    /**
    *工厂方法
    */
//BenzCarFactory factory = new 
BenzCarFactory();
//  Car car = factory.produceBenz();
//  car.produce();
/**
*静态工厂方法*/
Car car = BenzCarFactory.produceBenz();
car.produce();
 }
}

可以看出,每个工厂只生产一种产品,客户端通过不同的工厂去生产不同的产品。这样做的好处就是我们对业务进行拓展时不用更改代码,只需要新增一个拓展对产品或者对象就可以,这也是最简单也是我认为最常用对工厂方法了。

抽象工厂

概念:创建相关或依赖对象的家族, 而无需明确指定具体类。

抽象工厂适用于复杂业务需求,复杂的产品生产场景中。怎么复杂呢?就是产品属性多了一个纬度,之前我们都是生产汽车,但是现在要区分出生产的颜色,对汽车的要求不仅仅是品牌还有颜色了。

来看看具体的代码实现:
首先定义三种颜色的接口

public interface Black {
  void create();
}

public interface Red {
  void create();
}

public interface White {
  void create();
}

然后定义我们存在的产品,我们现在只有黑色奔驰,黑色宝马,白色奔驰,白色宝马,红色奥迪。分别创建这五个产品的类。

public class BenzBlack implements Black {
    public void create() { 
      System.out.printIn("黑色奔驰");
    }
}

public class BenzWhite implements White {
    public void create() {
      System.out.printIn("白色奔驰");
    }
}

public class BMWBlack implements Black {
    public void create() {
        System.out.println("黑色宝马");
    }
}

public class BMWWhite implements White {
    public void create() {
        System.out.printIn("白色宝马"); ,
    }
}

public class RedAudi implements Red {
    public void create() {
        System.out.println("红色奥迪");
    }
}

然后我们定义工厂接口,工厂接口是把刚才颜色接口进行了统一整理在一 起。说明我们现在可以生产这三种颜色任意品牌汽车。

所以说对业务拓展性非常高。

public interface CarFactory {
Black black();
White white();
Red red();

那么就让我们随意创建E种汽车的工厂。

public class AudiFactory implements CarFactory{
    public Black black() {
        return null;
    }

public White white(){
    return null;
}

public Red red(){
    return new RedAudi();
}

public class BenzFactory implements CarFactory{
    public Black black(){
        return new BenzBlack();
    }
public White white(){
    return new BenzWhite();
}

public Red red() {
    return null;
    }
}

public class BMWFactory implements CarFactory {
    public Black black() {
        return new BMWBlack();
    }

    public White white() {
        return new BMWWhite();
    }

    public Red red() {
        return null;
    }
}

让我们来测试一下:

public class AbstractFactoryMethodTest{
    public static void main(StringD args){
        AudiFactory audi = new AudiFactory();
        Red redAudi = audi.red();
        redAudi.create();

        BenzFactory benz = new BenzFactory();
        Black blackBenz = benz.black();
        blackBenz.create();
   }
}

输出结果如下:

总结
简单工厂模式适用于工厂类需要创建的对象比较少的情况,客户只需要传入具体的参数,就可以忽略工厂的生产细节,去获取想要的对象;

工厂方法模式,主要是针对单一产品结构的情景,拓展时只需增加一个工厂类就可以;

抽象工厂模式则是针对多级产品结构(系列产品)的一种工厂模式,拓展时增加多个类,改动比较大;

最后在说一下, 每种模式都有自己的优点和弊端,没有最好的模式,只有最适合的模式,只要符合实际开发需求就是最好的。

作者:

喜欢围棋和编程。

 
发布于 分类 编程标签

发表评论

电子邮件地址不会被公开。