设计模式-简单工厂模式,工厂方法模式,抽象工厂模式

  1. 简单工厂模式

简单工厂模式不是23种设计模式之一!它只是日常编程中一种常用的方法或者说是这是一种习惯。

(1)简单工厂模式又称静态工厂模式(因为,它属工厂角色中定义的方法是静态方法),属于类创建模式,根据需求,我们可以根据传入的参数来返回不同子类的实例(其中用到了多态—继承,重写,向上转型)。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

在这里插入图片描述
(2)简单工厂模式最大的优点在于实现对象的创建和对象的使用分离,将对象的创建交给专门的工厂类负责,但是其最大的缺点在于工厂类不够灵活,增加新的具体产品需要修改工厂类的判断逻辑代码,这样就违背了开闭原则(对于扩展是开放的,对于修改是封闭的),而且产品较多时,工厂方法代码逻辑将会非常复杂。

在这里插入图片描述

案例代码如下
抽象产品角色:

package com.shuyu.operation;
 
import lombok.Data;
 

@Data
public class Operation {
    private double numberA=0;
    private double numberB=0;
 
    public  double getResult(){
        double result=0;
        return result;
    }
 
}

实例产品角色:


 
public class OperationAdd  extends Operation{
    @Override
    public double getResult() {
        double result=0;
        result=getNumberA()+getNumberB();
        return result;
    }
}
 
 
 

 
public class OperationSub extends Operation {
    @Override
    public double getResult() {
        double result=0;
        result=getNumberA()-getNumberB();
        return result;
    }
}
 
 
 
 

 
public class OperationMul extends Operation{
 
    @Override
    public double getResult() {
        double result=0;
        result=getNumberA()*getNumberB();
        return result;
    }
}
 
 
 

 
public class OperationDiv extends Operation {
 
