Повторное использование крупных компонент

rtyug
На сайте с 13.05.2009
Offline
263
430

я хотел спросить

вот например у меня есть модуль для комментариев, расчитано чтобы ставить комментарии в темах,

НО если я хочу сделать этот модуль почти похожим еще как минимум для 5 элементов (кроме тем), например комментарии в: фото, видео, приватные, групыы, и блоги....

т.е. один и тот код нужно использовать минимум 7 раз даже один и тот же КОД и более-менее сложный (перебор и т.д.)

как лучше написать? старатся писать все в кучу? или писать один и тот же большой код 10 раз?

кто как бы тут сделал?

ну вот:


package MyApp::Controller::comment;

use strict;
use warnings;
use parent 'Catalyst::Controller';
use HTML::Entities::Numbered;

use SQL::Abstract;

use POSIX qw(ceil floor);

=head1 NAME

MyApp::Controller::comment - Catalyst Controller

=head1 DESCRIPTION

Catalyst Controller.

=head1 METHODS

=cut

=head2 index

=cut

sub index : Path : Args(0) {
my ( $self, $c ) = @_;

$c->response->body('Matched MyApp::Controller::comment in comment.');
}

sub add : Local : Args(0) {
my ( $self, $c, $edit ) = @_;

$c->stash->{template} = 'edit_comment.tt';

my $method = $edit ? 'stash' : 'flash';

$c->request->params->{id_co_comment} ||= '';
$c->request->params->{text_cm} ||= '';
$c->request->params->{move_id_co} ||= '';
$c->request->params->{id_cm} ||= '';
$c->request->params->{hiden_g_cm} ||= '';

if ( !$c->user_exists() ) {

$c->$method->{error_no_user} = 1;
$c->response->redirect(
$c->uri_for(
'/view_content/' . $c->request->params->{id_co_comment}
)
) if ( !$edit );
$c->detach();

}

if ( !$c->request->params->{id_co_comment} ) {
$c->$method->{error_no_id_co_comment} = 1;
$c->response->redirect(
$c->uri_for(
'/view_content/' . $c->request->params->{id_co_comment}
)
) if ( !$edit );
$c->detach();
}

if (
length( $c->request->params->{text_cm} ) <
MyApp->config->{length}->{min_text_comment}
|| length( $c->request->params->{text_cm} ) >
MyApp->config->{length}->{max_text_comment} )
{

$c->$method->{no_add_comment_text} = 1;
$c->response->redirect(
$c->uri_for(
'/view_content/' . $c->request->params->{id_co_comment}
)
) if ( !$edit );
$c->detach();
}

my $f = $c->model('ExtraDBI')->new;

my ($loop_data) =
$c->forward( 'check_sql_comment', [ $f, $edit, undef, undef ] );

my $move_id_se;
if ( $edit
&& $c->request->params->{move_id_co} eq 'on'
&& $c->check_user_roles('moder_co') )
{

my $dbh = $c->model('DBI')->dbh;

my $sth = $dbh->prepare(
"SELECT id_se
FROM content
WHERE id_co = ?
LIMIT 1"
);
$sth->execute( $c->request->params->{id_co_comment} );
$move_id_se = $sth->fetchrow_hashref();
$sth->finish();

$f->no_sql->zero_die( 'no_move_id_se', $move_id_se->{id_se} );

}

if ( $f->error_valid ) {

# to error

my $out_bad = $f->out_bad;

foreach ( @{$out_bad} ) {
$c->$method->{$_} = 1;
}

if ($edit) {

$c->forward( 'edit', [ $c->request->params->{id_cm} ] );
}
else {
$c->$method->{text_cm_current} = $c->request->params->{text_cm};
$c->response->redirect(
$c->uri_for(
'/view_content/' . $c->request->params->{id_co_comment}
)
);

}
$c->detach();

}
else {

my $hash;
my $where;
my $type_sql;

$hash->{text_cm} = name2decimal( $c->request->params->{text_cm} );

if ($edit) {
$type_sql = 'update';
if ( $c->request->params->{id_co_comment}
&& $c->check_user_roles('moder_co') )
{
$hash->{id_co} = $c->request->params->{id_co_comment};
}

if ( $c->request->params->{move_id_co} eq 'on'
&& $c->check_user_roles('moder_co') )
{

$hash->{id_se} = $move_id_se->{id_se};
$hash->{id_co} = $c->request->params->{id_co_comment};
}

if ( $c->check_user_roles('moder_co') ) {

$hash->{hiden_g_cm} =
$c->request->params->{hiden_g_cm} eq 'on' ? 1 : 0;
}

$where->{id_cm} = $c->request->params->{id_cm};

}
else {

$type_sql = 'insert';

$hash->{id_co} = $loop_data->{id_co};
$hash->{id_se} = $loop_data->{id_se};
$hash->{id_un} = $c->user->{user}->{id};
$hash->{hiden_g_cm} = '0';
$hash->{created} = time;
$hash->{ip} = $c->request->address;
$hash->{forwarded} = $c->request->header('X-Forwarded-For');
$hash->{host} = $c->request->hostname;

}

my $sql = SQL::Abstract->new;

my ( $stmt, @bind ) = $sql->$type_sql( 'comment', $hash, $where );

my $dbh = $c->model('DBI')->dbh;
my $sth = $dbh->prepare($stmt);
$sth->execute(@bind);
$sth->finish();

my $lastid = $dbh->{mysql_insertid} unless ($edit);

if ( $loop_data->{email_sent} && !$edit ) {

$dbh->do(
qq{replace INTO sent_comment (id_co,
id_un)
VALUES (?,
?)},
undef, $loop_data->{id_co}, $hash->{id_un}
);

}

for ( MyApp->config->{new_comment}->{text_sent_email} ) {
s/__ID_CO__/$loop_data->{id_co}/g;
s/__ID_CM__/$lastid/g;
}

my $parent = $$;
my $child = fork();

if ( $$ == $parent ) {

# print "Parent: pid=$$;($parent)\n";

}
else {

eval {

my $sql_sent = 'SELECT t2.email_address
FROM sent_comment AS t1,
users AS t2
WHERE t1.id_un = t2.id
AND t1.id_co = ' . $loop_data->{id_co} . '
AND t2.active is null
AND t2.email_sent = 1
';

my $sth = $dbh->prepare($sql_sent);
$sth->execute();

while ( my $email = $sth->fetchrow_arrayref() ) {

$c->forward(
qw /MyApp::Controller::registration sent_email/,
[ MyApp->config->{new_comment}->{from_sent_email},
$email->[0],
MyApp->config->{new_comment}->{sub_sent_email},
MyApp->config->{new_comment}->{text_sent_email}
]
);

}

$sth->finish();

};
if (@!) {
print "error";

}

# kill("TERM", $child);

}

waitpid $child, 0;

#kill(TERM => $child) or warn "Can't kill child, because: $!\n";

if ( !$edit ) {
$c->response->redirect(
$c->uri_for(
'/view_content/'
. $loop_data->{id_co}
. '/end#comment-'
. $lastid
)
);
}
else {

#my $page = sprintf( '%.f', ( ( $where->{id_cm} + 1 / 10 ) )) if ($where->{id_cm} > 10);
my $page = ceil( $where->{id_cm} / 10 ) if ( $where->{id_cm} > 10 );

$page = '/' . $page;

$c->response->redirect(
$c->uri_for(
'/view_content/' . $loop_data->{id_co} . '' . $page
)
);
}

}

$c->detach();
}

