C#类工厂与子类:类自主决定实例创建的工厂模式实现困惑
这其实是**自工厂模式(Self-Factory Pattern)**的典型场景,刚好能满足你让类自身负责实例化子类的需求。我来帮你完善这个实现思路和完整代码示例:
完整实现代码示例
首先我们补全基础结构,再实现核心的创建逻辑:
// 观测数据类,用于传递创建生物的判断依据 class Observation { public int NumLegs; public bool HasWings; public int NumChromosomes; // 可根据需求添加更多属性,比如是否有外骨骼、羽毛等 } // 生物基类,负责自身及子类的实例化逻辑 class Organism { // 基类定义所有生物共有的属性/方法 public virtual string GetClassification() => "Unknown Organism"; // 核心静态创建方法:根据观测数据判断并返回对应子类实例 public static Organism CreateByObservation(Observation obs) { // 根据观测属性匹配具体生物类型 if (obs.NumLegs == 6 && obs.HasWings) { return new Insect(); } else if (obs.NumLegs == 2 && obs.HasWings) { return new Bird(); } else if (obs.NumLegs == 4 && !obs.HasWings) { return new Mammal(); } // 处理未匹配到的情况:返回默认实例、null或抛出异常都可 else { return new UnknownOrganism(); } } } // 具体生物子类,继承自Organism class Insect : Organism { public override string GetClassification() => "Insect"; } class Bird : Organism { public override string GetClassification() => "Bird"; } class Mammal : Organism { public override string GetClassification() => "Mammal"; } class UnknownOrganism : Organism { public override string GetClassification() => "Unknown"; }
关键设计要点
- 自包含创建逻辑:所有子类的实例化判断逻辑都集中在基类的静态方法里,完全符合你“由类自身决定创建子类实例”的需求,不需要额外的独立工厂类。
- 扩展性友好:后续新增生物类型时,只需要添加对应的子类,再在
CreateByObservation方法里新增一个判断分支即可,无需修改其他现有代码。 - 封装实例化细节:外部调用者只需要传入
Observation对象,无需关心具体实例化的是哪个子类,降低了调用端与具体生物类的耦合度。
优化建议(应对大量子类场景)
如果后续需要支持的生物类型很多,大量的if-else会让代码变得臃肿难维护,这时可以用条件-类型映射字典来优化:
class Organism { // 提前定义判断条件与对应子类的映射 private static readonly Dictionary<Func<Observation, bool>, Type> _organismTypeMap = new Dictionary<Func<Observation, bool>, Type> { { obs => obs.NumLegs == 6 && obs.HasWings, typeof(Insect) }, { obs => obs.NumLegs == 2 && obs.HasWings, typeof(Bird) }, { obs => obs.NumLegs == 4 && !obs.HasWings, typeof(Mammal) } }; public static Organism CreateByObservation(Observation obs) { // 遍历映射字典,找到第一个匹配的类型并实例化 foreach (var mapping in _organismTypeMap) { if (mapping.Key(obs)) { return Activator.CreateInstance(mapping.Value) as Organism; } } return new UnknownOrganism(); } // 基类其他属性/方法... }
这种方式把判断逻辑和类型解耦,新增子类时只需要在字典里添加一条映射即可,代码的可读性和维护性会大幅提升。
内容的提问来源于stack exchange,提问作者ErikvdW
相关产品推荐
相关产品推荐

