2015-10-19 90 views
1

我目前正在研究代表一件事的类。那件事可以有多种表现形式。任何给定的事物的表示在构造时都是固定的。取决于正在使用哪种表示取决于正在存储的数据。有多少构造函数太多?

对于(抽象)例如:

  • 一种enum其中每个值是表示,e.g的类型; AlphaBetaCharlie
  • 这三个表示法都有IdName字段。
  • Beta也有一个Attributes字段。
  • Charlie也有一个ChildId字段。
  • 所有这三种表示法都有许多方法,例如, IsValidFor(...)TriggeredBy(...)
  • 所有这三种表示都存储在同一个数据库表中。

这使我有三个专门的构造一类,例如:

public enum RepresentationType { Alpha, Beta, Charlie } 

public class Representation 
{ 
    ... 
    public Representation(Guid id, String name) { Type = RepresentationType.Alpha, ... } 
    public Representation(Guid id, String name, String attributes) { Type = RepresentationType.Beta, ... } 
    public Representation(Guid id, String name, Guid childId) { Type = RepresentationType.Charlie, ... } 
} 

我明白为什么我在这里结束了,而且在某些方面这种做法是有道理的;该类表示一种类型的事物,并且它具有很多共享功能。

但是其也存在问题对于其他一些原因:

  • 每一表示具有其自己专门的构造通常涉及重复码结束。我试图通过链接构造函数来改善这一点,但后来我终于得到了很长的函数链。
  • 对于一个给定的对象,它不能保证所有的属性都会被设置,这会在我再次处理数据时导致问题。

我在考虑将这一切重构为一组子类,例如, RepresentationAlphaRepresentationBetaRepresentationCharlie。这意味着我将不得不编写更多的代码,但不要太繁琐。但是,当我需要使用集合中的表示形式时,我可以看到进一步的问题,但我不知道我实际正在查看哪种表示形式。

这是一个明智的行为吗?我只是为另一个交易一个问题?有我应该看的设计模式吗?有多少构造函数太多?

编辑基于评论:

  • 如果我子类的,我可能会也使用继承。
  • 我有一个用于创建每个单独表示的工厂模式,它是我感兴趣的每个表示的存储。
  • 不太重要,如果我做子类,我可能也会将类型保留为其重要的我正在使用的数据。
+4

从这个很难说,但你有没有考虑继承而不是使用枚举来区分你的对象? –

+0

一目了然,我想知道这是否可以成为工厂模式的良好用例? – Tim

+0

我和Nathan在一起。这听起来像你需要一个基类和子类而不是一个类和一个确定哪些字段是合适的“type”属性。 –

回答

1

没有超过一个构造函数就有很强的优势。

一旦你失去了获得两个人的优势,每个人都会失去优势。对于某些类型的每种超载都可以明确证明的人来说,有六七种以上的情况并不罕见。

我试图通过链接构造函数来改善这一点,但后来我结束了长链功能。

这并不是一件坏事,因为链条的每个步骤都应该足够明显地被认为是孤立的。如果不是,那么这是一个更大的问题的标志,这可能表明它不是两个许多构造函数的问题,因为太少的类,它们应该完全分离成不同的类(尽管也许共享一个共同的基础或实现一个共同的接口)。

1

几个构造函数没有什么错。如果班级实际上代表了单一班级的“一件事”是有道理的。

为了避免非初始化字段考虑共享(也许private)构造函数,将从您的所有其他构造函数调用来初始化通用字段。

继承往往导致更多的问题比它的价值(即如果涉及JSON序列化),所以我会等到你必须拥有它,只有在这一点考虑加入继承。另一方面,如果“一件事”只是松散地定义,并且类型在行为上有很大不同 - 尝试继承,但也看看非相关类的通用接口是否可行。