内部类使用外部类的方法。这是Cyclic参考吗?怎么避免

时间:2014-11-25 05:13:23

标签: java inner-classes cyclic-reference

我想知道在内部类中调用外部Class方法然后在外部类中使用内部Class方法被认为是不好的做法。

在这种情况下:  在 BidParser 中,我调用属于外部类的方法 updateMaps ()。 此外,我在 BidParser 中调用第二个内部类 InputSanityChecker 的方法。

这是不好的做法和反模式吗?我在这里创造一个上帝对象吗?(尽管其他外部课程要遵循更多功能)

编辑:我有两个变量Var1,Var2(比方说)属于Outer,但是对于updateX和checkX方法是必需的。

public class Outer{


    public static void main( String[] args ){
        if(args.length == 1){
            File file = new File(args[0]);
            BidParser.parseBids(file);//<--- Question refers here
        }else{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            BidParser.parseBids(br);  //<--- and here
        }
    }


    private static void updateMaps(String[] elements){
        //.....blah blah
    }

    static class BidParser{
        public static void parseBids(File file){
            //.....blah blah
            InputSanityChecker.checkInput(elems);//<---second inner class method
            InputSanityChecker.checkMaps(elems);    //<---second inner class method
            updateMaps(elems);  //<-----outer class method

        }
        public static void parseBids(Reader reader){
            //.....blah blah
            InputSanityChecker.checkInput(elems);//<---second inner class method
            InputSanityChecker.checkMaps(elems);    //<---second inner class method
            updateMaps(elems);  //<-----outer class method

        }
      }
    static class InputSanityChecker{

        public static boolean checkInput(String[] elements){
              //.....blah blah
        }

        public static boolean checkMaps(String[] elements){
              //.....blah blah
        }   
    }
}

1 个答案:

答案 0 :(得分:5)

它不是循环引用。所有类 - 外部和嵌套静态 - 都是编译器同样独立的。在调用静态方法时,没有实例引用。

此设计违反单一责任原则BidParser应负责解析出价,以及全部。即这个类应该接受输入 - 甚至不是File,只是Reader,并且产生一些Bids对象,它应该返回给调用者。

然后调用者的责任1)以任何Reader和2)的形式准备输入以获取生成的Bids对象并对其执行某些操作。 Reader可以是FileReader,BufferedReader,StringReader等的实例......参见Java IO Documentation

此外,此设计违反了不要重复自己原则。您可以在BidParser中看到重复的代码。一旦您将类设计为仅使用更抽象的输入,这种违规将自动修复。

考虑InputChecker,如果每个元素都是以其他元素的形式检查的,那么这个类应该负责一次只检查一个可检查的块(元素)。并且解析器负责迭代元素并根据需要调用InputChecker

如果外部类中有一些变量需要解析和检查出价,则应将它们作为参数传递。如果检查失败无法阻止解析,那么您最好将检查器从解析器中分离出来。所以它看起来像:

try{
     Bids bids = BidParser.parse( bidsInput );
     BidChecker.check(bids, var1);
     Maps.update(bids, var2);
} catch (...){
}

概括:这样的设计很糟糕,因为它注入了BidParser类关于客户内部的知​​识,即紧密耦合应该避免,因为它是不可测试的并且导致可维护性差。除了通过参数传递之外,你的班级不应该了解它的任何客户。并且(在这个简短的例子中是过度的)控制反转(以及跟随依赖注入)的概念甚至更进一步追求松散耦合并产生更可测试和清洁的设计。

考虑SOLID principles of Object-Oriented Design。维基百科关于Don't Repeat Yourself的文章也链接到了另一个有用的原则,这些原则引入了某种编程哲学。