我有一个包含几个包的库-
让我们说
包一个;
包b;
在包 a 里面我有 public a_class
在包 b 里面我有 public b_class
a_class 使用 b_class。
我需要由此生成一个库,但我不希望客户端看到 b_class。
我知道的唯一解决方案是将我精美易懂的包扁平化为单个包,并对 b_class 使用默认包访问。 还有其他方法吗?也许使用接口(interface)或某种形式的设计模式??
最佳答案
如果您拒绝将代码移动到一个单独的、受控的服务器上,那么您所能做的就是在尝试使用您的 API 时阻碍客户端程序员。让我们开始将良好实践应用于您的设计:
- 让您的包裹按照现在的方式组织起来。
对于每个你想“隐藏”的类:
- 不公开。
- 将其公共(public) API 提取到新的公共(public)接口(interface):
公共(public)接口(interface) MyInterface {...}
- 创建一个公共(public)工厂类以获取该接口(interface)类型的对象。
公共(public)类 MyFactory { 公共(public) MyInterface createObject(); }
到目前为止,您的包已经松散耦合,并且实现类现在是私有(private)的(正如良好实践所宣扬的,您已经说过)。尽管如此,它们仍然可以通过接口(interface)和工厂获得。
那么,如何避免“陌生”客户端执行您的私有(private) API?接下来是一个创造性的、有点复杂但有效的解决方案,它基于阻碍客户端程序员:
修改你的工厂类:为每个工厂方法添加一个新参数:
public class MyFactory
{
public MyInterface createObject(Macguffin parameter);
}
那么,什么是Macguffin
?它是您必须在应用程序中定义的新接口(interface),至少有一个方法:
public interface Macguffin
{
public String dummyMethod();
}
但不提供此接口(interface)的任何可用实现。在代码的每个地方,您都需要提供一个 Macguffin
对象,通过 anonymous 类创建它:
MyFactory.getObject(new Macguffin(){
public String dummyMethod(){
return "x";
}
});
或者,更高级,通过动态代理对象,即使客户端程序员敢反编译代码,也找不到这个实现的“.class”文件。
你从中得到什么?基本上是劝阻程序员不要使用需要未知、未记录、无法理解的对象的工厂。工厂类应该只注意不要接收空对象,并调用虚拟方法并检查返回值是否也不为空(或者,如果您想要更高的安全级别,请添加未记录的 key 规则)。
因此,此解决方案依赖于您的 API 微妙的混淆,以阻止客户端程序员直接使用它。 Macguffin 接口(interface)及其方法的名称越模糊越好。
关于java - 如何防止客户端在 Android 库中看到内部私有(private)类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28147027/