我认为,了解语言设计者所期望的默认实践以及他们针对语言改进的默认实践总是有用的,即使稍后会偏离这些实践约定。在Scala中,所有字段都必须在它们声明的类的构造函数中初始化。这是一个重要的限制。次要构造函数也受到限制。构造函数中的任何临时变量都需要放在内部方法或闭包中,以避免不必要的字段,这会使构造函数的主体看起来很乱。所有这些妨碍了使用构造函数体。即使分配给来自超类的抽象变量,也需要覆盖val/var语法,以消除为了构建而使用派生类的一些优点。Scala创建需要复杂构造过程的对象的默认方式
伴侣对象可以访问其类的所有字段。然而,对于构造来说,这并不是它可能首先出现的优点,因为所有的字段都必须在类的构造函数中初始化。所以似乎自然的做法是在对象中使用方法来处理类变量,为类中的每个不可变集合创建一个临时可变集合,默认为listbuffer,然后将所有值和集合传入一个无形的构造函数。工厂可以在任何物体甚至是班级中,但也可以在伴侣物体中,除非有其他充足的理由。对象不能使用类型参数,但如果需要,它们的工厂方法可以使用当然,您可以拥有许多工厂方法,因为您需要准构造函数,并且可以重用任何常用算法。
这是正确的吗?
针对为例请求,这里的构造我从C#对面斯卡拉移植的过程是,注意多类型参数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;
}
}
该构造函数创建一个简单的统一十六进制网格。其他构造函数需要使用完全不同的算法,其他构造函数需要相关但更复杂的算法才能创建。我不是专家,但我的印象是工厂在C#中的使用少得多。
我不确定要理解你的问题。你能否提供一个“复杂的施工过程”的例子? – paradigmatic
@paradigmatic提供的示例 –
构造函数看起来像是附加到伴随对象的主要候选对象,尽管在这种情况下我会试图使它成为一个更具体的命名方法,以清楚它的作用。 –