23种设计模式——工厂方法模式

目录

回顾简单工厂模式

工厂方法模式

优缺点

工厂方法模式VS简单工厂模式

应用场景

实例

用工厂方法模式实现计算器

导出数据


回顾简单工厂模式

可以参考我的另一篇博客

在这里插入图片描述

工厂类角色LightSimpleFactory:在客户端的直接控制下创建产品对象。
抽象产品角色Light:定义简单工厂创建的对象的父类或它们的接口。可以是一个类、抽象类或接口
具体产品角色BulbLight, TubeLight:具体产品对象。


  • 优点:工厂类中有必要的逻辑判断,根据客户端的选择,动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖
  • 缺点:在某种程度上违背了开放–封闭原则。对工厂类过于依赖,一旦工厂类出现问题,所有程序都会出现问题

因此,推出了工厂方法模式

工厂方法模式

实质:延迟到子类来选择实现

目的:定义一个创建产品对象的工厂接口,将具体创建工作放到具体工厂子类中。

允许在不修改工厂角色的情况下引进新产品。

具体产品由具体工厂创建,往往一一对应

在这里插入图片描述


抽象工厂(Creator)角色:
核心,与应用程序无关。所有具体工厂类都要实现这个接口。

方法中指向抽象产品类

具体工厂(Concrete Creator)角色:
实现抽象工厂接口。包含与应用程序相关的逻辑,受应用程序调用来创建不同的产品对象。图中:BulbCreator与TubeCreator。

方法中指向具体产品类

抽象产品(Product)角色:
Light

具体产品(Concrete Product)角色:
BulbLight,TubeLight


示例代码:

(1)抽象产品角色:

public abstract class Light {
	public abstract void TurnOn();
	public abstract void TurnOff();

}

(2)具体产品角色:

public class BulbLight extends Light{

	@Override
	public void TurnOn() {
		System.out.println("电灯泡亮了");		
	}

	@Override
	public void TurnOff() {
		System.out.println("电灯泡灭了");	
	}
	
}
public class TubeLight extends Light{

	@Override
	public void TurnOn() {
		System.out.println("管道亮了");
		
	}

	@Override
	public void TurnOff() {
		System.out.println("管道暗了");	
	}

}

(3)抽象工厂角色:

public abstract class Creator {
    //指向具体产品类
	public abstract Light factory();
}

(4)具体工厂角色:

public class BulbCreator extends Creator{

	@Override
	public Light factory() {
		return new BulbLight();
	}

}
public class TubeCreator extends Creator{

	@Override
	public Light factory() {
		return new TubeLight();
	}

}

简单测试一下:

import java.util.Scanner;

public class Test {

	public static void main(String[] args) {
		System.out.println("请输入1 or 2");
		Scanner cin=new Scanner(System.in);
		int n=cin.nextInt();
		if(n==1) {
			Creator c1=new BulbCreator();
			Light l1=c1.factory();
			l1.TurnOn();
			l1.TurnOff();
		}else {
			Creator c2=new TubeCreator();
			Light l2=c2.factory();
			l2.TurnOn();
			l2.TurnOff();
		}
		cin.close();
		
	}

}

工厂方法模式很好的体现了“依赖倒置原则”, 依赖倒置原则告诉我们“要依赖抽象,不要依赖于具体类”,也就是:不能让高层组件依赖于低层组件,而且不管高层组件还是低层组件,都应该依赖于抽象。

  • 对于抽象工厂来说,它不关心具体的实现方式,它只是“面向接口编程”
  • 对于具体的实现来说,它只关心自己“如何实现接口”所要求的功能。

优缺点

克服了简单工厂模式一些缺点,保留了简单工厂模式的优点。

优点:

需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象。原有工厂对象不需要进行任何修改,也不需要修改客户端,较好的符合了“开放-封闭”原则。

而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。

缺点

具体产品对象与工厂方法的耦合性高。

工厂方法需要选择具体的产品对象,并创建他们的实例。因此具体产品对象与工厂方法是耦合的。

工厂方法模式VS简单工厂模式

二者在结构上大同小异。

但工厂方法类的核心是一个抽象工厂类,而简单工厂模式的核心是一个具体类。

