抽象类和接口 应用场景

来源:互联网 发布:知乎 漂亮的av 编辑:程序博客网 时间:2024/05/23 19:15

很多童鞋经常背诵抽象类和接口的区别,使用场景,但并没有深入了解什么时候使用他们,或者使用哪个更好,本文举一小例,并不一定完全正确,欢迎读者吐槽;


我们看一个银行借款的领子,中国人民银行管理并监督所有的银行,它制定了一个规范,所有的银行在进行借款时都必须遵守这个规范(基本接口);

Version~0.1.0:

中国人民银行定义了一个操作接口:

package GoodDesignPattern;import java.util.Map;public interface BankLoan {/** * 银行借款操作 * 每个公司都需要实现该方法,并针对自己公司员工的情况进行特殊操作, * 比如判断该员工是否有资格,能借款多少等等 * @return */public Map<String, String>  loanOperation(String userId);}

所有的银行都必须遵守这个接口,进行具体的实现:

package GoodDesignPattern;import java.util.HashMap;import java.util.Map;public class ABC implements BankLoan {@Overridepublic Map<String, String> loanOperation(String userId) {//所有银行借款必须的校验if(userId==null || userId.isEmpty()){System.out.println("userId为空!");return null;}//所有银行借款必须的校验if(userId.length()!=32){System.out.println("userId格式错误,应该为32位!"+userId);return null;}//所有银行借款必须的校验if(!queryUserExist(userId)){System.out.println("用户不存在:"+userId);return null;}//所有银行借款必须的校验if(!queryUserIllegal(userId)){System.out.println("用户没有资格进行借款:"+userId);return null;}//业务逻辑Map<String, String> map = getResultMap(userId);return map;}//根据数据库查询是否存在,根据自己公司的用户表查询public boolean queryUserExist(String userId){return true; //return false;}//根据数据库查询数据查询判断public boolean queryUserIllegal(String userId){return true; //return false;}//根据数据库查询相关信息public Map<String, String> getResultMap(String userId){Map<String, String> map = new HashMap<String, String>();map.put("name", "詹姆斯"); //此处为了方便直接写死map.put("amount", "100000"); //应根据userId,在系统进行一系列判断计算,得出能借款金额,此处为了方便直接写死map.put("rankLevel", "A"); //应根据userId,在系统进行一系列判断计算,得出用户等级,此处为了方便直接写死//.....其它一些列操作return map;}}

package GoodDesignPattern;import java.util.HashMap;import java.util.Map;public class ICBC implements BankLoan {@Overridepublic Map<String, String> loanOperation(String userId) {//所有银行借款必须的校验if(userId==null || userId.isEmpty()){System.out.println("userId为空!");return null;}//所有银行借款必须的校验if(userId.length()!=32){System.out.println("userId格式错误,应该为32位!"+userId);return null;}//所有银行借款必须的校验if(!queryUserExist(userId)){System.out.println("用户不存在:"+userId);return null;}//所有银行借款必须的校验if(!queryUserIllegal(userId)){System.out.println("用户没有资格进行借款:"+userId);return null;}//业务逻辑Map<String, String> map = getResultMap(userId);return map;}//根据数据库查询是否存在,根据自己公司的用户表查询public boolean queryUserExist(String userId){return true; //return false;}//根据数据库查询数据查询判断public boolean queryUserIllegal(String userId){return true; //return false;}//根据数据库查询相关信息public Map<String, String> getResultMap(String userId){Map<String, String> map = new HashMap<String, String>();map.put("amount", "100000"); //应根据userId,在系统进行一系列判断计算,得出能借款金额,此处为了方便直接写死map.put("rankLevel", "A"); //应根据userId,在系统进行一系列判断计算,得出用户等级,此处为了方便直接写死//.....其它一些列操作return map;}}
我们发现,每当一家银行做此操作时,都会做一些校验,并且他们都是类似的,这不仅繁琐,而且有些银行容易遗漏一些校验操作;虽然校验的逻辑大同小异,但是每个银行都可能自己定义自己的方法名、判断自己的业务逻辑,这样的开发低效且中国人民银行不方便管理,为此,人行需要调整自己的规范,统一各个银行的行为;

Version~0.2.0:

中国人民银行修改自己的规范:

之前的接口不变,新增一个抽象类:

package GoodDesignPattern;import java.util.Map;public abstract class CommonOpretion {public Map<String, String> loanOperation(String userId) {//所有银行借款必须的校验if(userId==null || userId.isEmpty()){System.out.println("userId为空!");return null;}//所有银行借款必须的校验if(userId.length()!=32){System.out.println("userId格式错误,应该为32位!"+userId);return null;}//所有银行借款必须的校验if(!queryUserExist(userId)){System.out.println("用户不存在:"+userId);return null;}//所有银行借款必须的校验if(!queryUserIllegal(userId)){System.out.println("用户没有资格进行借款:"+userId);return null;}//业务逻辑Map<String, String> map = getResultMap(userId);return map;}//根据数据库查询是否存在,根据自己公司的用户表查询protected abstract boolean queryUserExist(String userId);//根据数据库查询数据查询判断protected abstract boolean queryUserIllegal(String userId);//根据数据库查询相关信息protected abstract Map<String, String> getResultMap(String userId);}
看看这个抽象类的逻辑,你可以看出来,把所有的公共逻辑都写在里面,具体的业务操作方法是抽象的,由具体的银行去实现即可,看下银行的实现:

package GoodDesignPattern;import java.util.HashMap;import java.util.Map;public class ABC extends CommonOpretion implements BankLoan {//根据数据库查询是否存在,根据自己公司的用户表查询@Overridepublic boolean queryUserExist(String userId){return true; //return false;}//根据数据库查询数据查询判断@Overridepublic boolean queryUserIllegal(String userId){return true; //return false;}//根据数据库查询相关信息@Overridepublic Map<String, String> getResultMap(String userId){Map<String, String> map = new HashMap<String, String>();map.put("name", "詹姆斯"); //此处为了方便直接写死map.put("amount", "100000"); //应根据userId,在系统进行一系列判断计算,得出能借款金额,此处为了方便直接写死map.put("rankLevel", "A"); //应根据userId,在系统进行一系列判断计算,得出用户等级,此处为了方便直接写死//.....其它一些列操作return map;}}

package GoodDesignPattern;import java.util.HashMap;import java.util.Map;public class ICBC extends CommonOpretion implements BankLoan {//根据数据库查询是否存在,根据自己公司的用户表查询@Overridepublic boolean queryUserExist(String userId){return true; //return false;}//根据数据库查询数据查询判断@Overridepublic boolean queryUserIllegal(String userId){return true; //return false;}//根据数据库查询相关信息@Overridepublic Map<String, String> getResultMap(String userId){Map<String, String> map = new HashMap<String, String>();map.put("amount", "100000"); //应根据userId,在系统进行一系列判断计算,得出能借款金额,此处为了方便直接写死map.put("rankLevel", "A"); //应根据userId,在系统进行一系列判断计算,得出用户等级,此处为了方便直接写死//.....其它一些列操作return map;}}
每个银行只要继承这个抽象类,并实现对应的业务逻辑方法即可,一些校验都统一放入抽象类中判断,这样,每个银行的实现逻辑清晰、规范、不会遗漏校验,当然如果抽象类中的某些抽象方法,有些银行不想做具体实现,可以默认返回,当然这是一个缺陷,欢迎读者提出更好的解决方案。

这个时候每个银行又要实现抽象类,又要实现接口,他们感觉很麻烦且没有必要,这个时候中国银行又进行调整:

Version~0.3.0:
顶层接口还是不变,抽象类修改:由抽象类实现接口

package GoodDesignPattern;import java.util.Map;public abstract class CommonOpretion  implements BankLoan{@Overridepublic Map<String, String> loanOperation(String userId) {//所有银行借款必须的校验if(userId==null || userId.isEmpty()){System.out.println("userId为空!");return null;}//所有银行借款必须的校验if(userId.length()!=32){System.out.println("userId格式错误,应该为32位!"+userId);return null;}//所有银行借款必须的校验if(!queryUserExist(userId)){System.out.println("用户不存在:"+userId);return null;}//所有银行借款必须的校验if(!queryUserIllegal(userId)){System.out.println("用户没有资格进行借款:"+userId);return null;}//业务逻辑Map<String, String> map = getResultMap(userId);return map;}//根据数据库查询是否存在,根据自己公司的用户表查询protected abstract boolean queryUserExist(String userId);//根据数据库查询数据查询判断protected abstract boolean queryUserIllegal(String userId);//根据数据库查询相关信息protected abstract Map<String, String> getResultMap(String userId);}
具体银行不再需要实现接口:

package GoodDesignPattern;import java.util.HashMap;import java.util.Map;public class ABC extends CommonOpretion {//根据数据库查询是否存在,根据自己公司的用户表查询@Overridepublic boolean queryUserExist(String userId){return true; //return false;}//根据数据库查询数据查询判断@Overridepublic boolean queryUserIllegal(String userId){return true; //return false;}//根据数据库查询相关信息@Overridepublic Map<String, String> getResultMap(String userId){Map<String, String> map = new HashMap<String, String>();map.put("name", "詹姆斯"); //此处为了方便直接写死map.put("amount", "100000"); //应根据userId,在系统进行一系列判断计算,得出能借款金额,此处为了方便直接写死map.put("rankLevel", "A"); //应根据userId,在系统进行一系列判断计算,得出用户等级,此处为了方便直接写死//.....其它一些列操作return map;}}
到此一个体现接口和抽象类结合使用的简单例子就说完了,谢谢~



原创粉丝点击