言語設計者が意図したデフォルトの慣行と、後でそれらの慣習から逸脱したとしても、言語の改善を目標とするデフォルトの慣行を知ることは常に役立つと思います。Scala では、すべてのフィールドは、宣言されているクラスのコンストラクターで初期化する必要があります。これは重大な制限です。2 次コンストラクターも制限されています。コンストラクター内の一時変数は、コンストラクターの本体が乱雑に見える可能性がある不要なフィールドを回避するために、内部メソッドまたはクロージャーに配置する必要があります。これはすべて、コンストラクタ本体の使用に不利です。スーパークラスから抽象変数に代入する場合でも必要なオーバーライド val/var 構文は、構築のために派生クラスを使用する利点の一部を取り除きます。
コンパニオン オブジェクトは、そのクラスのすべてのフィールドにアクセスできます。ただし、クラスのコンストラクターですべてのフィールドを初期化する必要があるため、構築の場合、これは最初に現れる可能性があるという利点ではありません。そのため、オブジェクト内のメソッドを使用してクラス変数の処理を行い、クラス内の不変コレクションごとに一時的な可変コレクションを作成し、listbuffer をデフォルトにして、すべての値とコレクションを実体のないコンストラクタ。ファクトリは任意のオブジェクトまたはクラスに含めることができますが、特に理由がない限り、コンパニオン オブジェクトに含めることもできます。オブジェクトは型パラメータを取ることができませんが、ファクトリ メソッドは必要に応じて取ることができます。そしてもちろん、準コンストラクターが必要な数のファクトリ メソッドを持つことができ、一般的なアルゴリズムを再利用できます。
これは正しいです?
例の要求に応えて、C# から Scala に移植する過程にあるコンストラクターを次に示します。Scala では複数の型パラメーターがなくなっていることに注意してください。
public class GridC : GridBase<HexC, SideC, UnitC, ISegC>
{
public Geometry<HexC, SideC, UnitC, ISegC> geomC { get; private set; }
internal GridC(Scen scen, int gridNum, int xDim, int yDim, int xOff, int yOff, Terr terr = Terr.Plain):
base(gridNum, scen, 10.0)
{
this.geomC = scen.geomC;
xIntLeft = xOff + 1;
yIntBottom = yOff;
xIntRight = xDim * 2 + 1 + xOff;
yIntTop = yDim * 2 + 2 + yOff;
Coodg hexCoodg;
for (int x = xOff; x < xDim * 2 + xOff; x += 2)
{
for (int y = yOff; y < yDim * 2 + yOff; y += 2)
{
if (x % 4 == y % 4)
{
hexCoodg = new Coodg(num, x + 2, y + 2);
HexC hexC = scen.hexCs.NewHexC(hexCoodg);
SideC sideC;
MiscStrat.sixDirn.ForEach(i =>
{
Coodg sideCoodg = hexCoodg + Cood.DirnTrans(i);
sideC = sides[sideCoodg];
if (sideC == null)
scen.sideCs.NewSide(hexC, i);
else
scen.sideCs.SetHex2(sideC, hexC, i);
});
}
}
}
}
上記のサブクラスは、構築に関連する部分を示すためだけに編集された次の基本クラスのコンストラクターを提供するために純粋に作成されています。
public class GridBase<HexT, SideT, UnitT, SegT> : IGridBase
where HexT : Hex where SideT : Side where UnitT : Unit where SegT : ISeg
{
public int num { get; private set; }
int IGridBase.num { get { return num; } }
IListsGeom<HexT, SideT, UnitT> iLists;
public HexList<HexT> hexs { get { return iLists.hexs; } }
public SideList<SideT> sides { get { return iLists.sides; } }
public Geometry<HexT, SideT, UnitT, SegT> geom { get; private set; }
public int xIntLeft { get; protected set; }
public int xIntRight { get; protected set; }
public int yIntBottom { get; internal set; }
public int yIntTop { get; internal set; }
public double scale { get; private set; }
protected GridBase(int num, IListsGeom<HexT, SideT, UnitT> iLists, double scale)
{
this.num = num;
this.iLists = iLists;
this.scale = scale;
}
}
コンストラクターは、単純な均一な Hex グリッドを作成します。完全に異なるアルゴリズムを使用する他のコンストラクターが必要であり、関連するがより複雑なアルゴリズムを必要とする他のコンストラクターが作成されます。私は専門家ではありませんが、私の印象では、ファクトリは C# ではあまり使用されていません。