9

我正在创建一个 Java 库,作为最终产品,打算将此 .jar 分发给开发人员。

我正在从 Objective-C “翻译”我的库,我在其中控制开发人员可以使用哪些类头文件。换句话说,我只向开发人员展示他们可以处理的几个类。

在我的 Java 库中,我正在使用包并且我的包已经变得非常大。所以我决定把我的模型和控制器分成不同的包。但是现在我想保持私有的模型需要标记为公共才能从主包中使用。

我的问题是这是否违背了我在 Objective-C 中所做的事情?

例如,我有一个 Event 类,它实际上只在内部使用,我不希望用户知道或考虑它。我有另一个类 TimedEvent,用户可以获得一个管理实例。

在我的 Objective-C 中,我只是从库公共范围中排除了 Event 类,允许 TimedEvent。

如果我在我的图书馆里让事情变得更整洁,那么似乎包不是办法。从现在开始,我的主控制器在主包中,所有模型都在另一个包中 - 被迫具有公共范围。

意见?

4

2 回答 2

5

这在 Java 中是可能的,但有原因(几乎)没有人这样做......

如果将实现和接口放在同一个包中,则可以省略类和方法中的所有访问修饰符(private, protected, public)以赋予它们“默认”或“包”可见性:仅允许同一包中的类查看/使用它们。

缺点:您必须混合 API 和实现。

另一种方法是将实现移动到一个包*.private.*中。不再混合 API 和实现,但恶意用户可以轻松访问实现 - 这只是一个命名约定。就像一个停止标志:它意味着一些东西(“小心”),但实际上并没有阻止你。

最后,您可以在接口内部实现接口。例如:

public interface IFoo {
    String getName();

    private static class Foo implements IFoo {
        public String getName();
    }

    public static class FooFactory {
        public static IFoo create() { return new Foo(); }
    }
}

丑陋,不是吗?

于 2012-07-09T14:07:48.297 回答
4

控制类向世界公开的常用方法是将实现隐藏在接口和工厂后面。

  • 为您创建一个接口,以及一个用于创建接口TimedEvent实例的类TimedEvent
  • 将接口放在主包中,工厂放在子包中
  • 让工厂公开可见
  • 在子包中实现接口,使其具有包可见性
  • TimedEvent在工厂中创建实现接口的类的实例

这是一个如何做到这一点的例子:

package com.my.main;
public interface TimedEvent {
    void fire();
}

package com.my.main.events;
import com.my.main;
public class EventFactory {
    public TimedEvent makeTimedEvent() { return new TimedEvent (); }
}
// TimedEventImpl has package visibility - it is not public.
class TimedEventImpl implements TimedEvent {
    public void fire() {
        // Fire a timed event
    }
}

用户将TimedEvent像这样访问:

com.my.main.events.EventFactory f = new com.my.main.events.EventFactory();
com.my.main.TimedEvent evt = f.makeTimedEvent();
evt.fire();
于 2012-07-09T14:12:15.217 回答