工厂方法模式又叫多态性工厂模式,因为具体工厂类都有共同的接口,或者有共同的抽象父类。

应用场景

工厂方法模式:如果一个类需要创建某个类的对象,但是又不知道具体的实现,可以选用工厂方法模式,把创建对象的工作延迟到子类中实现。

简单工厂模式:一个类想要把对外创建对象的职责集中管理和控制

实例

用工厂方法模式实现计算器

public abstract class Operation {
	protected double numberA=0;
	protected double numberB=0;
	
	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;
	}
	
	public double getResult() {
		double result=0;
		return result;
	}

}
public class OperationAdd extends Operation{

	public double getResult() {
		double result=0;
		result=numberA+numberB;
		return result;
	}

}
public class OperationSub extends Operation{
	
	public double getResult() {
		double result=0;
		result=numberA-numberB;
		return result;
	}
}
public class OperationMul extends Operation{
	
	public double getResult() {
		double result=0;
		result=numberA*numberB;
		return result;
	}
}
public class OperationDiv extends Operation{
	
	public double getResult() {
		double result=0;
		if(numberB==0)
		result=numberA/numberB;
		return result;
	}
}
public interface OperationFactory {
	public abstract Operation createOperation() ;

}
public class AddFactory implements OperationFactory{
	
	@Override
	public Operation createOperation() {
		return new OperationAdd();
	}

}
public class SubFactory implements OperationFactory{

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

}
public class MulFactory implements OperationFactory{

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

}
public class DivFactory implements OperationFactory{

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

}
import java.util.Scanner;

public class Test {

	public static void main(String[] args) {
		System.out.println("请输入两个操作数,再输入一个运算符:");
		Scanner cin=new Scanner(System.in);
		int a=cin.nextInt();
		int b=cin.nextInt();
		String s=cin.next();
		//此处只检验加减
		if(s.equals("+")) {
			OperationFactory of1=new AddFactory();
			Operation o1=of1.createOperation();
			o1.setNumberA(a);
			o1.setNumberB(b);
			System.out.println(o1.getResult());
		}else {
			OperationFactory of2=new SubFactory();
			Operation o2=of2.createOperation();
			o2.setNumberA(a);
			o2.setNumberB(b);
			System.out.println(o2.getResult());
		}
		cin.close();

	}

}

导出数据

各分公司内运行系统独立,每天业务结束时,各分公司导出业务数据、打包、传送给总公司。

导出数据格式会有不同要求:文本格式、数据库备份格式、Excel格式、Xml格式

分清哪是产品类、哪是工厂类

产品类:

public abstract class Export {
	public abstract void export(String data);

}
public class ExportDB extends Export{

	@Override
	public void export(String data) {
		System.out.println("以DB方式导出业务数据"+data);
		
	}

}

public class ExportExcel extends Export{

	@Override
	public void export(String data) {
		System.out.println("以excel导出业务数据"+data);
		
	}
	
}

public class ExportText extends Export{

	@Override
	public void export(String data) {
		System.out.println("以文本导出业务数据"+data);
		
	}
	
}

public class ExportXml extends Export{

	@Override
	public void export(String data) {
		System.out.println("以xml方式导出业务数据"+data);
		
	}

}

工厂类: 

public interface FrimFactory {	
	public Export exportFile();

}
public class TextFactory implements FrimFactory{

	@Override
	public Export exportFile() {
		// TODO Auto-generated method stub
		return new ExportText();
	}

}

public class ExcelFactory implements FrimFactory{
	@Override
	public Export exportFile() {
		// TODO Auto-generated method stub
		return new ExportExcel();
	}
	
}

public class DBFactory implements FrimFactory{
	
	public ExportDB exportFile() {
		return new ExportDB();
	}

}

public class XmlFactory implements FrimFactory{
	@Override
	public Export exportFile() {
		// TODO Auto-generated method stub
		return new ExportXml();
	}

}
public class Test {

	public static void main(String[] args) {
		FrimFactory f1=new DBFactory();
		Export e1=f1.exportFile();
		e1.export("data1");
		
		FrimFactory f2=new TextFactory();
		Export e2=f2.exportFile();
		e2.export("data2");

	}

}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值