工厂方法模式(Factory Method)从最初代码到一步步改进

解决的问题:
●  将“类实例化的操作”与“适用对象的操作”分开,让使用者不用知道具体参数就可以实例化出所需要的“产品”类,从而避免了在客户端代码中显式指定,实现了解耦。
●  即使用者可直接消费产品而不需要知道其生产的细节。

简单工厂模式:定义一个创建对象的类,由这个类来封装实例化对象的行为(代码)。
在这里插入图片描述
工厂类角色Creator:工厂类在客户端的直接控制下(Create方法)创建产品对象。
抽象产品拥有角色Product:定义简单工厂创建的对象的父类或它们共同拥有的接口。可以是一个类、抽象类或接口。
具体产品角色ConcreteProduct:定义工厂具体加工出的对象。

首先是一部分最简单的加减乘除的代码
继承思想的编程

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner=new Scanner(System.in);
		System.out.println("请输入数字A:");
		String strNumberA=scanner.nextLine();
		System.out.println("请选择运算符号(+、-、*、/)");
		String strOperator=scanner.nextLine();
		System.out.println("请输入数字B:");
		String strNumberB=scanner.nextLine();
		Operation oper;
		oper=OperationFacotry.createOperate(strOperator.charAt(0));
		oper.setNumberA(Double.parseDouble(strNumberA));
		oper.setNumberB(Double.parseDouble(strNumberB));
		System.out.println("结果是:"+oper.getRseult());
	}

}
abstract class Operation{
	//两个Number属性,主要用于计算器的前后数
	private double numberA=0;
	private double numberB=0;
	boolean flag=true;
	public double getNumberA() {
		return numberA;
	}
	public void setNumberA(double numberA) {
		this.numberA = numberA;
	}
	public double getNumberB() {
		return numberB;
	}
	public void setNumberB(double numberB) {
		this.numberB = numberB;
	}
	//虚方法GetResult(),用于得到结果
	public abstract double getRseult();
}
//加法类,继承运算类
class OperationAdd extends Operation{

	@Override
	public double getRseult() {
		// TODO Auto-generated method stub
		double result=0;
		return getNumberA()+getNumberB();
	}
	
}
//减法类,继承运算类
class OperationSub extends Operation{

	@Override
	public double getRseult() {
		// TODO Auto-generated method stub
		double result=0;
		return getNumberA()-getNumberB();
	}
	
}
//乘法类,继承运算类
class OperationMul extends Operation{

	@Override
	public double getRseult() {
		// TODO Auto-generated method stub
		double result=0;
		return getNumberA()*getNumberB();
	}
	
}
//除法类,继承运算类
class OperationDiv extends Operation{

