是为了识别类型而推导出一个好主意吗?

时间:2012-08-07 20:59:02

标签: oop inheritance refactoring

问题比平时长,但我试着详细说明。请耐心等待并阅读整个问题,这可能是一个有趣的问题

我有一个方法A当前接受一个具有两个属性List<X>但是代表两个不同实体的对象,因此该属性被命名为aptly R和S.类结构是

class A
{
   List<X> R;
   List<X> S;
}

现在我有一个方法接受类型A的输入并同时使用(集合,方法签名)

public void updateMe(A objA)
{

}

现在我有一个案例,我需要重用这个方法,但现在的情况是我不需要区分实体,因此只有一个列表,List<X> T。

现在我的问题是如何重构方法以使用单个列表,但仍然提供了区分前面两个列表的能力。

我的方法将更新这些集合,因此可以添加到列表中或从中删除。

我的解决方案目前是创建新类来表示从X派生的两个不同实体,然后将此基类列表传递给我的方法,并让方法更新此基类,然后在阅读它时我将能够确定哪个对象是什么类型。

因此我的新课程将是

public class X1:X
{
}

public class X2:X
{
}



class A
{
   List<X> R;
}

这是最好的解决方案还是我可以采取的任何其他方法...我似乎不喜欢扩展类只是为了识别类型而不添加任何属性的想法。

2 个答案:

答案 0 :(得分:0)

我会说,要么: 1.使用ENUM :) 2.使用抽象方法getList()使类Y和Z扩展抽象X.但对于简单的案例来说,这肯定是一种矫枉过正。所以,回到1 - 只需使用枚举:)

答案 1 :(得分:0)

似乎目标是在类的内容上实现一种多态的形式。从这个意义上讲,你应该为内部内容隔离一个类,所以我的回答集中在导致你的问题的目标而不是问题本身。

一般来说,对于你问题的先验,我会说两个集合之间的区别,每个集合代表一个不同的实体,不是代表类型的问题,假设它是正确的,但是调用者的责任。
我的回答遵循这条路径,然而以强类型的方式实现变量内部表示和更新逻辑,具有静态多向性(省略,出于时间原因,向您解释此选择)。

作为决定是否使用X的子类的规则,您应该问自己:updateMe逻辑运行List<X> RList<X> S的更新,它确实根据对象的详细信息X

我从你的问题中假设这并不总是两个列表,我的解决方案也概括了集合的类型 我希望能给你一个起点。如果我猜到你的要求,我会说明更多。

template <class staticPolimorphicAInnerT>
class A 
{
    public:
        void updatMe (const A& ref) {
            // <do something pre if necessary>
            updateInnerMe (A.innerObj);
            // <do some other post if necessary>
        }

        void updateInnerMe (const staticPolimorphicAInnerT& innerRef) {
            innerObj.updateMe (innerRef);
            // or better: 
            // inner_update_method (innerRef)
        }

    private:
        // is used to request the static polymorphism
        typedef void (staticPolimorphicAInnerT::* inner_update_method) (const staticPolimorphicAInnerT&)
        staticPolimorphicAInnerT innerObj; 
        //<something more i hope> 

}

template <class T>
class AInnerFirst
{
    public:
        void updatMe (const AInnerFirst& ref) {
            // <do something with R>
            // <do something with S>
        }

    private:
        List<T> R;
        List<T> S;
}

template <class T>
class AInnerSecond 
{
    public:
        void updatMe (const AInnerSecond& ref) {
            // <do something with W>
        }

    private:
         Vector<T> W;
}