Мне было интересно, следует ли считать неправильную практику вызовом метода внешнего класса во внутреннем классе, а затем использовать внутренний метод класса во внешнем классе.
В этом случае: В BidParser я вызываю метод updateMaps(), который принадлежит внешнему классу. Кроме того, я вызываю в BidParser методы второго внутреннего класса InputSanityChecker.
Это плохая практика и анти-шаблон? Я создаю объект Бога здесь? (Больше функций, чтобы следовать в других внешних классах)
EDIT: У меня есть две переменные 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
}
}
}
Это не циклическая ссылка. Все классы - внешние и вложенные статические - должны быть одинаково независимыми от компилятора. И хотя вы вызываете статические методы, ссылок на экземпляры нет.
Эта конструкция нарушает принцип единой ответственности: BidParser
должен нести ответственность за синтаксические ставки и все. Т.е. этот класс должен принимать входной сигнал - даже не File
, просто Reader
, - и производить некоторый Bids
объект, который он должен вернуться к абоненту.
Тогда ответственность абонент 1) подготовить материалы в виде любого Reader
и 2) принять произведенный Bids
объект и сделать что - то с ним. Reader может быть экземпляром FileReader, BufferedReader, StringReader и т.д. См. Java IO Documentation
Кроме того, этот дизайн нарушает принцип " Не повторяй сам". Вы можете увидеть дубликат кода в BidParser
. Это нарушение будет исправлено автоматически, как только вы создадите класс для работы только с более абстрактным вводом.
Учитывая InputChecker
, если каждый элемент проверен inpedendently из других, этот класс должен отвечать за проверку только одного проверяемого фрагмента (элемента) за раз. И должен быть обязанностью парсера перебирать элементы и при необходимости обращаться к InputChecker
.
Если во внешнем классе есть некоторые переменные, которые необходимы для анализа и проверки ставок, вы должны передать их в качестве аргументов. Если неудачная проверка не может предотвратить синтаксический анализ, то лучше всего выберете контролер из парсера. Так выглядит:
try{
Bids bids = BidParser.parse( bidsInput );
BidChecker.check(bids, var1);
Maps.update(bids, var2);
} catch (...){
}
Обобщить: такой дизайн плохой, потому что он вводит BidParser
класса BidParser
о внутренних компонентах своих клиентов, т. BidParser
связь, которую следует избегать, поскольку она не тестируется и ведет к плохой ремонтопригодности. Ваш класс не должен знать о нем других клиентов, кроме переданных через аргументы. И (что является излишним в этом кратком примере) концепция инверсии управления (и последующая инъекция зависимостей) идет еще дальше в стремлении к свободному соединению и созданию более проверяемого и чистого дизайна.
Рассмотрим SOLID принципы объектно-ориентированного проектирования. Также статья Википедии " Не повторяйте сами ссылки на другие полезные принципы, которые вводят какую-то философию программирования".
static
. внутренние классы или неstatic
; они являются внутренними классами, потому что у них есть ссылка на экземпляр внешнего класса, с которым они созданы.checkInput(elems);
из BidParser недействителен (выдаст ошибку компилятора). Это должен бытьInputSanityChecker.checkInput(elems);