    @Override
    public double getResult() {
        double result=0;
        if (getNumberB()==0){
            try {
                throw new Exception("除数不能为0");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else {
            result=getNumberA()/getNumberB();
        }
        return result;
    }
}

工厂角色:


 
public class OpreationFactory {
 
    public static Operation createOperate(String operate){
        Operation operation=null;
        switch (operate){
            case "+":
                operation=new OperationAdd();
                break;
            case "-":
                operation=new OperationSub();
                break;
            case "*":
                operation=new OperationMul();
                break;
            case "/":
                operation=new OperationDiv();
                break;
 
        }
        return operation;
    }
}

测试类:

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class SimplefactoryApplicationTests {
 

	@Test
	public void contextLoads() {
		Operation operation= OpreationFactory.createOperate("+");
		operation.setNumberA(1);
		operation.setNumberB(4);
		log.info("执行结果"+operation.getResult());
	}
 
}

输出结果:5.0
  1. 工厂方法模式

(1)工厂方法模式与简单工厂模式类似,区别在于使用不同的工厂类创建不同的具体产品对象,各个不同功能的实例对象的创建代码,没有耦合在同一个工厂类里,这也是工厂方法模式对简单工厂模式解耦的一个体现。工厂方法模式克服了简单工厂会违背开闭原则的缺点,又保持了封装对象创建过程的优点。

但工厂方法模式的缺点是每增加一个产品类,就需要增加一个对应的工厂类,增加了额外的开发量。

(2)抽象工厂:工厂模式的核心,提供一个创建对象的接口,任何需要创建对象的具体工厂都要实现这个接口。
具体工厂:实现抽象工厂接口的类,受到调用者的调用从而创建对象。
抽象产品:工厂方法模式所创建的对象的超类。也就是所有具体产品的共同父类。
具体产品:实现抽象工厂接口的类。工厂模式中所有创建的对象都是具体产品的实例。

在这里插入图片描述

代码实现如下:

抽象产品和具体产品:

import lombok.Data;
 
/**
 * @author Shuyu.Wang
 * @package:com.shuyu.operation
 * @className:
 * @description:基本运算接口
 * @date 2018-11-07 13:11
 **/
public interface Operation {
    public  double getResult(double numberA,double numberB);
 
}
 
 
 
 
 
/**
 * @author Shuyu.Wang
 * @package:com.shuyu.operation
 * @description:加法类
 * @date 2018-11-07 13:32
 **/
public class OperationAdd  implements Operation{
    @Override
    public double getResult(double numberA,double numberB) {
        double result=0;
        result=numberA+numberB;
        return result;
    }
}
 
 
 
 
 
/**
 * @author Shuyu.Wang
 * @package:com.shuyu.operation
 * @description:除法
 * @date 2018-11-07 13:42
 **/
 
public class OperationDiv implements Operation {
 
    @Override
    public double getResult(double numberA,double numberB) {
        double result=0;
        if (numberB==0){
            try {
                throw new Exception("除数不能为0");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else {
            result=numberA/numberB;
        }
        return result;
    }
}
 
 
 
 
 
/**
 * @author Shuyu.Wang
 * @package:com.shuyu.operation
 * @description:乘法
 * @date 2018-11-07 13:39
 **/
 
public class OperationMul implements Operation{
 
    @Override
    public double getResult(double numberA,double numberB) {
        double result=0;
        result=numberA*numberB;
        return result;
    }
}
 
 
 
 
 
/**
 * @author Shuyu.Wang
 * @package:com.shuyu.operation
 * @description:减法类
 * @date 2018-11-07 13:35
 **/
 
public class OperationSub implements Operation {
    @Override
    public double getResult(double numberA,double numberB) {
        double result=0;
        result=numberA-numberB;
        return result;
    }
}

抽象工厂和具体工厂:

import lombok.Data;
 
/**
 * @author Shuyu.Wang
 * @package:com.shuyu.operation
 * @className:
 * @description:基本运算接口
 * @date 2018-11-07 13:11
 **/
public interface Operation {
    public  double getResult(double numberA,double numberB);
 
}
 
 
 
 
 
/**
 * @author Shuyu.Wang
 * @package:com.shuyu.operation
 * @description:加法类
 * @date 2018-11-07 13:32
 **/
public class OperationAdd  implements Operation{
    @Override
    public double getResult(double numberA,double numberB) {
        double result=0;
        result=numberA+numberB;
        return result;
    }
}
 
 
 
 
 
/**
 * @author Shuyu.Wang
 * @package:com.shuyu.operation
 * @description:除法
 * @date 2018-11-07 13:42
 **/
 
public class OperationDiv implements Operation {
 
    @Override
    public double getResult(double numberA,double numberB) {
        double result=0;
        if (numberB==0){
            try {
                throw new Exception("除数不能为0");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else {
            result=numberA/numberB;
        }
        return result;
    }
}
 
 
 
 
 
/**
 * @author Shuyu.Wang
 * @package:com.shuyu.operation
 * @description:乘法
 * @date 2018-11-07 13:39
 **/
 
public class OperationMul implements Operation{
 
    @Override
    public double getResult(double numberA,double numberB) {
        double result=0;
        result=numberA*numberB;
        return result;
    }
}
 
 
 
 
 
/**
 * @author Shuyu.Wang
 * @package:com.shuyu.operation
 * @description:减法类
 * @date 2018-11-07 13:35
 **/
 
public class OperationSub implements Operation {
    @Override
    public double getResult(double numberA,double numberB) {
        double result=0;
        result=numberA-numberB;
        return result;
    }
}
  1. 抽象工厂方法

抽象工厂方法中一个工厂可以生产同一产品族的多中具体产品。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
举例:
问题:现有电脑产品配件厂商基于windows和apple生产不同类型的CPU和RAM,请试用抽象工厂模式描述该场景。

问题分析:
Windows产品包含WindowsCPU和WindowsRAM,(WindowsCPU和WindowsRAM属于一个产品族)
Apple产品包含AppleCPU和AppleRAM,(AppleCPU和AppleRAM属于一个产品族)
或者说是CPU包含Windows型和Apple型,RAM包含Windows型和Apple型。

下面说的可以结合后面的例子代码自己试一下,
试下增加一个新的LinuxCPU和LinuxRAM以及新增一个GPU产品是不是符合开闭原则。
①符合开闭原则情况

增加产品族:对于增加新的产品族,抽象工厂模式很好地支持了开闭原则,
只需要增加具体产品并对应增加一个新的具体工厂,对已有代码无须做任何修改。
如LinuxCPU和LinuxRAM,这种只需要新增一个工厂就行,属于扩展,不是修改,所以符合开闭原则情况。
②不符合开闭原则情况

增加新的产品等级结构:增加新的产品等级结构:对于增加新的产品等级结构 ,
需要修改所有的工厂角色,包括抽象工厂类,
在所有的工厂类中都需要增加生产新产品的方法,违背了开闭原则。
如新增一个GPU产品,这属于新增一个新的产品等级结构。

如果是工厂模式,则会创建四个工厂类,分别生产四个产品:WindowsCPU,AppleCPU,WindowsRAM,AppleRAM。

如果是抽象工厂模式,则只需要创建两个工厂类,将这四个产品两两组合(即一个工厂生产多种产品):
工厂1:WindowsCPU,WindowsRAM。工厂2:AppleCPU,AppleRAM
工厂1:WindowsCPU,AppleCPU。工厂2:WindowsRAM,AppleRAM
(上面是两种不同的分产品族的方法)

思路:

  1. 我选择创建两个接口CPU,RAM,分别创建WindowsCPU,WindowsRAM,AppleCPU,AppleRAM四个类来分别实现对应接口。
public interface CPU {
	public void CPURun();
}

public interface RAM {
	public void RAMRun();
}
public class WindowsCPU implements CPU{
	@Override
	public void CPURun() {
		System.out.println("windows cpu run!");
	}	
}
public class WindowsRAM implements RAM{
	public void RAMRun() {
		System.out.println("windows RAM run!");
	}
}
public class AppleCPU implements CPU{
	@Override
	public void CPURun() {
		System.out.println("apple CPU run!");
	}
}
public class AppleRAM implements RAM{
	@Override
	public void RAMRun() {
		System.out.println("apple RAM run!");
	}
}

3.接下来就是创建工厂类了,抽象工厂顾名思义就是抽象工厂类,所以先创建一个抽象接口再来创建两个工厂实现接口。

public interface interfaceFactory {//抽象工厂
	public CPU createCPU();
	public RAM createRAM();
}
public class WindowsFactory implements interfaceFactory{
	@Override
	public CPU createCPU() {
		return new WindowsCPU();
	}
	@Override
	public RAM createRAM() {
		return new WindowsRAM();
	}
}
public class AppleFactory implements interfaceFactory{
	@Override
	public CPU createCPU() {
		return new AppleCPU();
	}
	@Override
	public RAM createRAM() {
		return new AppleRAM();
	}
}

4.到Test类测试一下

public class Test {
	public static void main(String[] args) {
//		WindowsCPU  windowsCPU = new WindowsCPU();
//		windowsCPU.CPURun();

//		WindowsRAM windowsRAM = new WindowsRAM();
//		windowsRAM.RAMRun();

//		AppleCPU appleCPU = new AppleCPU();
//		appleCPU.CPURun();

//		AppleRAM appleRAM = new AppleRAM();
//		appleRAM.RAMRun();

		WindowsFactory  windowsFactory= new WindowsFactory();
		CPU windowsCPU = windowsFactory.createCPU();
		RAM windowsRAM = windowsFactory.createRAM();
		windowsCPU.CPURun();
		windowsRAM.RAMRun();
		
		AppleFactory appleFactory = new AppleFactory();
		CPU appleCPU = new AppleFactory().createCPU();
		RAM appleRAM = new AppleFactory().createRAM();
		appleCPU.CPURun();
		appleRAM.RAMRun();
	}
}

这只是其中一种方式,还可以创建Windows,Apple抽象类,创建CPU工厂和RAM工厂,CPU工厂生产Windows型和Apple型,RAM工厂同理。方式不唯一。

总结:工厂模式乃是一一对应的关系,一个工厂生产一种产品;抽象工厂模式乃是一个工厂生产多种产品。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值