1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
| #!/usr/bin/env perl
use v5.36;
# --- 製品クラス(国内) ---
package DomesticPayment;
use v5.36;
use Moo;
has amount => (is => 'ro', required => 1);
sub process ($self) {
my $fee = int($self->amount * 0.03);
my $total = $self->amount + $fee;
say "【国内決済】金額: ¥" . $self->amount . " + 手数料: ¥$fee = 合計: ¥$total";
return $total;
}
package DomesticShipping;
use v5.36;
use Moo;
has address => (is => 'ro', required => 1);
sub ship ($self) {
say "【国内配送】お届け先: " . $self->address;
say " 配送業者: ヤマト運輸";
say " 配送日数: 1-2営業日";
return { carrier => 'yamato', days => 2 };
}
package DomesticNotification;
use v5.36;
use Moo;
has email => (is => 'ro', required => 1);
sub notify ($self, $order_id) {
say "【国内通知】$order_id の注文確認メールを送信";
say " 宛先: " . $self->email;
say " 言語: 日本語";
return 1;
}
# --- 製品クラス(海外) ---
package GlobalPayment;
use v5.36;
use Moo;
has amount => (is => 'ro', required => 1);
sub process ($self) {
my $fee = int($self->amount * 0.05);
my $total = $self->amount + $fee;
say "【海外決済】Amount: \$" . $self->amount . " + Fee: \$$fee = Total: \$$total";
return $total;
}
package GlobalShipping;
use v5.36;
use Moo;
has address => (is => 'ro', required => 1);
sub ship ($self) {
say "【海外配送】Delivery to: " . $self->address;
say " Carrier: FedEx International";
say " Estimated: 5-10 business days";
return { carrier => 'fedex', days => 10 };
}
package GlobalNotification;
use v5.36;
use Moo;
has email => (is => 'ro', required => 1);
sub notify ($self, $order_id) {
say "【海外通知】Order confirmation for $order_id sent";
say " To: " . $self->email;
say " Language: English";
return 1;
}
# --- 製品クラス(EU) ---
package EUPayment;
use v5.36;
use Moo;
has amount => (is => 'ro', required => 1);
sub process ($self) {
my $fee = int($self->amount * 0.04);
my $total = $self->amount + $fee;
say "【EU決済】Montant: €" . $self->amount . " + Frais: €$fee = Total: €$total";
return $total;
}
package EUShipping;
use v5.36;
use Moo;
has address => (is => 'ro', required => 1);
sub ship ($self) {
say "【EU配送】Livraison à: " . $self->address;
say " Transporteur: DHL Express";
say " Délai estimé: 3-5 jours ouvrés";
return { carrier => 'dhl', days => 5 };
}
package EUNotification;
use v5.36;
use Moo;
has email => (is => 'ro', required => 1);
sub notify ($self, $order_id) {
say "【EU通知】Confirmation de commande $order_id envoyée";
say " Destinataire: " . $self->email;
say " Langue: Français";
return 1;
}
# --- 抽象Factoryロール ---
package OrderFlowFactory;
use v5.36;
use Moo::Role;
requires 'create_payment';
requires 'create_shipping';
requires 'create_notification';
# --- 国内向けFactory ---
package DomesticOrderFlowFactory;
use v5.36;
use Moo;
with 'OrderFlowFactory';
sub create_payment ($self, %args) { DomesticPayment->new(%args) }
sub create_shipping ($self, %args) { DomesticShipping->new(%args) }
sub create_notification ($self, %args) { DomesticNotification->new(%args) }
# --- 海外向けFactory ---
package GlobalOrderFlowFactory;
use v5.36;
use Moo;
with 'OrderFlowFactory';
sub create_payment ($self, %args) { GlobalPayment->new(%args) }
sub create_shipping ($self, %args) { GlobalShipping->new(%args) }
sub create_notification ($self, %args) { GlobalNotification->new(%args) }
# --- EU向けFactory(新規追加) ---
package EUOrderFlowFactory;
use v5.36;
use Moo;
with 'OrderFlowFactory';
sub create_payment ($self, %args) { EUPayment->new(%args) }
sub create_shipping ($self, %args) { EUShipping->new(%args) }
sub create_notification ($self, %args) { EUNotification->new(%args) }
# --- OrderProcessor(変更なし) ---
package OrderProcessor;
use v5.36;
use Moo;
has factory => (is => 'ro', required => 1);
sub process ($self, $order_id, $amount, $address, $email) {
say "=" x 50;
say "注文処理開始: $order_id";
say "=" x 50;
my $payment = $self->factory->create_payment(amount => $amount);
my $shipping = $self->factory->create_shipping(address => $address);
my $notification = $self->factory->create_notification(email => $email);
my $total = $payment->process;
say "";
my $delivery_info = $shipping->ship;
say "";
$notification->notify($order_id);
say "";
say "=" x 50;
say "注文処理完了";
say "=" x 50;
say "";
return { total => $total, delivery_info => $delivery_info };
}
# --- メイン処理 ---
package main;
use v5.36;
# 3市場の一覧
my %factories = (
domestic => DomesticOrderFlowFactory->new,
global => GlobalOrderFlowFactory->new,
eu => EUOrderFlowFactory->new,
);
# 各市場の注文を処理
for my $market (qw(domestic global eu)) {
my $processor = OrderProcessor->new(factory => $factories{$market});
$processor->process(
"ORD-$market-001",
1000,
"Address for $market",
"$market\@example.com"
);
}
|