sub edit_comment : Local : Args(2) {
my ( $self, $c, @args ) = @_;

$c->stash->{template} = 'edit_comment.tt';

if ( $args[0] !~ /^\d+$/ || $args[1] !~ /^\d+$/ || !$c->user_exists() ) {
$c->stash->{error_id_and_user} = 1;
$c->detach();
}

my $f = $c->model('ExtraDBI')->new;

my ($loop_data) =
$c->forward( 'check_sql_comment', [ $f, '1', '1', $args[0], $args[1] ] );

if ( $f->error_valid ) {

# to error
my $out_bad = $f->out_bad;
foreach ( @{$out_bad} ) {
$c->stash->{$_} = 1;
}
$c->detach();
}

if ($loop_data) {

$c->stash->{text_cm} = $loop_data->{text_cm};
$c->stash->{id_co} = $loop_data->{id_co};
$c->stash->{hiden_g_cm} = $loop_data->{hiden_g_cm};
$c->stash->{id_cm} = $loop_data->{id_cm};

}

$c->stash->{moder} = 1 if ( $c->check_user_roles('moder_co') );

$c->detach();

}
Спалил тему: Pokerstars вывод WMZ, etc на VISA 0% или SWIFT + Конверт USD/GBP,etc (net profit $0,5 млрд) (https://minfin.com.ua/blogs/94589307/115366/) Monobank - 50₴ на счет при рег. тут (https://clck.ru/DLX4r) | Номер SIP АТС Москва 7(495) - 0Ꝑ, 8(800) - 800Ꝑ/0Ꝑ (http://goo.gl/XOrCSn)
rtyug
На сайте с 13.05.2009
Offline
263
#1


sub edit2 : Local : Args(0) {
my ( $self, $c ) = @_;

$c->forward( 'add', ['1'] );

}

sub delete_comment : Local : Args(2) {
my ( $self, $c, @args ) = @_;

$c->stash->{template} = 'edit_comment.tt';

if ( $args[0] =~ /^\d+$/ && $c->user_exists() ) {

my $sql;

if ( !$c->check_user_roles('moder_co') ) {
$sql =
'AND created > '
. ( time - 86400 )
. ' AND id_un = '
. $c->user->{user}->{id};

}

my $dbh = $c->model('DBI')->dbh;

$dbh->do(
qq{DELETE FROM comment
WHERE id_cm = $args[0] $sql LIMIT 1},
undef
);
}

if ( $args[0] !~ /^\d+$/ || !$c->user_exists() ) {
$c->response->redirect( $c->uri_for('/') );
}
else {
$c->response->redirect( $c->uri_for( '/view_content/' . $args[1] ) );

}
$c->detach();

}


sub check_sql_comment : Privat {
my ( $self, $c, $f, $edit, $edit0, $id_cm_sql, $id_co_sql ) = @_;

# $edit0 - edit select comment

my $method = $edit ? 'stash' : 'flash';

my $dbh = $c->model('DBI')->dbh;

my $sql_comment = 'SELECT t1.id_co,
t1.id_se,
t1.id_un,
t1.forbi_comm_co,
t1.close_co,
t1.hiden_co,
t1.active_co,
t2.active_se,
t2.close_se,
t2.id_un AS id_un_se,
t3.email_sent
' . ( $edit0 ? ', t4.text_cm ' : '' ) . '
'
. ( $edit ? ', t4.id_cm, t4.created, t4.id_un AS id_un_cn' : '' ) . '
FROM content AS t1
LEFT JOIN section AS t2
ON t1.id_se = t2.id_se
LEFT JOIN users AS t3
ON t1.id_un = t3.id
' . (
$edit
? '
LEFT JOIN comment AS t4
ON t1.id_co = t4.id_co
AND t4.id_cm = ?
'
: ''
)
. '
WHERE t1.id_co = ?
LIMIT 1';

my @sql;
push @sql, $id_cm_sql ? $id_cm_sql : $c->request->params->{id_cm}
if ($edit);
push @sql, $id_co_sql ? $id_co_sql : $c->request->params->{id_co_comment};

my $sth = $dbh->prepare($sql_comment);
$sth->execute(@sql);
my $loop_data = $sth->fetchrow_hashref();
$sth->finish();

if ( !$loop_data->{id_co} ) {
$c->$method->{error_no_id_co} = 1;
$c->response->redirect(
$c->uri_for(
'/view_content/' . $c->request->params->{id_co_comment}
)
) if ( !$edit );
$c->detach();
}

if ($edit) {
if ( !$loop_data->{id_cm} ) {
$c->stash->{error_no_cm} = 1;
$c->detach();
}
if ( $loop_data->{id_un_cn} != $c->user->{user}->{id}
&& !$c->check_user_roles('moder_co') )
{
$c->stash->{error_no_id_un_cm} = 1;
$c->detach();
}

if ( $loop_data->{created} < time - 86400
&& !$c->check_user_roles('moder_co') )
{
$c->stash->{error_no_created} = 1;
$c->detach();
}

}

if ( !$c->check_user_roles('moder_co') ) {

$f->bad_fields_type('arrey');
$f->no_sql->zero_die( 'error_no_forbi_comm_co',
$loop_data->{forbi_comm_co} == 1
&& $loop_data->{id_un} != $c->user->{user}->{id} );
$f->no_sql->zero_die( 'error_no_hiden_co',
$loop_data->{hiden_co} == 1
&& $loop_data->{id_un} != $c->user->{user}->{id} );
$f->no_sql->zero_die( 'error_no_active_co',
$loop_data->{active_co} != 1
&& $loop_data->{id_un} != $c->user->{user}->{id} );
$f->no_sql->zero_die( 'error_no_active_se',
$loop_data->{active_se} != 1
&& $loop_data->{id_un_se} != $c->user->{user}->{id} );
$f->no_sql->zero_die( 'error_no_close_co',
$loop_data->{close_co} == 1 );

$f->no_sql->zero_die( 'no_edit_no_un_cn',
$loop_data->{id_un_cn} != $c->user->{user}->{id} )
if ($edit);

}

$f->no_sql->valid_id( 'error_no_id_co_comment',
$c->request->params->{id_co_comment} )
if ( !$edit0 );

return $loop_data if ($loop_data);
}

