체스 상황을 모델링하기위한 작은 클래스 집합에서 위치를 나타내는 클래스를 만들고 싶습니다. 그러나 나는 올바른 64 개의 위치 만 만들고 (그리고 내보내기), 시스템이 같은 위치에 대해 여러 개의 객체를 생성하지 못하도록하기 위해 생성자를 비공개로 만들고 싶었습니다. 기본적으로 싱글 톤이지만 1 = 64입니다. 64 톤입니다. 거의.n-gleton 패턴을 사용하여 고유 한 n 개의 항목을 나타내고 (내보내는)?
가능한 사용 :
use Positions; # exports positions
my $pos = e4;
# something happens...
do_foo() if $pos == d5;
do_bar() if $pos->row == 8;
내 솔루션은 내가 원하는 방식으로 작동하지만 세련의 이상 디자인 종류를 느낀다.
기본 : 나는 위치를 인스턴스화하는 클래스 사용자가 모든 개체를 원하지 않기 때문에
package Position;
use Moo;
has column => (is => 'ro');
has row => (is => 'ro');
has name => (is => 'lazy');
sub _build_name {
my $self = shift;
return $self->column . $self->row;
}
sub to_string { shift->name }
# ...
은 isa
유효 열이나 행에 대한 에러 체크 없습니다. 이제 수출에 :
# prepare 64 positions
my %position;
foreach my $col ('a' .. 'h') {
foreach my $row (1 .. 8) {
# build
my $name = "$col$row";
my $pos = Cherl::Position->new(column => $col, row => $row);
# remember
$position{$name} = $pos;
}
}
# export
sub import {
my $class = shift;
my $caller = caller;
# magic!
no strict 'refs';
for my $name (sort keys %position) {
*{$caller . '::' . $name} = sub { $position{$name} };
}
}
# make it private
sub BUILDARGS {
my ($class, @args) = @_;
die 'private' unless +(caller 1)[0] eq __PACKAGE__;
return $class->SUPER::BUILDARGS(@args);
}
대안은 내가
이 column
들과 row
초 동안 에러 체크를 추가하고 두 위치의 이름은 true의 경우 반환 할 ==
연산자를 오버로드하는 것입니다 생각할 수있는 position을 적절하게 비교하는 것과 같습니다. 이 시나리오에서 동일한 위치에 많은 수의 객체를 작성하는 데 약간 겁이납니다. 그러나 이것은 초기 최적화 일 수 있습니다.
따라서이 클래스를 디자인하는 더 좋은 방법이 있다면 (Moo 사용) 문제가됩니다. 티아! :)
어쩌면 자바 프로그래밍의 여름이 지나치게 복잡해질 수도 있습니다. :/ – memowe