3

たとえば、java.io.File は単なる具象クラスです。私の代替品は、Windows ショートカットの解決をサポートしています。抽象パスで正規化/正規化/解決を行う FileSystem オブジェクトにアクセスできないため、可能な .lnk ファイルを解決するためにコンストラクター パラメーターを前処理する必要があります。前処理の必要性により、純粋なサブクラス化が除外されます。super(...) を呼び出す前に前処理を行うことはできず、File は不変です。そこで、File を拡張してデリゲートを使用し、File のすべてのコンストラクターとメソッドをオーバーライドします (すべてのコンストラクターで super("") を呼び出します)。

これはうまく機能しますが、明らかに理想的ではありません。ファイルが変更された場合、新しいメソッドやコンストラクターをオーバーライドしていないため、基になる空の抽象パス名が公開されます。明らかな何かが欠けていますか?よりシンプルでより良い方法があるはずです。

4

4 に答える 4

9

特定のケースでは、正規化/正規化/解決に関する決定を行う別のファクトリ クラスを使用したほうがよいように思われます。

次に、ファイルをファイルにすることができます。よりシンプル。

于 2008-12-10T11:23:53.240 に答える
4

本当にサブクラス ルートが必要な場合はsuper()、クリーンアップ コードをクラスの外または静的ブロックに配置することで、 への呼び出しがサブクラス コンストラクターの最初の行でなければならないという要件をごまかすことができます。

public class MyFile extends File {

    public MyFile(String path) {

        // static blocks aren't ideal, this is just for demo purposes:
        super(cleanPath(path)); 
    }

    private static String cleanPath(String uncleanPath) {...}

}

krosenvold によって提案されたファクトリ パターンは、別の優れたソリューションです。

于 2008-12-10T11:28:18.770 に答える
2

これはうまく機能しますが、明らかに理想的ではありません。ファイルが変更された場合、新しいメソッドやコンストラクターをオーバーライドしていないため、基になる空の抽象パス名が公開されます。明らかな何かが欠けていますか?

いいえ、継承の使用に関する問題を発見しました。サブクラスはスーパークラスとその内部に密接に結合されているため、壊れやすい可能性があります。そのため、Effective Java などは、可能であれば継承よりも委譲を優先すべきだと言っています。

krosenvold の解決策はきれいに聞こえると思います。

于 2008-12-10T11:32:25.187 に答える
2

krosenvoldの解決策が進むべき道だと私には思えます。

ただし、ファイルを作成した元のパスを記録しておく必要がある場合は、ラッパー クラスを実装できます。

public class FileWrapper {

    private File file;
    private String path;

    private FileWrapper(String path) {
        this.path = path;
        file = new File(preProcess(path));
    }

    private String preProcess(String path) {
        // process
        return path;
    }

    public File getFile() {
        return file;
    }

    public String getPath() {
        return path;
    }
}
于 2008-12-10T11:36:01.170 に答える