2016-06-21 76 views
0

我有一个工厂类CipherBuilder,其静态方法build返回StringCipher对象到客户端。 我想隐藏StringCipher类,所以客户端只能通过CipherBuilder工厂得到这种类型的对象,并且不能直接调用类构造函数(但它仍然可以使用它的公有方法)。以工厂模式隐藏客户端的产品

我当前的实现是创建另一个包从客户端代码分开,并把其中的三个班,CipherBuilder工厂(这是公开的),在StringCipher(包私人)和公共的接口吧(IStringCipher)。这样客户端不能直接调用构造函数,但它仍然可以通过接口使用公共方法。

但是因为我不得不创建一个新的包来隐藏一个类,这就像一个黑客。有没有更好的方式来执行此操作(使用Java),同时将StringCipher保留在与客户端代码相同的包中,并将StringCipherCipherBuilder保存在单独的文件中?

+0

让CipherBuilder创建一个IStringCipher。并且StringCipher以某种方式被隐藏。它确实意味着一个包私人类和构造函数。子包也是惯例。人们可以使该类成为工厂类的静态内部类。 –

+0

因此,在将StringCipher与客户端代码保持在同一个包中时,没有办法做到这一点?我可以在单独的文件中执行静态内部类吗? – devil0150

+1

另一种方法:** Java SPI,服务提供程序接口**。这是一种机制,通过该机制可以发现并加载XML解析器。至于原始问题:我不完全确定你想要指定的东西是多么“好”。 (顺便说一下,至少有一个'package'是常态。)有一个带有私有构造函数的类(例如工厂),可以将工厂传递给构造函数并检查一个非null对象。丑陋! (更好地等待Java 9与模块。)对不起,混乱。 –

回答

2

为了保持CipherBuilderStringCipher在同一个包,你可以做的StringCipher构造的保护,这样,客户端无法建立StringCipherCipherBuilder仍然可以访问,因为这两个类都在同一个包。

我希望这有助于

+0

关键在于隐藏课程而不为其创建单独的包。我将编辑帖子来解释这一点。 – devil0150

+0

似乎没有更好的解决方案。你能否在答案中包括“如果客户类在同一个包中”的句子,我会接受它。 – devil0150

0

有几件事情,你如何能实现它。

您可以将StringCipher类定义为CipherBuilder类中的私人类。如果StringCipher将被编码为接口,则工厂方法CipherBuilder可能会返回给您一个接口;

其他的解决办法,如果你不想接口,将在同一个包中定义CipherBuilderStringCipher,并设置访问级别StringCipher的构造函数包(没有访问修饰符级)。然后StringCipher只能在包内创建。

+0

第二种解决方案是我目前正在做的。第一个解决方案可以在保持StringCipher与CipherBuilder不同的文件的情况下完成吗? – devil0150

+0

@ devil0150也许我误解了你,但如果两个类都在单独的包中,并且在问题描述中建议你有单独的包,那么第二种解决方案将无法工作。和第一个解决方案不会工作,如果你有私人的构造函数。除非你使用反射,但这将是不好的做法,对于这种情况 – user902383

+0

@ devil0150,当然你可以分开它们,并改变访问级别,但是再次,这将与第二个解决方案相同 – user902383

0

我认为最简单的方法是:

1)创建你的包

2)在里面你的包中创建:

public class CipherBuilder{...} 
    public class IStringCipher{...} 
    class StringCipher {...} 

你的包外,没有人会看到CipherBuilder。

+0

我假设第三行应该是StringCipher。但是,这仍然是我目前正在做的。 – devil0150

+0

是的,只是改变了它。我明白,你需要客户端在同一个包中。也许你可以在一个单独的文件中定义一个asbtract StringCipher类,并将一个Inner类定义到实现它的CipherBuilder中。它有意义吗? –