Как я могу динамически вызывать объект в Perl Moose OOP? - PullRequest
3 голосов
/ 17 декабря 2008

Вот классическая модель объекта:

 class ViewBase
 {
  void DoSomethingForView() { } //May be virtual
 }

 class View1 : ViewBase //(derived class from ViewBase)
 {
    void DoSomethingForView() { }
    void DoSomethingForView1Special() { }
 }

 class View2: ViewBase //(another derived class from ViewBase)
 {
    void DoSomethingForView2Special() { }
 }

 class Application
 {
    void Print() { }
    void DoSomething() { }

     //Do some magic to create a view object (View1 or View2) and return

    //Something which I don't know to describe. Its like dynamically 
    //returning object of View1 or View2 at runtime
  }

Я хочу преобразовать это в модель класса Perl Moose.

Так что,

Я буду называть методы просмотра как

void Main()
{

  App = new Application();

  App->View1->DoSomethingForView(); 
  App->View1->DoSomethingForView1Special();
  App->View2->DoSomethingForView(); 
  App->View2->DoSomethingForView2Special();

}

Я не буду знать, какой вид будет вызываться. Но во время выполнения должен быть создан экземпляр View1 / View2 и должен быть вызван DoSomethingForView ().

Приведенный выше код не совсем Perl. Как перевести и добиться этого в Perl.

Объект Application должен иметь объект View, но мы не будем знать тип представления во время компиляции. У нас есть тестовое приложение, разработка на Perl.

Вы можете представить, что Приложение - это приложение с графическим интерфейсом, а View - это то, что вы видите в окне приложения. Пользователь может выбрать любой вид.

Прошу прощения за мой английский. Пожалуйста, дайте мне знать, если мне нужно предоставить больше текста.

Ответы [ 2 ]

3 голосов
/ 18 декабря 2008

Так что это дает вам примерно эквивалентный синтаксис в Perl. Это не поможет вам с некоторыми из ваших противоречивых критериев.

Обратите внимание на следующее:

  • класс ABC {...} заменяется синтаксическим пакетом perl ABC;
  • Заглавные имена методов в верблюжьем корпусе превращаются в правильный perl "case-snake-case".
  • Приложение было превращено в сиг-приложение $ 101 * *

Это было проверено на Moose v62, Perl 5.10. Вторая из последней строки завершится неудачей, поскольку do_something_for_view не реализован классом View2. Поскольку вы звоните конкретно view1 или view2, я не вижу приложения, которое, по вашему мнению, указывает на полиморфизм.

package ViewBase;

sub do_something_for_view { 
    Carp::croak "ViewBase::do_something_for_view is ABSTRACT!"; 
}

package View1;
use Moose;
extends 'ViewBase';

sub do_something_for_view { print "Doing something for View1.\n"; }
sub do_something_for_view1_special { print "Doing something SPECIAL for View1.\n"; }

package View2;
use Moose;
extends 'ViewBase';

sub do_something_for_view2_special() { print "Doing something SPECIAL for View2.\n"; }

package Application;
use Moose;

has view1 => ( 
      is      => 'rw'       # read/write
    , isa     => 'View1'
    , lazy    => 1
    , default => sub { View1->new(); } 
    );

has view2 => ( 
      is      => 'rw'       # read/write
    , isa     => 'View2'
    , lazy    => 1
    , default => sub { View2->new(); } 
    );

sub print {}
sub do_something {}

#void Main()
#{

package main;

  #App = new Application();
my $App = Application->new();

  #App->View1->DoSomethingForView(); 
$App->view1->do_something_for_view();
  #App->View1->DoSomethingForView1Special();
$App->view1->do_something_for_view1_special();
  #App->View2->DoSomethingForView(); 
$App->view2->do_something_for_view();
  #App->View2->DoSomethingForView2Special();
$App->view2->do_something_for_view2_special();

#}
2 голосов
/ 13 апреля 2010

Если вы используете MooseX :: Declare , вы можете упростить синтаксис до того, что вы написали, например, ваши объявления превратятся в:

use MooseX::Declare;
 class ViewBase {
  method DoSomethingForView() { } #May be virtual
 }

 class View1 extends ViewBase {
    method DoSomethingForView() { }
    method DoSomethingForView1Special() { }
 }

 class View2 extends ViewBase {
    method DoSomethingForView2Special() { }
 }

 class Application {
    method Print() { }
    method DoSomething() { }

     #Do some magic to create a view object (View1 or View2) and return

    #Something which I don't know to describe. Its like dynamically 
    #returning object of View1 or View2 at runtime
  }
...