Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как правильно передавать переменные в объекты? 
:(
    Опции темы
Infod
Дата 31.3.2007, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 31.3.2007

Репутация: нет
Всего: нет



Есть класс MainClass.pm

создаем объект
$main = new MainClass;

присваиваем объекту константу
$main->{myconst} = "Something";

В главном пакете есть много разных подпакетов вида 
MainClass::SubClass1
MainClass::SubClass2

объекты создаются вида:
$main->{obj1} = new MainClass::SubClass1;

также есть вида:
MainClass::SubClass1::SubSubClass1

и есть класс MainClass::Uni::LWP.pm

так вот, этот универсальный класс используется многими другими подклассами.
и при создании объекта
$ua = new MainClass::Uni::LWP;

в него нужно передать константу $main->{myconst} из главного класса

Как это сделать, если объект LWP создается во всех классах?
Пока приходят в голову глобальные переменные (фи smile ) или передавать эту константу при создании объектов - но это муторно

Помогите плз, я не очень силен в ООП, подозреваю, что ответ должен быть простой
Сорри, если сумбурно

Спасибо
PM MAIL   Вверх
Nab
Дата 31.3.2007, 17:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 25.3.2006
Где: Kiev

Репутация: 26
Всего: 37



У меня реализован такой механизм.
Так как весь основной функционал реализуется через методы ядра, и плагины добавляют объекту ядра дополнительный функционал тоже в виде методов, то объект ядра у меня сквозной: передаеться как параметр всем объектам - плагинам при создании и доступен из любой точки приложения.
Код

$main->{obj1} = MainClass::SubClass1->new($main);
# в методе new MainClass::SubClass1
package MainClass::SubClass1;
use Scalar::Util;
sub new {
    $class = shift;
    bless $self, $class;
    $self->{'main'} = shift;

    Scalar::Util::weaken( $self->{'main'} )
        if ref $self->{'main'};    # weaken circular reference

    $self->{'ua'} = MainClass::Uni::LWP->new($self->{'main'}->{myconst});
}

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


--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
Infod
Дата 31.3.2007, 19:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 31.3.2007

Репутация: нет
Всего: нет



Цитата

Так как весь основной функционал реализуется через методы ядра, и плагины добавляют объекту ядра дополнительный функционал тоже в виде методов, то объект ядра у меня сквозной: передаеться как параметр всем объектам - плагинам при создании и доступен из любой точки приложения.
Выделить всё


А есть ли более красивые способы? И сильно ли повлияет передача объекта во все другие объекты на использование памяти и быстродействие?

Цитата

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


Я так и делаю, в примере для простоты написал
PM MAIL   Вверх
Nab
Дата 31.3.2007, 19:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 25.3.2006
Где: Kiev

Репутация: 26
Всего: 37



Цитата(Infod @  31.3.2007,  19:35 Найти цитируемый пост)
А есть ли более красивые способы? И сильно ли повлияет передача объекта во все другие объекты на использование памяти и быстродействие?

Передается не объект а ссылка на него... а она у вас будет так или иначе передаваться, не важно каким способом вы получите доступ к нужному параметру... А вообще, это зависит от изначальной архитектуры приложения, если основной способ передачи параметров другой, то делайте пожалуй однотипно, чтоб самому не путаться потом...


--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
korob2001
Дата 31.3.2007, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 31
Всего: 61



Цитата

так вот, этот универсальный класс используется многими другими подклассами.
и при создании объекта
$ua = new MainClass::Uni::LWP;

в него нужно передать константу $main->{myconst} из главного класса

Можно попробовать, в основном классе. Создать поле, в котором и будет храниться уже созданный объект класса MainClass::Uni::LWP. Создавать этот объект можно в конструкторе основного класса. Затем создать метод, который будет при необходимости возвращать уже готовый объект, всем подклассам, которые его используют или наследуют от него.
В итоге у нас в памяти будет только один объект, с которым и будут работать все подклассы и наш основной класс. Разумеется такой подход не всегда уместен, но если при создании объекта используются одни и те же данные, то он вполне оправдан.

Хотя возможно я не совсем понял условие задачи. 

Это сообщение отредактировал(а) korob2001 - 31.3.2007, 20:09


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
Infod
Дата 31.3.2007, 20:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 31.3.2007

Репутация: нет
Всего: нет



Цитата

Можно попробовать, в основном классе. Создать поле, в котором и будет храниться уже созданный объект класса MainClass::Uni::LWP. Создавать этот объект можно в конструкторе основного класса. Затем создать метод, который будет при необходимости возвращать уже готовый объект, всем подклассам, которые его используют или наследуют от него.


Об этом я тоже сразу подумал, правда мне совсем не понятно, как это реализовать.  smile 

Набросал пример, если не трудно, можете пояснить на этом коде?

Код


use MainClass;

my $obj = new MainClass;
$obj->{my_constant} = "some_value";

$obj->

package MainClass;

sub new  { ... }

  sub main_func  {
     my $main = new MainClass::SubClass1;
     $main->process_task;
  }

# Вот такой "универсальный" метод создавать?
sub ua  {
  my ($self) = shift;
  my $ua = new MainClass::Uni::LWP(my_const => $self->{my_constant});

  return $ua;
}

package MainClass::SubClass1  {
  sub new { ... }

  sub process_task  {
    my $self = shift;

    my $process = new MainClass::SubClass2;
  }
}

package MainClass::SubClass2  {
  sub new { ... }

  sub parse_page  {
    my $self = shift;
    
    my $ua = new MainClass::Uni::LWP;  # Вот как сюда передать константу?
  }
}



т.е. не понятно, как созданным объектам получить доступ к объекту $obj. Или я создаю их неправильно?
PM MAIL   Вверх
nitr
Дата 31.3.2007, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 37
Всего: 84



Цитата(Nab @  31.3.2007,  17:42 Найти цитируемый пост)
И еще, как правило напрямую к объекту как к хешу не стоит обращаться, нужно реализовать доступ к свойствам через методы, тогда контролировать легче будет кто где и чего изменяет...

сказано... 


--------------------
PM   Вверх
tishaishii
Дата 31.3.2007, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Создатель
***


Профиль
Группа: Завсегдатай
Сообщений: 1262
Регистрация: 14.2.2006
Где: Москва

Репутация: 4
Всего: 8



Как получится - так и "правильно".

Это сообщение отредактировал(а) tishaishii - 31.3.2007, 22:02
PM MAIL ICQ Skype   Вверх
korob2001
Дата 31.3.2007, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 31
Всего: 61



Ну так через конструкторы и передавай свою константу:
Код

my $obj = new MainClass(my_const => "Bla, bla, bla");


package MainClass;

sub new  {
    my $check = shift;
    my $class = ref($check) ||  $check;
    my $self = {
        my_const => "default_value", @_
    };
    return bless($self, $class);
}

sub main_func  {
     my $main = new MainClass::SubClass1(my_const => $self->{my_const});  # Передаём константу дальше
     $main->process_task;
}

sub ua  {
  my ($self) = shift;
  my $ua = new MainClass::Uni::LWP(my_const => $self->{my_constant});

  return $ua;
}

package MainClass::SubClass1  {
  sub new {
      my $check = shift;
      my $class = ref($check) ||  $check;
      my $self = {
          my_const => "default_value", @_
      };
      return bless($self, $class);
  }

  sub process_task  {
    my $self = shift;

    my $process = new MainClass::SubClass2(my_const => $self->{my_const}); # Передаём константу дальше
  }
}

package MainClass::SubClass2  {
  sub new {
      my $check = shift;
      my $class = ref($check) ||  $check;
      my $self = {
          my_const => "default_value", @_
      };
      return bless($self, $class);
  }

  sub parse_page  {
    my $self = shift;
    
    my $ua = new MainClass::Uni::LWP($self->{my_const});  # Вот как сюда передать константу? ( Передаём константу ещё дальше).
  }
}

Константу мы передали до места назначения, но код этот глюковатый. Так как над ним можно, а главное нужно, хорошенько подумать. Для этого либо тебе нужно чётко изложить, цель всего, что написано выше, либо перейти на примеры попроще.

Ты помоему сильно увлекаешься созданием методов-фабрик, т.е. в методе ты создаешь новый объект. Вот здесь например:
Код

sub main_func  {
     my $main = new MainClass::SubClass1(my_const => $self->{my_const});  # Передаём константу дальше
     $main->process_task;
}

sub ua  {
  my ($self) = shift;
  my $ua = new MainClass::Uni::LWP(my_const => $self->{my_constant});

  return $ua;
}

Перед тем как создавать такую фабрику объектов, нужно подумать:
А действительно нужно создавать новый объект при каждом вызове метода main_func() или ua()? Или же можно создать этот объект один раз, в конструкторе или методе INIT, при созданнии текущего объекта, сохранить её в тот же анонимный хеш и пользоваться этой ссылкой везде, где объект не обязательно должен быть новым?


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
Infod
Дата 31.3.2007, 23:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 31.3.2007

Репутация: нет
Всего: нет



Цитата

Ну так через конструкторы и передавай свою константу:


Это ж неудобно. А если констант или переменных несколько, и каждому объекту нужны не все они? Передавать хеш с параметрами не предлагать smile

Цитата

А действительно нужно создавать новый объект при каждом вызове метода main_func() или ua()?


Это я в примере написал, чтобы показать, насколько бывает неудобно таскать эту константу по объектам. smile 

А цель у меня была - понять, как лучше всего обмениваться параметрами между объектами.
Значит только передавать ссылку на главный объект или передавать каждому объекту нужные параметры через конструктор?
PM MAIL   Вверх
korob2001
Дата 1.4.2007, 04:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 31
Всего: 61



В принципе, можно передавать не только число или строку, можно создатьвать объект любого класса и передать его, твоему классу. Главное что бы твой класс был готов корректно работать с этим объектом. Как класс это будет делать, конечного программиста, использующего его, вообще не должно волновать. Он читает документацию, изучает интерфейс класса и работает с его открытыми методами и полями.

Так же не стоит забывать о наследовании, если ответ на вопрос: "Является?", положительный. Например:
Пудель, является Собакой? Да. Значит класс Pudel может быть подклассом класса Dog.
Собака, является Животным? Да. Значит класс Dog может быть подклассом класса Animal.


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0528 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.