9

この .jar を開発者に配布する予定の最終製品として、Java ライブラリを作成しています。

開発者が利用できるクラス ヘッダー ファイルを制御する Objective-C からライブラリを "翻訳" しています。つまり、開発者が処理できるいくつかのクラスのみを開発者に公開しています。

Java ライブラリでパッケージを使用していますが、パッケージがかなり大きくなりました。そこで、モデルとコントローラーを別々のパッケージに分けることにしました。しかし、プライベートにしたかったモデルは、メイン パッケージから使用するためにパブリックとしてマークする必要があります。

私の質問は、これは Objective-C で行っていたことに反しますか?

たとえば、実際には内部でのみ使用される Event クラスがあり、ユーザーにそれを知られたり、考えたりしたくありません。ユーザーが管理のインスタンスを取得できる別のクラス TimedEvent があります。

私の Objective-C では、Event クラスをライブラリのパブリック スコープから単純に除外し、TimedEvent を許可しました。

私が自分のライブラリで物事をより整頓している場合、パッケージはその方法ではないようです。今では、私のメイン コントローラーはメイン パッケージにあり、すべてのモデルは別のパッケージにあり、パブリック スコープを持つ必要があります。

意見 ?

4

2 に答える 2

5

これはJavaで可能ですが、(ほとんど)誰もそれをしない理由があります...

実装とインターフェースを同じパッケージに入れる場合、クラスとメソッドからすべてのアクセス修飾子 ( privateprotectedpublic) を省略して、「デフォルト」または「パッケージ」の可視性を与えることができます。同じパッケージ内のクラスのみが表示を許可されます。 /それらを使用します。

欠点: API と実装を混在させる必要があります。

もう 1 つのアプローチは、実装をパッケージに移動すること*.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 に答える