=head1 AUTHOR


Dmitriy

email: rtyug@ukr.net


=head1 LICENSE

This library is free software. You can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

1;

например, я не давно работал с одной программой где было все в куча нуписано на ORM, и разобратся все сложно

другими словами: есть 20 модулей которые связываються между собой и все как один модуль!! чтобы изменит например 3-4, то нужно все переписать или многие модули переписать, т.к. получается что нужно все 20 переписать из этого следует: просто все переписать или сделать все в кучу...

======

но вот я как раз читал где-то в списке рассылке, говорилось про недостатки DBIC, в том что все контроллеры должны быть не однородными!! т.е. в DBIC, можно крассиво написать код к 10 контроллерам, и может полуиться, так что нужно будет изменить программу! изменит 2 контроллера, а изменить не получиться, так как остальные 8 работать не будет, потому что они будут взаимосвязывающиеся ( все однородные ) и прейдется все 10 переписывать, вот лучше удалить все и написать заново…

я пожаловался и пришли они к выводу что надо все удалить, но там просто была программа не дописанная, правда...

=====

ну там есть много вариантов

http://search.cpan.org/~flora/Catalyst-Run...Type/Chained.pm


package MyApp::Controller::Greeting;
use base qw/ Catalyst::Controller /;

# this is the beginning of our chain
sub hello : PathPart('hello') Chained('/') CaptureArgs(1) {
my ( $self, $c, $integer ) = @_;
$c->stash->{ message } = "Hello ";
$c->stash->{ arg_sum } = $integer;
}

