如果您拒绝将代码移动到单独的、受控的服务器上,那么您所能做的就是在尝试使用您的 API 时阻碍客户端程序员。让我们开始将良好实践应用于您的设计:
- 让您的包裹按现在的方式组织起来。
-
对于每个你想“隐藏”的类:
public interface MyInterface {...}
public class MyFactory
{
public MyInterface createObject();
}
到目前为止,您的包已松散耦合,并且实现类现在是私有的(正如良好实践所宣扬的,并且您已经说过)。尽管如此,它们仍然可以通过接口和工厂获得。
那么,如何避免“陌生”客户端执行您的私有 API?接下来是一个创造性的、有点复杂但有效的解决方案,它基于阻碍客户端程序员:
修改你的工厂类:为每个工厂方法添加一个新参数:
public class MyFactory
{
public MyInterface createObject(Macguffin parameter);
}
那么,Macguffin 是什么?它是您必须在应用程序中定义的新接口,至少有一个方法:
public interface Macguffin
{
public String dummyMethod();
}
但不提供此接口的任何可用实现。在代码的每个地方,您都需要提供一个Macguffin 对象,通过匿名 类创建它:
MyFactory.getObject(new Macguffin(){
public String dummyMethod(){
return "x";
}
});
或者,更高级,通过动态代理对象,即使客户端程序员敢反编译代码,也找不到这个实现的“.class”文件。
你从中得到什么?基本上是劝阻程序员不要使用需要未知、未记录、无法理解的对象的工厂。工厂类应该只注意不要接收空对象,并调用虚拟方法并检查返回值是否也不为空(或者,如果您想要更高的安全级别,请添加未记录的密钥规则)。
因此,此解决方案依赖于对您的 API 进行微妙的混淆,以阻止客户端程序员直接使用它。 Macguffin 接口及其方法的名称越模糊越好。