Можно ли найти экземпляр объекта без его передачи в метод? - PullRequest
2 голосов
/ 28 февраля 2011

У меня есть класс синтаксического анализатора "MessageParser", который я передаю ему сообщение типа String для его анализа. Подпись метода разбора для класса

public void parse(String message);

Мне нужно передать ему экземпляр «Properties», но я не хочу менять сигнатуру метода, чтобы добавить к нему новый аргумент. Я боролся с этим последние пару дней и попробовал несколько вариантов - см. Отправка в объекте типа Object вместо String - Полиморфизм

Класс, который вызывает метод синтаксического анализа ParserManager, знает об объекте свойств. Есть ли способ для MessageParser найти объект свойств, не передавая ему?

Редактировать

Вот пример кода. Я хотел бы, чтобы «MessageCparser» обращался к объекту «prop» в «ParserManager», не меняя ничего в интерфейсе «Parser» или в классе «ParserManager». Это возможно?

public interface Parser{
    public void parse(String message);
}

public class MessageCParser implements Parser{
    public void parse(String message){
        MessageObject mobject = (MessageObject)message; 
        System.out.println("Parsing C" + mobject.getMessage());
    }

    public void parse(String m){}
}


import java.util.HashMap;

public class ParserManager{

Properties prop = null;

    public ParserManager() {
        prepare();
    prop = new Properties()
    }

    HashMap parsers = new HashMap();


    public void prepare(){

        parsers.put("A",new MessageCParser());

    }

    public void parseMessage(String msgType, String message){
        ((Parser)parsers.get(msgType)).parse(message);
    }
}

Спасибо

Ответы [ 3 ]

3 голосов
/ 28 февраля 2011

Наиболее очевидным решением было бы добавить ссылку на объект Properties как поле в ParserManager, а затем либо предоставить ParserManager объект свойств в качестве аргумента конструктора, либо через метод установки как показано ниже:

class ParserManager {
    ...
    Properties props;

    public void setParsingProperties(Properties props) {
        this.props = props;
    }

    public void parse(String message) {
        // props available here, without being passed as agurment.
    }
}

class CallingParserManager {
    ...
    void someMethod() {
        ...
        parserManager.setParsingProperties(propertiesToUse);
        parserManager.parse(theString);
        ...
    }
    ...
}

Глядя на ваш предыдущий вопрос, я бы сказал, что было бы хорошо, если бы вы добавили setParsingProperties в интерфейс Parser. Метод может быть реализован как пустой метод для тех анализаторов, которым не нужны свойства.


Относительно ваших правок: Нет, так решить невозможно.

MessageObject mobject = (MessageObject) message;

Будет работать только в том случае, если MessageObject является подтипом String (но поскольку String является окончательным (не может быть расширен), это не может иметь место).

Грязное быстрое исправление должно было бы проверить (с instanceof), является ли Parser экземпляром MessageCParser, и привести его к типу, а затем использовать MessageCParser специальный метод синтаксического анализа, который принимает Properties аргумент.

1 голос
/ 28 февраля 2011

Ну, в общем, есть четыре способа получения информации:

  • Это может быть частью состояния объекта, к которому вызывается метод (например, его можно передать конструктору).и затем сохраняется в поле)
  • Может быть параметром самого метода
  • Доступ к нему можно получить статически, например, через синглтон
  • К нему можно получить доступ черезлокальная переменная потока

Все это, конечно, можно использовать с косвенной направленностью - например, если что-то else , которое знает о Properties, доступно через одно из перечисленныхмеханизмы, тогда вы можете добраться до этого, а затем узнать о Properties.Но вы не можете просто найти вызывающий объект и спросить , что .

Что вам нужно сделать с рассматриваемым Properties?Будет ли Properties варьироваться в зависимости от вызова для одного и того же MessageParser?Если это так, то действительно должен быть параметром.Вы говорите, что не хотите изменять сигнатуру метода, но если вы хотите передать больше информации, это именно то, что вы должны сделать.

0 голосов
/ 28 февраля 2011

Если у вас есть только один экземпляр вашего объекта «Свойства», вы можете использовать что-то вроде Singleton pattern .

Вы также можете добавить ссылку на ParserManager где-то в вашем MessageParser, а затем вызвать метод в ParserManager, который вернет свойства, но без некоторых фрагментов кода невозможно помочь вам в этом.

...