`
calmness
  • 浏览: 353244 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

关于接口暴露问题的解决思路

    博客分类:
  • Java
阅读更多
前一两天在讨论群里,我提出过一个关于接口暴露的问题与群友们进行讨论,后来无甚结果,所以把自己这一问题在这里提出来,希望和大家讨论讨论。

   该问题主要是关于对外接口暴露的问题(此接口并非指java中的interface,而是指用户编程时可使用的接口),例如有一个类的大部分方法是不应该暴露给用户的,然而事实上,因为设计问题,任何一个用户都可以创建该类的实例以至于使用它,虽然在实际当中,可能没有用户会去这样做,不过我认为如果能够尽量避免这种情况应该是最好的选择。但是又该如何避免呢?

   我想这种问题出现的主要原因体现在设计者在对象职责分配上想尽可能的达到分散职责让程序更容易进行维护,这种目的是非常正确的,不过在实现上可能没有注意到接口暴露的问题,导致出现了我所说的情况。在群中讨论的时候,并没有人认同我的看法,也许我是错的,也许我是对的,不过这无关紧要,重要的是能够通过交流发现问题促进进步。

举个简单的例子:

public class TestA{
 public void methodA(){
   TestB testB = new TestB();
   testB.methodB();
}
} 

public class TestB{
 public void methodB(){
……
}
} 


在上面这个例子中,TestA依赖于TestB,而TestB这个类的方法应该是用户不可见,且不能让用户使用的,如果按照上面的方法,用户就可以使用TestB这个类了。

   对于这一问题,我的解决办法是将职责分配到实现类的父类或者接口上,在实现类当中以protected为方法标识,这样做虽然不能完全避免,但是可以尽可能的让客户知道哪些是给他使用哪些是不该使用的。

public class TestA extends TestB{
 public void methodA(){
   methodB();
}
}
public class TestB{
 protected void methodB(){
……
}
}


根据上面这种方式,TestB的方法通过protected进行了隐藏,可以进一步的让用户得知他所拥有的权限,从而就可以很轻易的解决了接口暴露的问题,上面的例子只是为了表达明确,并没有过多的设计,在实际开发当中,TestB更多的是作为抽象类或者是接口的形式出现,这种做法一样达到了对象职责的区分,容易维护,同时也封装了不该外露的接口,而且也可以随时开发给用户使用。在这里我只讲了一个大概的思路,并没有详细讨论如何去做,还需大家一起来参与。

对于这一问题只是本人一家之谈,可能有很多我没有想过的问题,有不同意的朋友欢迎与我讨论。
分享到:
评论
9 楼 intolong 2007-04-25  
感觉接口通常有两种:

1. 客户接口,主要暴露给客户,供客户方便使用。

2. 实现接口,真正用于实现代码的地方,可供其实现者,客户接口实现者(用来组装)和高级用户使用。

客户接口通常要客户用最小的努力使用到尽可能常用的功能,它的实现一般会去assemble各种实现接口的实现类,所以它很象一个facade.

实现接口才是真正用来封装,复用的。通常实现接口的实现类都写的短小精悍,做最少的事情,把组装的工作留给别人(客户接口实现类)。
8 楼 daynight830 2007-04-24  
其实design patterns就是为了解决一系列的这些问题。客户端所有的调用都应该通过调用接口来完成,虽然new了不同的实现子类,但是子类的具体实现,客户端是无法看到的。所以楼主的大体思想是对的,我表示赞同。
7 楼 海妖的夜 2007-04-22  
或许可以使用private的默认构造方法.那么B类最好不要有默认构造函数要做的事情,或者把初始化挪到init方法里去,或者有参数的构造方法,让别人来调.如果说a也打算用有参数的构造方法的话,那狠一点都放到init里做初始化好了.
主要目的是告诉别人如果你new了我,那么我就报错,你就无法使用我,你要用我就必须换一种方法来创建我.
结合factory的话,应该就更加可行了.
另外我也觉得你如果这么new的话,有必要放到一个包里面.
另外提出我的一个方法:
权限都用包权限,然后要对外开发的东西就用一个代理类公布出去,要调就调代理类好了.去除a和b的耦合比较好.
6 楼 weiqingfei 2007-04-22  
calmness 写道


引用

既然TestB只对TestA开放,那么说明两个类的紧密性,那么把这两个类放到一个包里,让方法使用默认修饰,只在本包内使用就可以了。

使用默认修饰并不好,这样就迫使依赖该类方法的其他类必须与该类在同一个包内,导致包可能非常臃肿,这种方式是最不推荐的了


如果两个类有这样的特殊关系,没有理由不把他们放在同一个包里,如果这样包就出现了臃肿问题,那只能说明设计上有问题。
5 楼 歆渊 2007-04-20  
这是个有意义的问题, 像C++就有一个 friend 关键字, 用来给特殊关系的类之间开后门. 到了 Java 把这个给去掉了, 我觉得不是因为这个机制完全没有必要, 而是 friend 修饰这么单一级别的划分对实质性问题反而欲盖弥彰, 还不如不要. Java 里似乎是通过默认的 default/package 权限来解决这方面的问题, 同一个包里的类可以互相之间访问任何非private的成员.

不过OO再精练升华以后, 我相信下一代OO语言在这个方向上还是需要点作为的. 可能是在 "代码单元" 之间可以自定义角色, 比如Helper, Client之类的, 根据角色再进一步界定不同成员的访问权限/可见性.
4 楼 calmness 2007-04-20  
引用

从设计的角度来将,应该暴露只应该暴露的东西,但是楼主的例子还是有些问题,因为如果是classB完全只被classA使用,则完全可以将B作为A的内部类来使用,我们永远不要忘记优先使用聚合的原则。

毕竟继承让我们浪费了一次继承的机会。

实际上这里涉及到两个问题,类隐藏和方法隐藏。

关于类的隐藏可以设计成内部类,前提是只有一个类引用,也就是说该类是私有的。另外可以通过factory的作用达到隐藏具体类创建的作用。
当然如果调用者绕过Factory非要new XXImpl出来则也没有办法。

方法隐藏就是对于public方法的定义要小心,确认是否真正的需要public。

对于设计我觉得定义方法的公开级别比类更加普遍。

可能是我的表达有问题,我所指的情况是在TestB并不仅仅只给A使用的情况下,如果使用内部类隐藏则把整个类都隐藏了,不适合其他类使用,对于使用factory来进行隐藏,可是类仍然存在可被直接使用的问题,能尽量不提供公共的接口就应该避免,当然是在可行的情况下,而非是什么情况都使用继承或者接口实现来处理这一问题。

引用

例子好像有点不合适
classB要让classA用 就已经暴露接口了 。

我所谓的暴露接口是指避免让用户可以直接使用,而classA是必须依赖于B的,但是B则不能够提供给其他人使用

引用

既然TestB只对TestA开放,那么说明两个类的紧密性,那么把这两个类放到一个包里,让方法使用默认修饰,只在本包内使用就可以了。

使用默认修饰并不好,这样就迫使依赖该类方法的其他类必须与该类在同一个包内,导致包可能非常臃肿,这种方式是最不推荐的了
3 楼 weiqingfei 2007-04-20  
既然TestB只对TestA开放,那么说明两个类的紧密性,那么把这两个类放到一个包里,让方法使用默认修饰,只在本包内使用就可以了。
2 楼 xly_971223 2007-04-20  
例子好像有点不合适
classB要让classA用 就已经暴露接口了 。
1 楼 jamesby 2007-04-20  
从设计的角度来将,应该暴露只应该暴露的东西,但是楼主的例子还是有些问题,因为如果是classB完全只被classA使用,则完全可以将B作为A的内部类来使用,我们永远不要忘记优先使用聚合的原则。

毕竟继承让我们浪费了一次继承的机会。

实际上这里涉及到两个问题,类隐藏和方法隐藏。

关于类的隐藏可以设计成内部类,前提是只有一个类引用,也就是说该类是私有的。另外可以通过factory的作用达到隐藏具体类创建的作用。
当然如果调用者绕过Factory非要new XXImpl出来则也没有办法。

方法隐藏就是对于public方法的定义要小心,确认是否真正的需要public。

对于设计我觉得定义方法的公开级别比类更加普遍。

相关推荐

    基于USB接口的RS232转换器的设计.pdf

    因此,设计一种能够将USB接口转换为RS232接口的设备,对于解决上述问题具有重要意义。 #### USB与RS232接口特点对比 - **RS232接口**:电路简单,信号经差分处理后可靠性较高,适合远距离数据传输,被大量智能...

    Java设计模式 编程思路

    Java设计模式是软件工程中的一种最佳实践,它们是解决常见编程问题的经验总结,为软件开发提供了可重用的解决方案。这些模式是经过多年实践和验证的,可以帮助开发者在编写代码时保持灵活性,提高代码的可读性和可...

    中断调用方式的ARM二次开发接口设计.pdf

    为解决这些问题,基于中断调用的二次开发接口设计应考虑以下几点: 1. **模块化设计**:将功能模块化,用户仅需调用与所需功能相关的中断,减少不必要的资源占用。 2. **权限管理**:设置访问控制,限制用户对敏感...

    LTE零流量小区排除处理思路总结.doc

    【LTE零流量小区排除处理思路】\n\n在日益完善的4G网络建设中,LTE零流量小区的问题逐渐受到关注。这种现象不仅反映了用户分布和行为的实际情况,而且为引导用户发展提供了线索,同时也能暴露出设备潜在的故障。对...

    银行向对象存储架构转型升级的思路和最佳实践.docx

    尽管这种架构初期能提供较好的性能和存储性价比,但随着数据量的急剧增加,问题逐渐暴露: 1. ECM系统压力增大:ECM数据库作为联机型关系数据库,随着影像数据量的增长,查询性能下降,导致数据调阅响应时间延长。 ...

    全时域智能化监测系统的构建与实现.pdf

    为解决这些问题,文章提出了构建一个基于Python语言,结合企业微信第三方API接口的全时域智能化监测系统框架。 首先,业务系统运维痛点在于系统种类多样,涉及的技术领域广泛,对IT技术人员的综合能力要求高,而...

    Android创建UI的新思路:用javascript与Activity进行交互.zip

    参考资料和学习资料将有助于你解决遇到的问题,深入理解这一技术。在进行毕业设计或课程设计时,这种JavaScript与Activity的交互方式能让你的项目更具创新性和实用性。 总之,通过JavaScript与Activity的交互,...

    关于信息化条件下的科技档案管理工作探究.docx

    随着信息化技术的普及,科技档案管理工作得到了显著提升,但同时也暴露出信息处理系统不完善、信息化标准建设不足及工作人员素质不高等问题。文章强调了信息化技术对于提高工作效率、促进科技信息交流的关键作用,并...

    Java程序设计:第三章 面向对象程序设计.ppt

    面向对象程序设计是 Java 编程的基础,它解决了传统程序设计风格中的缺陷,如数据抽象简单、信息完全暴露、算法复杂、无法很好地描述客观世界等问题。面向对象程序设计的基本思路是首先分析问题并建立相应的对象,...

    陈家林 - Android应用安全检测

    最后,陈家林分享了解决方案的一些思路,例如,对于敏感的View,可以使用setImportantForAccessibility()或setAccessibilityDelegate()方法让Accessibility失效,防止辅助功能被滥用。 总结来说,Android应用安全...

    Dubbo视频教程--基础篇--第01节--使用Dubbo对传统工程进行服务化改造的思路介绍.rar

    - **实现服务提供者**:将业务逻辑封装为服务,实现服务接口,并配置Dubbo服务暴露。 - **实现服务消费者**:消费服务,通过Dubbo API调用服务提供者的接口。 - **部署与测试**:将服务部署到运行环境,进行功能...

    com模型

    为了应对这些问题,软件开发领域逐渐转向了组件化的设计思路,其中COM模型作为一种成熟的解决方案脱颖而出。 #### 三、COM模型的关键特性 1. **封装性**:COM组件能够将其内部实现细节隐藏起来,只暴露对外接口,...

    JavaEE技面试常见问题.doc

    ### JavaEE技术面试常见问题...以上就是JavaEE技术面试中关于数据结构、算法以及设计模式的一些常见问题及其解答思路。这些知识点对于准备面试的开发者来说非常重要,能够帮助他们更好地理解和应用这些核心概念和技术。

    使用Dubbo对传统工程进行服务化改造的思路介绍--源码.zip

    为解决这些问题,我们可以引入服务化理念,将大应用拆分为多个独立的服务,每个服务负责一部分业务功能,实现模块化和解耦。 Dubbo的核心特性包括服务注册与发现、远程调用、负载均衡、容错机制、监控等,这些都为...

    工业实时数据采集传送软件开发设计分享.pdf

    OPC服务器扮演着I/O驱动器的角色,它负责与现场设备通信,将设备数据通过OPC标准接口暴露给需要这些数据的应用程序,如人机界面软件。这种标准化接口确保了不同OPC客户端能够与多个OPC服务器无缝对接,实现互操作性...

    WebofScience数据库在计算机软件设计中的应用.docx

    传统的软件设计方法在面对复杂性和规模不断增大的项目时逐渐暴露出效率低下的问题。针对这一挑战,研究者提出了一种新的解决方案——将WebofScience数据库应用于计算机软件设计之中,旨在提升设计的有效性。 #### ...

    Thinking in Patterns

    它们描述了问题、解决方案以及适用的场景,为开发者提供了设计思路和代码实现的参考框架。 #### 模式分类 设计模式通常分为三大类: 1. **创建型模式**:关注对象的创建机制,确保系统在合适的时候创建正确的对象...

    嵌入式系统的虚拟仪器成测试系统的新思路

    4. 嵌入式系统的虚拟仪器需要解决的技术问题集中在系统平台的构建、接口和驱动程序的设计以及软面板设计等方面。 5. 硬件系统组成 硬件系统包括嵌入式主板、仪器功能板、Flash存储介质(DOC或CF卡)、液晶显示屏、...

Global site tag (gtag.js) - Google Analytics