面向接口编程和解耦

面向接口编程和解耦

什么是面向接口编程??
面向接口编程:同时也是面向抽象编程,此类思想要明确的分清编译期和运行期在面向接口编程中的区别。为原本昂长的代码声明一个接口,使其成为接口的实现类。之后直接调用接口,即可使用实现类中的相关方法。

简单的来说,就是A类调用B类中的方法时,不直接调用B类中的方法,而是编写一个接口,让B类实现此接口,而A类调用接口中的方法;
听起来好像多次一举,但是并不是,我们简单介绍一下此类做法的优点:
此类做法为面向接口编程,好处
1.降低代码耦合性,代码要遵循高内聚,低耦合,低耦合表示的就是不同类的代码之间尽量不能相互影响,不能让彼此的依赖性过强,否则会对后期的维护开发造成不必要的麻烦,前人栽树后人乘凉,降低耦合从我做起,方便他人也方便自己。
2.提升协同开发效率,如果多人分工写不同层的代码,就可以先编写一个接口,双方按照接口的规范来编写,可以提升开发效率,也可以降低出bug的概率。
3.有利于程序应用的扩展,如果我们不使用面向接口编程,那么后期我们在添加功能时就要修改程序源代码各种调用,麻烦的很,也不好修改,但是如果面向接口,那么在添加功能时就可以在接口中添加一个新的方法,让实现类重写,在让测试类调用接口就可以了。

在这里插入图片描述
结构
接口放在工程的service包中
实现类放在工程的service.Impl包中

此时我们在Servlet中对接口进行调用:
private UserService userService = new UserServiceImpl();
我们发现,我们并没有完全摆脱Service类,因此此时虽然可以使用,但严格来讲并不是面向接口编程,因此我们需要

解耦!

需要让代码完全只依赖于接口,因此需要解耦
解耦是啥?
解耦:编译期降低与实现类的依赖,在Spring中也会使用到
实现了解耦技术之后,就可以完全摆脱两个类之间的直接连接。
为了方便,我们需要使用工厂设计模式,运用反射技术,调用到类中的方法
这是我们的第一想法
在这里插入图片描述可是我们发现,这种方式只能对一个接口发挥作用,每次有了新Servlet,又要对工厂进行修改,所以我们应当使用xml配置文件来解决这个问题,来完成面向接口编程的最终版本!
使用beans.xml文件对配置进行存储

<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="userServic" class="xxx.xxxx.xxx.service.impl.UserServiceImpl"/>
</beans>

其中,bean就是一个接口实现类的配置,id为名,class为值
以下是我们要实现的流程:
在这里插入图片描述
此时,即使是来了另一个Servlet调用其他接口,也不会出问题了,只要在beans.xml中配置好就可以。
贴一下代码:
Servlet

private UserServic userServic=BeanFactory.getBean("userServic",UserServic.class);

BeanFactory:

//接口工厂设计
/*
	我们一次性把xml文件中所有配置信息都取出,放在Map容器中
	每次调用传进来Key,我们就能对应的找寻到Value,然后返回
*/
//编写一个Map当作容器,
private static Map<String,Object> map=new HashMap<String,Object>();
static{
try{
//使用dom4j读取xml文件
InputStreamin=BeanFactory.class.getClassLoader().getResourceAsStream("com/beans.xml");//获取文件
SAXReader saxReader=new SAXReader();//声明一个SAX对象
Document document=saxReader.read(in);//传入文件地址
//使用xpath遍历
List<Node>list=document.selectNodes("/beans/bean");//传入文件名,获取所有的Node,存储为一个集合
//每一个xml文件中的bean,都是一个Node
for(Nodenode:list){
//遍历并存入Map容器
String s=node.valueOf("@id");
String s1=node.valueOf("@class");
//使用反射技术,反射出对应的接口对象
Object o=Class.forName(s1).newInstance();
map.put(s,o);
}
}catch(Exceptione){
e.printStackTrace();
}
}
//使用时调用此方法,先传入beans.xml中的id,再传入接口.class,会返回接口对象
public static <T> T getBean(String name,Class<T> clazz){
return(T)map.get(name);
}

简化版:

private static Map<String,Object>map=new HashMap<String,Object>();
static{
try{
//使用dom4j读取
SAXReader saxReader=new SAXReader();
Document document=saxReader.read(BeanFactory.class.getClassLoader().getResourceAsStream("com/beans.xml"));
//使用xpath遍历
List<Node> list=document.selectNodes("/beans/bean");
for(Nodenode:list){
map.put(node.valueOf("@id"),Class.forName(node.valueOf("@class")).newInstance());
}
}catch(Exceptione){
e.printStackTrace();
}
}
public static <T> T getBean(String name,Class<T> clazz){
return(T)map.get(name);
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值