继承和组合的联系(策略模式--组装车间):计算不同身份员工工资案例

公司有三类人员,新入职人员,中层人员和领导,三种身份的工资计算是不同的,先看一下简单的结构图。。。

在这里插入图片描述

用继承来实现的话:

abstract class Employee{
	int id;
	double salary;
	public abstract void setCalcSalary(int id,double salary);
	public double CalculatSalary() {
		// TODO Auto-generated method stub
		System.out.println(id);
		return salary;
	}
}
class JuniorEmployee extends Employee{
	
	@Override
	public void setCalcSalary(int id,double salary) {
		// TODO Auto-generated method stub
		this.id=id;
		this.salary=salary;
	}

	
	
}

class SeniorEmployee extends Employee{

	@Override
	public void setCalcSalary(int id, double salary) {
		// TODO Auto-generated method stub
		this.id=id;
		this.salary=salary+500;
	}


	
}
class ManagerEmployee extends Employee{

	@Override
	public void setCalcSalary(int id, double salary) {
		// TODO Auto-generated method stub
		this.id=id;
		this.salary=salary+1000;
	}

	
	
}
public class Test4 {
	public static void main(String[] args) {
		JuniorEmployee j=new JuniorEmployee();//id=1的员工入职了
		j.setCalcSalary(1, 3000);
		System.out.println(j.CalculatSalary());
		SeniorEmployee s=new SeniorEmployee();//id=1的员工晋升了
		s.setCalcSalary(1, 5000);
		System.out.println(s.CalculatSalary());
		ManagerEmployee m=new ManagerEmployee();//id=1的员工晋升了
		m.setCalcSalary(1, 8000);
		System.out.println(m.CalculatSalary());
	}
}

上面的继承代码你会发现,虽然是一个员工,但是创建了3个对象,还必须要保证三个id必须相同。先不说这样妥不妥,单单对象创建就消耗了不必要的资源。用组合的方法更简便:

interface ICalculateSalary {
	double calculateSalary(double baseSalary);
}
class JuniorEmployee implements ICalculateSalary{
	public double calculateSalary(double baseSalary) {
		return baseSalary;
	}
}
class SeniorEmployee implements ICalculateSalary{
	public double calculateSalary(double baseSalary) {
		return baseSalary+500;
	}
}
class ManagerEmployee implements ICalculateSalary{
	public double calculateSalary(double baseSalary) {
		return baseSalary+1000;
	}
}
class Employee{
	int id;
	double baseSalary;
	ICalculateSalary employee;
	Employee(int id){
		this.id=id;
	}
	void setCalcSalary(ICalculateSalary employee,double baseSalary) {
		this.employee=employee;
		this.id=id;
		System.out.println(id+":"+employee.calculateSalary(baseSalary));
	}
	
}
public class Test4 {
	public static void main(String[] args) {
		Employee e=new Employee(1);
		e.setCalcSalary(new JuniorEmployee(),3000);
		e.setCalcSalary(new SeniorEmployee(),5000);
		e.setCalcSalary(new ManagerEmployee(), 6000);
	}
}


在组合模式下,只创建了一个对象,把晋升的身份当成参数传入了,而且可以动态在不同的策略下切换身份,非常灵活,这就是组合。

细心的读者可能会疑问,继承需要一个父类3个子类,组合需要一个接口3个子类,加1个雇员类,反而复杂了,没必要。

下面我们归纳一下继承和组合的优缺点:
继承是is a关系,可以翻译成 我是一个xxx。
组合是has a关系,可以翻译成 我有一个xxx。
就单单看字面意思,我有比我是强多了。(举个例子,A说我是一个妹子,B说我有一个妹子。。。。那A就只能是个妹子,B的话有一个妹子可能还有其他妹子。)

继承的优点:
子类可以重写父类的方法来实现对父类的扩展。
继承的缺点:
1.父类的内部细节子类可见
2.子类从父类继承的方法在编译时就确定下来了,无法再运行期间改变父类的方法。
3.如果对父类做了修改的话,必须对子类的方法做出相应的修改,所以这里就体现了高耦合(你会发现你的工作成了ctrl+c和ctrl+v。这样会浪费你大部分工作时间,很繁琐)

组合的优点:
1.当前对象(Employee)只能通过所包含的那个对象(ICalculateSalary的实例)去调用其方法,所包含的对象内部细节对当前对象是不可见的。
2.当前对象(Employee)与包含的对象(ICalculateSalary的实例)是一个低耦合关系,如果修改包含的类中的代码不需要修改当前对象的代码。
3.当前对象(Employee)在运行时动态绑定所包含的对象(多态),可以通过set方法对包含对象赋值(这个例子我用一个成员变量赋值了)
组合的缺点:
1.容易产生过多对象(这里我不理解)
2.为了能组合多个对象,必须仔细对接口进行定义。

组合是实现策略模式的关键,但策略模式照样需要继承的支持,但主题架构依然是组合,继承是发生在分叉中的故事。

猜你喜欢

转载自blog.csdn.net/weixin_43299461/article/details/86509130
今日推荐