# this is our endpoint, because it has no :CaptureArgs
sub world : PathPart('world') Chained('hello') Args(1) {
my ( $self, $c, $integer ) = @_;
$c->stash->{ message } .= "World!";
$c->stash->{ arg_sum } += $integer;

$c->response->body( join "<br/>\n" =>
$c->stash->{ message }, $c->stash->{ arg_sum } );
}

вот я красиво диспатчизировал:


sub index_pages :Path('/last') : Args(1) {
my ( $self, $c, $id) = @_;

$c->stash->{template} = 'photo.tt';

$c->forward( 'last', [ $id, undef, undef, '1'] );
}

sub last : Local : Args(0) {
my ( $self, $c, $id ) = @_;

$c->stash->{template} = 'photo_album_privat.tt';

# if ( !$id_un || (!$c->user_exists() || $id_un != $c->user->{user}->{id}) && !$c->check_user_roles('moder_co') ) {
# $c->stash( no_user_privat => 1, off_photo => 1, );
# $c->detach();
# }

$c->forward( 'index', [ undef, undef, undef, '1'] );

}


sub privat : Local {
my ( $self, $c, $id_un, $id ) = @_;

$c->stash->{template} = 'photo_album_privat.tt';

if ( !$id_un || (!$c->user_exists() || $id_un != $c->user->{user}->{id}) && !$c->check_user_roles('moder_co') ) {
$c->stash( no_user_privat => 1, off_photo => 1, );
$c->detach();
}

$c->forward( 'index', [$id, '1', $id_un] );

}


sub index_pages :Path('/photo') : Args(1) {
my ( $self, $c, $id, $privat, $id_un ) = @_;

$c->stash->{template} = 'photo.tt';

$c->forward( 'index', [$id] );
}


sub index :Path : Args(0) {
my ( $self, $c, $id, $privat, $id_un, $last ) = @_;

$c->stash->{template} = 'photo.tt';


NZ
На сайте с 20.09.2009
Offline
12
#2

Если честно, я не понял Вас.

rtyug
На сайте с 13.05.2009
Offline
263
#3

как сделать парадигму, если парадигмы фремворка и парадигмы-парадигмов не хватает?

===

я хотел спросить, потому что:

я сталкивался с готовыми программами и про это обсуждалось в списках рассылки:

другими словами: есть 20 модулей которые связываються между собой и все как один модуль!! чтобы изменит например 3-4, то нужно все переписать или многие модули переписать, т.к. получается что нужно все 20 переписать из этого следует: просто все переписать или сделать все в кучу...

т.е. если парадигма очень не удобная!!! если стараться все связывать между собой...

как правильно писать? или все равно?

====

вот например у меня есть модуль для комментариев, расчитано чтобы ставить комментарии в темах,

НО если я хочу сделать этот модуль почти похожим еще как минимум для 5 элементов (кроме тем), например комментарии в: фото, видео, приватные, группы, и блоги....

т.е. один и тот код нужно использовать минимум 7 раз даже один и тот же КОД и более-менее сложный (перебор и т.д.)

как лучше написать? старатся писать все в кучу? или писать один и тот же большой код 10 раз?
кто как бы тут сделал?

или все равно?

N
На сайте с 16.02.2009
Offline
19
#4

Вам нужно использовать классы и их наследование. Таким образом, у Вас будет один главный класс, а остальные - его производные.

Здесь о теории.

Здесь о практике, пункт 6.8.5.

rtyug
На сайте с 13.05.2009
Offline
263
#5

я хотел про другое вообще-то....

я так понял что если писать большую програму, то в любом случае нужно писать все в кучю...!

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

N
На сайте с 16.02.2009
Offline
19
#6

Всё правильно, Вы создаёте базовый класс с общими функциями, а затем, по мере необходимости, расширяете базовый класс до нужного функционала.

А совсем без повторения кода Вам ну никак не обойтись :)

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий