作者:NiceCui

概述

工厂模式包括:

  1. 简单工厂模式
  2. 工厂方法模式
  3. 抽象工厂模式
  • 工厂模式符合软件开发中的OCP原则(open close principle),对扩展开放,对修改关闭。

  • 无论是工厂方法模式,还是抽象工厂模式,都属于工厂模式,在形式和特点上很相近,他们的最终目的都是为了解耦。

总览

简单工厂模式

  1. 一个抽象产品类,派生出多个具体产品类
  2. 一个工厂类,通过逻辑判断,实例化所需的产品类

具体的描述

  • [x] (1) ==抽象产品类==:为各种具体产品声明抽象类或者接口
  • [x] (2) ==具体产品类==:抽象产品的具体实现,对应具体的产品
  • [x] (3) ==工厂类==:用户只关注产品,无需关注具体实现,生产出具体的产品

工厂方法模式

  1. 一个抽象产品类,派生出多个具体产品类
  2. 一个抽象工厂类,派生出多个具体工厂类
  3. 每个具体工厂类只能生产出一个具体的产品类

具体的描述

  • [x] (1) ==抽象产品类==:为各种具体产品声明抽象类或者接口
  • [x] (2) ==具体产品类==:抽象产品的具体实现
  • [x] (3) ==抽象工厂类==:声明了==一个==方法,只对应一种产品
  • [x] (4) ==具体工厂类==:抽象工厂的实现,生成==一个==具体产品 ==(一组产品)==

抽象工厂模式

  1. 多个抽象产品类,每个抽象产品类都可以派生出多个具体产品类
  2. 一个抽象工厂类,可以派生出多个具体工厂类
  3. 每个具体工厂类都能生成出多个具体产品类 (后续都有相应代码,看了就会懂)

具体的描述

  • [x] (1) ==抽象产品类==:为各种具体产品声明抽象类或者接口
  • [x] (2) ==具体产品类==:抽象产品的具体实现
  • [x] (3) ==抽象工厂类==:声明了==一组方法==,每个方法对应一种类型产品
  • [x] (4) ==具体工厂类==:抽象工厂的实现,生成一组具体产品 ==(一组产品)==

代码实现

==简单工厂模式==

抽象产品类

package com.nicecui.design.factory.simple;
/**
 * 
 * Fruits
 * @author NiceCui
 * @date 2018年1月23日上午11:33:37
 *
 */
public abstract class Fruits {
    
    public abstract void print();
}

具体产品类

// 苹果
public class Apple extends Fruits {

    @Override
    public void print() {
        System.out.println("This is a Apple");
        
    }
}
//橙子
public class Orange extends Fruits {

    @Override
    public void print() {
        // TODO Auto-generated method stub
        System.out.println("This is a Orange");
    }
}

工厂类

package com.nicecui.design.factory.simple;
/**
 * 
 * FruitsFactory
 * @author NiceCui
 * @date 2018年1月23日上午11:33:20
 *
 */
public class FruitsFactory {
    
    public Fruits getFruit(String name) {
        Fruits fruit = null;
        if(""==name||name == null) {
            return fruit;
        }
        switch (name) {
        case "Apple":
            fruit = new Apple();
            break;

        case "Orange":
            fruit = new Orange();
            break;
        }
        return fruit;
    }
}

==工厂方法模式==

  • 实现一个加减的计算机

抽象产品类

package com.nicecui.design.factory.method;

public abstract class Operation {
    
    public int A;
    public int B;
    
    public int getA() {
        return A;
    }

    public void setA(int a) {
        A = a;
    }

    public int getB() {
        return B;
    }

    public void setB(int b) {
        B = b;
    }
    
    public abstract void getResult() ;
    
}

具体产品类


//加法
public class OperationAdd extends Operation{
    
    public int a;
    public int b;
    
    public OperationAdd() {
    
    }
    
    @Override
    public void getResult() {
        
        System.out.println("a+b="+(super.A+super.B));
    }
}
// 减法
public class OperationSub extends Operation{
    
    public int a;
    public int b;
    
    @Override
    public void getResult() {
        // TODO Auto-generated method stub
        System.out.println("a-b="+(super.A - super.B));
    }
}

抽象工厂类和具体工厂

package com.nicecui.design.factory.method;

public interface IFactory {
    
    Operation createOperation();
    
}

class AddFactory implements IFactory{

    @Override
    public Operation createOperation() {
        // TODO Auto-generated method stub
        return new OperationAdd();
    }
    
}

class SubFactory implements IFactory{

    @Override
    public Operation createOperation() {
        // TODO Auto-generated method stub
        return new OperationSub();
    }
    
}

