一种在超类中实例化子类的方法

 我确实是一只猪_143_267 发布于 2023-02-13 18:43

我有一个基本抽象类,它聚合了一个集合中的一堆项目:

abstract class AMyAbstract
{
    List Items { get; private set; }

    public AMyAbstract(IEnumerable items)
    {
        this.Items = new List(items);
    }
}

有很多子类,让我们为它们命名Foo,Bar,Baz,等他们都是一成不变的.现在我需要一个merge()方法,它将合并items两个对象,如下所示:

abstract class AMyAbstract
{
    // ...
    public AMyAbstract merge(AMyAbstract other)
    {
        // how to implement???
    }
}

Foo foo1 = new Foo(new string[] {"a", "b"});
Bar bar1 = new Bar(new string[] {"c", "d"});
Foo fooAndBar = foo1.merge(bar1);
// items in fooAndBar now contain: {"a", "b", "c", "d"}

由于对象是不可变的,因此该merge()方法不应该更改items字段的状态,而应该返回调用它的类uppon的新对象.我的问题是:如何明智地实施该merge()方法?

问题1:AMyAbstract显然不了解子类的特定构造函数(依赖性反转原理),因此我不能(或者我可以)在超类中创建子类的实例.

问题2:每个子类中的实现merge()方法是很多代码重复(DRY规则).

问题3:将merge()逻辑提取到一个全新的类并不能解决DRY规则问题.即使使用访客模式,也需要大量复制/粘贴.

上面提到的问题排除了我在阅读有关SOLID之前可能已经实现的任何想法.(从那时起,我的生活一直很悲惨;)

或者是否有一个完全不同的,开箱即用的approch来实现这些对象的合并?

我很欣赏C#,Java甚至PHP的答案.

编辑:我想我遗漏了一条有效的信息:事件虽然有很多不同的子类,但他们可以(应该)只用两种,也许三种方式构建(作为单一责任原则的含义):

无参数构造函数

一个接受一个IEnumerable参数的构造函数

一个接受数组和其他修饰符的构造函数

如果我可以在构造函数上设置约束 - 例如通过在接口中定义构造函数,这会将访问者模式放回到tablie 上.但这只能在PHP中实现.在Java或C#中,无法强制执行构造函数签名,因此我无法确定如何实例化子类.这是一个很好的规则,因为人们永远无法预测子类的作者如何构建对象,但在这种特殊情况下它可能会有所帮助.所以一个帮助问题是:我可以以某种方式强制实现类的实例化吗?在这个简单的情况下,Builder模式听起来太过分了,还是这样?

1 个回答
  • 你是对的依赖倒置规则和代码重复问题.

    您可以在抽象类中编写合并逻辑的核心实现,并给出为派生类创建新实例的任务.在抽象类中创建一个抽象方法,强制所有子项实现它.目的是这个方法是创建一个新的类实例并返回它.超类将使用此方法来获取新实例并进行合并.

    生成的java代码看起来像这样

    abstract class AMyAbstract {
        // ...
        public AMyAbstract merge(AMyAbstract other) {
            AMyAbstract obj = getNewInstance();
            // Do the merge
            // Return the merged object.
        }
    
        protected abstract AMyAbstract getNewInstance();
    }
    
    class foo extends AMyAbstract {
        protected foo getNewInstance() {
            // Instantiate Foo and return it.
        }
    }
    

    希望这可以帮助..

    2023-02-13 18:46 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有