设计模式之访问者模式代码示例

问题:根据电表显示的用电量计算用户的电费,注意:电表用不同的电表,电费有不同的计算方法

解析:运用访问者模式。访问这模式结构:1、抽象访问者(一般用接口来实现);2、具体访问者(实现接口的类);3、抽象元素(一般用抽象类实现);4、具体元素(继承抽象类的类)。在本问题中,电表用抽象类抽象出来,计费方法看成是计表员接口,而用不同的计费方法来实现这个计表员访问者接口。


package face;//访问者模式:核心是双重分派
interface Visitor{ //抽象访问者,一般用接口来实现
	public double visit(AmmeterElement element);
}
abstract class AmmeterElement{  //抽象元素,一般用抽象类来实现
	public abstract void accept(Visitor visitor);
	public abstract double showElectricAmount();
	public abstract void setElectricAmount(double n);
}

/*具体访问者,实现Visitor接口的类,本问题有两个具体访问者,分别是HomeAmmerterVisitor类(模拟负责家用电计费的计表员)
和IndustryAmmeteVisitor类(模拟负责工业用电计费的计表员)*/
class HomeAmmerterVisitor implements Visitor{           //家用电计费的计表员

	@Override
	public double visit(AmmeterElement element) {
		double charge = 0;
		double unitOne = 0.6,unitTwo = 1.05;
		int basic = 6000;
		double n = element.showElectricAmount();
		if( n <= basic){
			charge = n*unitOne;
		}else{
			charge = basic*unitOne + (n-basic)*unitTwo;
		}
		return charge;
	}
	
}

class IndustryAmmeteVisitor implements Visitor{     //工业用电计费的计表员

	@Override
	public double visit(AmmeterElement element) {
		double charge = 0;
		double unitOne = 1.25,unitTwo = 2.78;
		int basic = 15000;
		double n = element.showElectricAmount();
		if( n <= basic){
			charge = n*unitOne;
		}else{
			charge = basic*unitOne + (n-basic)*unitTwo;
		}
		return charge;
	}
	
}

class Ammeter extends AmmeterElement{  //具体被访问者访问的具体元素
    double electricAmount;
	@Override
	public void accept(Visitor visitor) {
		double feiyong = visitor.visit(this); //让访问者访问当前元素
		System.out.println("当前电表的用户需要交纳的电费:"+feiyong+"元");
		
	}

	@Override
	public double showElectricAmount() {
		return electricAmount;
	}

	@Override
	public void setElectricAmount(double n) {
		electricAmount = n;
		
	}
	
}

public class Demo05 {

	public static void main(String[] args) {
		
		AmmeterElement 电表 = new Ammeter(); //向上转型,把一个AmmeterElement类用其子类来实例化(方便具体元素的扩展)
		电表.setElectricAmount(5678);
		
		Visitor 计表员 = new HomeAmmerterVisitor(); //按照家用电标准计费的“计表员”
		电表.accept(计表员);
		
		 计表员 = new IndustryAmmeteVisitor(); //按照工业用电标准计费的“计表员”
		电表.accept(计表员);

	}

}

核心技术:双重分派,在访问者模式中,被访者(即抽象类的元素角色)首先调用accept方法接收访问者,被接收的访问者再调用visit(Element element)访问当前对象


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值