2017-10-31 7 views
2

Pythonからkotlinに変換して、そのパッケージを使用してシステムを移行できるようにするパッケージがあります。kotlin、どのように基本クラスのコンストラクタにパラメータを渡すを簡単にするには?

パッケージ内には、すべてのバリアントまたは共通の基本クラスの「味」であるクラスのセットがあります。

コードのほとんどは、かなりの数のオプションパラメータを持つ基本クラスにあります。そう考える:

オープンクラスBaseTree(ヴァル・高さ:intは= 10、ヴァルルーツ:ブール=真、// ......その他たくさん!!

class FruitTree(val fruitSize, height:Int=10, roots:Boolean=true, 
    // now need all possible parameters for any possible instance 
    ):BaseTree(height=height, roots=roots //... yet another variation of same list 

コード、実際の木ではありませんこれは基本クラスと約10個のサブクラスに約20個のパラメータがあり、各サブクラスは基本クラスから同じ2つのバリエーションを実際に繰り返す必要があるということです。パラメータリストが変更された場合の本当の悪夢!

「20パラメータが多すぎます」とコメントしているかもしれないこれはのオプションパラメータであり、このデザインの側面に影響を与える言語機能です。 20個の必須パラメータが狂っているかもしれませんが、10個または20個のオプションのパラメータもあまり一般的ではありません。たとえば、sqlalchemy Tableをチェックしてください。

Pythonでは、あなたが持つことができ、基本クラスのコンストラクタを呼び出すには:

def __init__(self, special, *args, **kwargs): 
    super().__init(*args, **kwargs) # pass all parameters except special to base constructor 

は、誰もが技術を知っています、別の方法を使用して、このパラメータリストの繰り返しを避けるために(おそらくインターフェイスまたは何かを使用していますか?)サブクラスごとに繰り返しますか?

答えて

0

この使用例を簡略化する設計パターンはありません。

ベストソリューション:Javaのようなアプローチを使用するコードをリファクタリングします。オプションのパラメータの代わりにプロパティを使用します。

ユースケース説明:多数のオプションパラメータを持つ広く使用されているクラスまたはメソッドは、Javaでは実用的ではなく、kotlinはJavaコードを改善する方法として最も進化しています。 5つのオプションのパラメータを持つpythonクラスは、オプションのパラメータを持たないJavaに変換され、5つの可能性があります。 (そして5階乗はです)異なるJava署名...言い換えれば混乱です。

普通のpythonクラスは、大部分の呼び出しでこれらのオプションのパラメータを指定する必要がなく、オプションのパラメータが例外の場合にのみ使用されるため、クラスに対して進化します。実際のユースケースは、多数のオプションパラメータの実装です.3つ以上のオプションパラメータを使用して個々のオブジェクトをインスタンス化することは非常にまれです。したがって、アプリケーションで500回使用される10個のオプションのパラメータを持つクラスは、3つのオプションパラメータが1つのインスタンスで使用されていた最大値になると予想します。しかしこれは、クラスが再利用される頻度にかかわらず、Javaでは実行できない設計アプローチです。

Javaでは、関数はオプションのパラメータを持っています。つまり、オブジェクトがJavaライブラリ内でこのようにインスタンス化された場合は、決して起こり得ません。

1つの必須インスタンスパラメータと5つの可能なオプションを持つオブジェクトを考えてみましょう。 Javaでは、これらのオプションはそれぞれ設定子によって設定可能なプロパティであり、オブジェクトはインスタンス化され、関連するオプションの設定が呼び出されますが、そのオプションのデフォルト値への変更は必要ありません。

これらのオプションはコンストラクタから設定することはできず、不変のままにしておくことができますが、結果のコードによってオプションのパラメータが減少します。

もう一つのアプローチは、「スイスアーミーナイフ」オブジェクトのグループを持たせることです。これは、コードがわずかに異なるニュアンスであると見なされても、同じテーマ。

kotlinのオプションパラメータのサポートにもかかわらず、kotlinの継承構造は、この機能のより重い使用のためにまだ最適化されていません。

0

あなたのサブクラスが本当にそのコンストラクターにその多くのパラメーターを持っているなら、その周りにはありません。あなたはそれらすべてを渡す必要があります。

しかし、(主に)それは、コンストラクタ/機能は、多くのパラメータが...

あなたはこの上だけではないことを持っていることを、何の良い兆候ません。これについては、すでにgradle-slackチャンネルで議論されています。将来的には、これについてコンパイラの助けを得ることになるでしょうが、今のところあなた自身で引数を渡す必要があります。

1

BaseTree(height, roots)のような名前をスキップすることはできますが、変数を並べ替えることはできますが、Pythonは動的言語なのでPythonのようなことはできません。

Javaが変数をスーパークラスにも渡す必要があるのは正常です。

FruitTree(int fruitSize, int height, boolean root) { 
    super(height, root); 
} 

これが最も可能性が高いあなたのクラスの設計の問題である基底クラスには約20のパラメータ、および約10サブクラス

があります。

+0

私はsqlalchemyについて考えていた最初の人気のあるPythonパッケージを見てきました。そして、私が見た最初の主要なクラスであるTableクラスには、文字通り20個のオプションのパラメータがあります(これは必要なパラメータに加えて、 )。これはクラスデザインに問題があることを意味しますか?それはおそらくすべてのpython広く使用されているパッケージは、彼らのデザインに問題がありますか?私は、これが言語でオプションのパラメータを持つことに起因する違いだと思う。 Javaでは、オプションのパラメータがない場合は、20個のパラメータは指定できませんが、オプションの場合は災害になります。 – innov8

関連する問題