==抽象工厂模式==

  • 生产一辆汽车的工厂,配置不一样,有进口和本地发动机和在淘宝和京东购买的座椅

抽象产品类


//座椅
public interface Chair {
    
    public void getChair();

}

//发动机
public interface Engine {
    
    public void getEngine ();
}

具体产品类

/**座椅**/

//京东买的
public class JD_Chair implements Chair{

    @Override
    public void getChair() {
        // TODO Auto-generated method stub
        System.out.println("从京东购买的座椅....");
    }
}
//淘宝买的 
public class TB_Chair implements Chair {

    @Override
    public void getChair() {
        // TODO Auto-generated method stub
        System.out.println("从淘宝买的座椅.....");
    }
}
/**发动机**/

//进口的
public class Import_Engine implements Engine{

    @Override
    public void getEngine() {
        // TODO Auto-generated method stub
        System.out.println("使用进口发动机....");
    }
}

//本地的
public class Local_Engine implements Engine{

    @Override
    public void getEngine() {
        // TODO Auto-generated method stub
        System.out.println("使用本地发动机....");
    }
}

抽象工厂

public interface CarFactory {
    
    //一组方法 对应 一组产品 上面有讲过
    public Chair getChair();
    public Engine getEngine();
}

具体工厂

  • 生产具体产品
//生产A型号的汽车
public class AcarFactory implements CarFactory{

    @Override
    public Chair getChair() {
        // TODO Auto-generated method stub
        return new JD_Chair();
    }

    @Override
    public Engine getEngine() {
        // TODO Auto-generated method stub
        return new Local_Engine();
    }
}
//生产B型号的汽车
public class BcarFactory implements CarFactory{

    @Override
    public Chair getChair() {
        // TODO Auto-generated method stub
        return new TB_Chair();
    }

    @Override
    public Engine getEngine() {
        // TODO Auto-generated method stub
        return new Import_Engine();
    }
}

总结

简单工厂模式

==优点==

  • 第一点当然是简单了,当耦合不是很大时候,简单工厂很适合
  • 最大的优点就是将类的实例化交给工厂类,工厂类中包含了必要的逻辑判断
  • ==客户端角度分析==客户选择条件动态的实例化相关的类,去除了与具体产品的依赖

==缺点==

  • 简单工厂模式不利于拓展,违背了==开放封闭原则==,每次添加一个类,都要修改工厂类

工厂方法模式

==优点==

  • 工厂方法模式对简单工厂模式进行了升级,将类的实例化延迟到了其子类==(也就是具体工厂类)==
  • 拓展添加具体类,无需对抽象工厂类修改,只需要添加想要的具体类和具体工厂即可

==缺点==

  • 面对再复杂的有点力不从心,例如:如若增加另一个产品体系,刚才我们的工厂方法是实现计算机,若果我们要来一台==电视机==呢,还是得再去抽象工厂添加修改,这样也会违背==开放封闭原则==

抽象工厂模式

==优点==

  • 可以针对多个产品系,很容易组合产品系列,只需要去实现具体的工厂类即可;例如:我们再添加一个C型号的车 需要 进口发动机和京东座椅 那我们只需要去添加相应的具体工厂就可以了。
  • 具有工厂方法模式解耦的优点。
  • ==产品系== 进口发动机和本地发动机为两个不同的等级结构,搭载进口发动机的车子就是一个产品系

==缺点==

  • 对于产品系的扩展将非常费劲,例如我们要生产的所有车子,需要配备 进口轮胎或者本地轮胎,产品系中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。

==最后开门说白话==

论文式解说 –> 现场对白式解答

设计模式的一个重要原则就是:别改代码,只需要添代码,以前所有的老代码,都是有价值的,需要尽力保留

  • new一个对象时,new的过程是宝贵的如何创建老对象的知识点(有的new很复杂,包括了很多参数),如果这个代码被修改了,那么保留的老对象也不知道怎么使用了,整个体系残缺了所以要想办法保留老对象的new过程,把这个new过程保存分布到一系列工厂类里,就是所谓的工厂模式。

  • 简单工厂:把对象的创建放到一个工厂类中,通过参数来创建不同的对象。
    这个缺点是每添一个对象,就需要对简单工厂进行修改(尽管不是删代码,仅仅是添一个switch case,但仍然违背了“不改代码”的原则)

  • 工厂方法:每种产品由一种工厂来创建,一个工厂保存一个new ,基本完美,完全遵循
    “不改代码”的原则

  • 抽象工厂:仅仅是工厂方法的复杂化,保存了多个new 大工程才用的上

关注公众号

image

版权声明:本文为NiceCui原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/NiceCui/p/8365676.html