	@Override
	public double getRseult() {
		// TODO Auto-generated method stub
		double result=0;
		return getNumberA()/getNumberB();
	}
	
}
//简单工厂类
class OperationFacotry{
	public static Operation createOperate(char operate) {
		Operation oper=null;
		switch(operate) {
		case'+':oper=new OperationAdd();break;
		case'-':oper=new OperationSub();break;
		case'*':oper=new OperationMul();break;
		case'/':oper=new OperationDiv();break;
		}
		return oper;
	}
}

       加减乘除都写成运算类Operation的子类,它们继承运算类后,重写getResult(方法,这栏如果要修改任何一算法,就不需要提供其他算法的代码了。
       有了简单工厂类如果我们像增加更加复杂的运算,只需要增加相应的运算子类和扩展工厂类就可以了。

//增加具体运算类OperationMN
//m的n次方类,继承运算类
class OperationMN extends Operation{

	@Override
	public double getRseult() {
		// TODO Auto-generated method stub
		double r=1;
		double m=getNumberA();
		int n=(int)getNumberB();
		for(int i=1;i<n;i++)
			r=r*m;
		return r;
	}
	
}

//简单运算工厂类
class OperationFactory{
	public static Operation createOperate(char operate){
		Operation oper = null;
		switch(operate){
			case'+':oper = new OperationAdd();break;
			case'-':oper = new OperationSub();break;
			case'*':oper = new OperationMul();break;
			case'/':oper = new OperationDiv();break;
		}
		return oper;
	}
}

       以上方法对扩展开放,但是也对修改开放,违背了封闭-开放原则
再次修改之后的代码:

package gongchang1;

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner=new Scanner(System.in);
		System.out.println("请输入数字A:");
		String strNumberA=scanner.nextLine();
		System.out.println("请选择运算符号(+、-、*、/):");
		String strOperator=scanner.nextLine();
		System.out.println("请输入数字B:");
		String strNumberB=scanner.nextLine();
		IFactory operFactory=null;
		switch(strOperator.charAt(0)) {
		case'+':operFactory=new AddFactory();break;
		case'-':operFactory=new SubFactory();break;
		case'*':operFactory=new MulFactory();break;
		case'/':operFactory=new DivFactory();break;
		}
		Operation oper=operFactory.createOperation();
		oper.setNumberA(Double.parseDouble(strNumberA));
		oper.setNumberB(Double.parseDouble(strNumberB));
		try {
			double result=oper.getRseult();
			System.out.println("结果是:"+result);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}

}
abstract class Operation{
	//两个Number属性,主要用于计算器的前后数
	private double numberA=0;
	private double numberB=0;
	boolean flag=true;
	public double getNumberA() {
		return numberA;
	}
	public void setNumberA(double numberA) {
		this.numberA = numberA;
	}
	public double getNumberB() {
		return numberB;
	}
	public void setNumberB(double numberB) {
		this.numberB = numberB;
	}
	//虚方法GetResult(),用于得到结果
	public abstract double getRseult();
}
//加法类,继承运算类
class OperationAdd extends Operation{

	@Override
	public double getRseult() {
		// TODO Auto-generated method stub
		double result=0;
		return getNumberA()+getNumberB();
	}
	
}
//减法类,继承运算类
class OperationSub extends Operation{

	@Override
	public double getRseult() {
		// TODO Auto-generated method stub
		double result=0;
		return getNumberA()-getNumberB();
	}
	
}
//乘法类,继承运算类
class OperationMul extends Operation{

	@Override
	public double getRseult() {
		// TODO Auto-generated method stub
		double result=0;
		return getNumberA()*getNumberB();
	}
	
}
//除法类,继承运算类
class OperationDiv extends Operation{

	@Override
	public double getRseult() {
		// TODO Auto-generated method stub
		double result=0;
		return getNumberA()/getNumberB();
	}
	
}
 interface IFactory{
	Operation createOperation();
}
class AddFactory implements IFactory{
	public Operation createOperation(){
		return new OperationAdd();
	}
}
class SubFactory implements IFactory{
	public Operation createOperation(){
		return new OperationSub();
	}
}
class MulFactory implements IFactory{
	public Operation createOperation(){
		return new OperationMul();
	}
}
class DivFactory implements IFactory{
	public Operation createOperation(){
		return new OperationDiv();
	}
}

优点:

● 更符合开-闭原则
新增一种产品时,只需要增加相应的吴体产品类和相应的工厂子类即可简单工厂模式霄要修改工厂类的判断逻辑
● 符合单一职责原则
每个具体工厂类只负责创建对应的产品简单工厂中的工厂类存在复杂的if分支逻辑判断不使用静态工厂方法,可以形成基于继承的等级构。简单工厂模式的工厂类使用静态工厂方法。
工厂方法模式是简单工厂模式的进一步抽象和拓展,在保留了简单工厂的封装优点的同时,让扩展变得简单,让继承变得可行,增加了多态性的体现。
缺点:

● 添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,系统类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,有更多的类霄要编译和运行,会给系统带来一些额外的开销;
● 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,增加了系统的实现难度;
虽然保证了工厂方法内的对修改关闭,但对于使用工厂方法的客户端,如果要增加一种产品,仍然霄要修改实例化的具体工厂类;
● 一个具体工厂只能创建一种具体产品。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值