Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Замена плейсхолдера на реальный класс


Автор: AlexKozlov 22.11.2011, 11:53
Предположим есть у меня некоторый класс, назначение которого иммитировать наличие чего-то реального, в то время как оно еще качается по сети, считается и т.д. Простейший пример - пусть есть класс EmptyPicture, который выводит пустой прямоугольник пока картинка грузится из инета. 

А хочется мне чтобы по завершении загрузки, объект этого класса подменил себя на объект класса PNGPicture (JPEGPicture, BMPPicture и т.п.). Естественно предполагается что все классы имеют общий интерфейс Picture, через который к ним и обращаются, так что никакого криминала при подмене не произойдет.

Чего не хочется: 
1) делать в каком либо виде адаптер, который по сути лишнее звено.
2) уведомлять все объекты имеющие ссылку на объект EmptyPicture, что им нужно ее поменять

В идеале должно быть что-то вроде

onLoadDone(Picture p){
  this=p; // Так к сожалению  не выходит
}

Возможно ли что то подобное? Или оно невозможно в принципе? Как-то сразу возникает мысль о проблемах с thread-safe

Автор: firedrago 22.11.2011, 12:54
в принцепе ничего не понял из вышенаписанного, но есть подозрение что Вам надо что-то типа
Код

public MainClass{
    private Picture p;

    public void showPic(){
        if(p==null){
            p = new EmptyPicture();
        }
        p.view();
   }

   public void onLoadDone(Picture p){
       this.p = p;
       showPic();
   }
}

Автор: Stolzen 22.11.2011, 12:57
Так есть же паттерн, который называется Lazy Initialization. Его еще в синглтоне применяют часто. Собственно проблемы с thread-safety оттуда распространяются и сюда, поэтому способы решения этих проблем тут так же применимы.
Можно написать прокси-класс, который будет как раз заниматься ленивой подгрузкой. Я так помимаю, именно этого вам делать и не хочется? Это не так уж и плохо, как кажется. В книге по паттернам у Фрименов, кстати, есть пример прокси, который обеспечивает ленирую загрузку фигуры.

Автор: firedrago 22.11.2011, 13:06
Stolzen, Lazy Initialization в моем понимании было всегда что-то типа
Lazy initialization means that you do not initialize objects until the first time they are used. Typically, this comes about when you are unsure of what initial value an instance variable might have but want to provide a default. Rather than initialize explicitly in the constructor (or class static initializer), it is left until access time for the variable to be initialized, using a test for null to determine if it has been initialized. For example:

public getSomething(  )
{
  if (something == null)
    something = defaultSomething(  );
  return something;
}


или я чего-то не знаю?

Автор: Stolzen 22.11.2011, 13:16
Цитата(firedrago @  22.11.2011,  13:54 Найти цитируемый пост)
    public void showPic(){
        if(p==null){
            p = new EmptyPicture();
        }
        p.view();
   }


Цитата(firedrago @  22.11.2011,  14:06 Найти цитируемый пост)
public getSomething(  )
{
  if (something == null)
    something = defaultSomething(  );
  return something;
}


Вам не кажется, что у этих кусков кода есть что-то общее? smile

Автор: firedrago 22.11.2011, 13:19
Stolzen,  smile  мы друг-друга поняли  smile 

Автор: AlexKozlov 22.11.2011, 15:01
firedrago,  поняли вы абсолютно правильно, но как раз именно от таких конструкций мне хочется отойти. На мой взгляд это получается слишком громоздко.


Автор: firedrago 22.11.2011, 15:26
AlexKozlov,   smile 
это правильное OOP с использованием интерфeйсов, наследования и т.д. все остальное - это изобретение велосипеда с квадратными колесами.....по крайней мере, это мое мнение

Автор: Stolzen 22.11.2011, 15:47
Цитата(firedrago @  22.11.2011,  16:26 Найти цитируемый пост)
это изобретение велосипеда с квадратными колесами.....по крайней мере, это мое мнение

Поддерживаю

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)