一.场景
简单工厂和工厂方法的场景:
编一个律师工资为场景。
1.律师有实习律师、正式律师、律师主任三种类型
2.实习律师的工资为基本工资1000+所办案件收入的10%+出勤数*100;
正式律师的工资为基本工资2000+所办案件收入的20%+出勤数*200
主任的工资为基本工资3000+所办案件收入的30%+出勤数*300
修改场景:
不同类型律师除了进行工资计算,每种类型律师还有案件数量计算、年终奖计算
二。实现
https://blog.csdn.net/u014203449/article/details/83098517
1.抽象工厂
在工厂方法的基础上,加案件数量计算的接口,各种律师案件数量计算的实现类
public interface CaseCalculation {
public Integer getCaseNumber();
}
public class DirectorCase implements CaseCalculation {
@Override
public Integer getCaseNumber() {
return null;
}
}
public class InternshipCase implements CaseCalculation {
@Override
public Integer getCaseNumber() {
return null;
}
}
public class LawyerCase implements CaseCalculation{
@Override
public Integer getCaseNumber() {
// TODO Auto-generated method stub
return null;
}
}
在各种律师类型的工厂加上创建计算案件数量实例的方法
public interface Factory {
//计算工资
public SalaryCalculation getSalaryCalculation();
//计算案件数量
public CaseCalculation getCaseCalculation();
}
public class LawyerFactory implements Factory{
@Override
public SalaryCalculation getSalaryCalculation() {
return new LawyerSalayr();
}
@Override
public CaseCalculation getCaseCalculation() {
// TODO Auto-generated method stub
return new LawyerCase();
}
}
public class InternshipFactory implements Factory{
@Override
public SalaryCalculation getSalaryCalculation() {
return new InternshipSalary();
}
@Override
public CaseCalculation getCaseCalculation() {
// TODO Auto-generated method stub
return new InternshipCase();
}
}
public class DirectorFactory implements Factory{
@Override
public SalaryCalculation getSalaryCalculation() {
// TODO Auto-generated method stub
return new DirectorSalary();
}
@Override
public CaseCalculation getCaseCalculation() {
// TODO Auto-generated method stub
return new DirectorCase();
}
}
客户端计算案件数量
public static void main(String[] args) {
Factory factory = new LawyerFactory();
CaseCalculation calculation = factory.getCaseCalculation();
calculation.getCaseNumber();
}
1.当不同的律师类型只进行各自工资计算时,用到的是工厂方法模式,但当不同类型律师还都要计算其他事,就相当于不同的产品线上有很多零件。三种律师类型就是三条产品线,计算工资和计算案件数量就是产品上的零件功能,不同类型的产品都具有这些功能而实现又不同
2.CaseCalculation和SalaryCalculation是两个抽象产品,之所以是抽象,是因为他们有不同的实现,DirectorCase、LawyerCase,LawyerSalayr、DirectorSalary是他们的实现。
而Factory是抽象工厂,里面的方法包括创建所有产品的方法。LawyerFactory、DirectorFactory就是具体工厂,创建具体的产品对象.
3.在运行的时候,创建具体的工厂实例,得到产品对象
4.抽象工厂优点:易于交换产品系列,要用都用一种产品线
缺点:增加一种产品需要改动很多地方。客户端程序不只有一个,凡是有客户端的地方都要先创建具体的产品工程,麻烦,一旦修改产品线,就都得修改
2.用简单工厂改造抽象工厂
用一个DataAccess类 代替客户端的选择工厂
public class DataAccess {
private static String lawyerType="Director";
//private static String lawyerType="Internship";
//private static String lawyerType="lawyer";
public static CaseCalculation getCaseCalculation() {
CaseCalculation ca=null;
switch (lawyerType) {
case "Director":
ca = new DirectorCase();
break;
case "Internship":
ca = new InternshipCase();
break;
case "lawyer":
ca = new LawyerCase();
break;
}
return ca;
}
public static SalaryCalculation getSalaryCalcution() {
SalaryCalculation sa = null;
switch (lawyerType) {
case "Director":
sa = new DirectorSalary();
break;
case "Internship":
sa = new InternshipSalary();
break;
case "lawyer":
sa = new LawyerSalayr();
break;
}
return sa;
}
}
客户端:
public static void main(String[] args) {
CaseCalculation calculation = DataAccess.getCaseCalculation();
calculation.getCaseNumber();
}
优点:避免了客户端繁杂的创建工厂实例
缺点:又回到了简单工厂 的问题,改动switch
3.用反射+抽象工厂改造简单工厂
之前在策略模式中,使用过反射 根据不同的类所在地址,创建不同的算法封装对象,从而进行计算。但策略模式中只创建一种接口的实例。 我们现在用工资计算和案件计算多个接口。
现在用反射,根据不同工厂类所在的地址,不同律师类型的工厂实例。然后律师工厂就可以得到对应类型的案件和工资对象了
改造DataAccess
public class DataAccess {
//主任工厂的类名
private static String lawyerType="DirectorFactory";
//主任工厂所在的包路径
private static String packageName="AbstractFactory";
public static CaseCalculation getCaseCalculation() {
Factory factory = null;
try {
factory = (Factory)Class.forName(packageName+"."+lawyerType).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return factory.getCaseCalculation();
}
}
客户端:
public static void main(String[] args) {
CaseCalculation calculation = DataAccess.getCaseCalculation();
calculation.getCaseNumber();
}
三。总结
1.多条产品线,每种产品又有很多功能,功能的接口是一样的,用抽象工厂。由工厂方法进化来的
2.抽象工厂客户端频繁 创建工厂实例,用简单工厂简化抽象工厂
3.反射加抽象工厂