演習問題6(レジ)
演習問題6-3 (Memento)
レジで会計しているときに、買い忘れを思い出すこともあると思います。だからといって、レジの会計を止めて(後に並んでいる人を待たせて)買い忘れを取りに行ってくるということはできません。
そのため、レジの処理を一時中断して、後の人の会計を先に済ませて、その後レジの処理を再開できるようにします。
そこで、一時中断したレジの処理を保存(store メソッド)し、再開後その続きができるように保存した情報を復元(restore メソッド)できるように Register クラスを修正してください。また、保存する仕組みとして Memento クラスも作成してください。
実行結果
お買い上げ日時 2020-09-23 12:30:00
合計金額 2,560円
お買い上げ日時 2020-09-23 12:30:00
大根 125円 1個
豚肉 245円 250g
レタス 147円 1個
トマト 276円 4個
鶏肉 156円 200g
合計金額 949円
コード
Enshu603.java
public class Enshu603 {
public static void main(String[] args ) {
Register reg = new Register ();
Cart cart1 = new Cart ();
cart1 .add(new Vegetable ("大根", 125, 1));
cart1 .add(new Meat ("豚肉", 98, 250));
cart1 .add(new Vegetable ("レタス", 147, 1));
cart1 .add(new Vegetable ("トマト", 69, 4));
reg .accept(cart1 );
reg .append(new CmdPurchaseTime ());
reg .append(new CmdAccount ());
reg .append(new CmdTotalPrice ());
Memento mm = reg .store();
// 処理中断 --------------------
// 別処理
Cart cart2 = new Cart ();
cart2 .add(new Meat ("牛肉", 395, 400));
cart2 .add(new Vegetable ("じゃがいも", 98, 10));
reg .accept(cart2 );
reg .append(new CmdPurchaseTime ());
reg .append(new CmdTotalPrice ());
reg .execute(); // 会計(表示)
// 処理再開 --------------------
reg .restore(mm );
cart1 .add(new Meat ("鶏肉", 78, 200)); // 買い忘れ 購入
reg .execute(); // 会計(表示)
}
}
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
なお、オブジェクト型の代入は参照のコピーです。元の情報を書き換えると保存した情報も変わってしまいますので注意してください。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.java
public class Memento {
private Cart cart = null;
private Vector <Command > cmds = null;
private int totalPrice = 0;
public Memento (Cart cart , Vector <Command > cmds , int totalPrice ) {
}
public Cart getCart() {
return cart ;
}
public Vector <Command > getCommmand() {
return cmds ;
}
public int getTotalPrice() {
return totalPrice ;
}
}
解答
Register.java
public class Register {
private Cart cart ;
private Vector <Command > cmds = new Vector <Command >();
private int totalPrice = 0;
private StringBuilder info = new StringBuilder ();
public Register () {}
public void accept(Cart cart ) {
this.cart = cart ;
cmds .clear();
totalPrice = 0;
info .delete(0, info .length());
}
public void append(Command cmd ) {
cmd .cart = this.cart ;
cmd .register = this;
cmds .add(cmd );
}
public void execute() {
for(Command cmd : cmds ) {
cmd .execute();
}
System.out.println(info );
System.out.println();
}
public void setTotalPrice(int totalPrice ) {
this.totalPrice = totalPrice ;
}
public int getTotalPrice() {
return totalPrice ;
}
public void appendInfo(String info ) {
this.info .append(info );
}
public Memento store() {
return new Memento (cart , cmds , totalPrice );
}
public void restore(Memento mm ) {
cart = mm .getCart();
cmds = mm .getCommmand();
totalPrice = mm .getTotalPrice();
info .delete(0, info .length());
}
}
Memento.java
public class Memento {
private Cart cart = null;
private Vector <Command > cmds = null;
private int totalPrice = 0;
public Memento (Cart cart , Vector <Command > cmds , int totalPrice ) {
this.cart = cart ;
this.cmds = new Vector <Command >();
for (Command cmd : cmds ) {
this.cmds .add(cmd );
}
this.totalPrice = totalPrice ;
}
public Cart getCart() {
return cart ;
}
public Vector <Command > getCommmand() {
return cmds ;
}
public int getTotalPrice() {
return totalPrice ;
}
}
Enshu603.cpp
#include <iostream>
using namespace std;
#include "Register.h"
#include "Vegetable.h"
#include "Meat.h"
#include "CmdPurchaseTime.h"
#include "CmdAccount.h"
#include "CmdTotalPrice.h"
int main()
{
Register reg ;
Cart * cart1 = new Cart ();
cart1 ->add(new Vegetable ("大根", 125, 1));
cart1 ->add(new Meat ("豚肉", 98, 250));
cart1 ->add(new Vegetable ("レタス", 147, 1));
cart1 ->add(new Vegetable ("トマト", 69, 4));
reg .accept(cart1 );
reg .append(new CmdPurchaseTime ());
reg .append(new CmdAccount ());
reg .append(new CmdTotalPrice ());
Memento * mm = reg .store();
// 処理中断 --------------------
// 別処理
Cart * cart2 = new Cart ();
cart2 ->add(new Meat ("牛肉", 395, 400));
cart2 ->add(new Vegetable ("じゃがいも", 98, 10));
reg .accept(cart2 );
reg .append(new CmdPurchaseTime ());
reg .append(new CmdTotalPrice ());
reg .execute(); // 会計(表示)
// 処理再開 --------------------
reg .restore(mm );
cart1 ->add(new Meat ("鶏肉", 78, 200)); // 買い忘れ 購入
reg .execute(); // 会計(表示)
delete cart1 , cart2 , mm ;
}
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.h
#include <vector>
#include "Cart.h"
class Command ;
class Memento
{
private:
Cart * cart ;
std::vector <Command *> cmds ;
int totalPrice = 0;
public:
Memento(void);
Memento(Cart *, std::vector <Command *>, int);
virtual ~Memento(void);
Cart * getCart(void);
std::vector <Command *>& getCommands(void);
int getTotalPrice(void);
};
Memento.cpp
#include <iostream>
using namespace std;
#include "Memento.h"
Memento::Memento(void) {}
Memento::Memento(Cart * cart , vector <Command *> cmds )
{
}
Memento::~Memento(void) {}
Cart * Memento::getCart(void)
{
return cart ;
}
vector <Command *>& Memento::getCommands(void)
{
return cmds ;
}
int Memento::getTotalPrice(void)
{
return totalPrice ;
}
解答
Register.h
#include <vector>
#include "Cart.h"
class Command ;
class Register
{
private:
Cart * cart ;
std::vector <Command *> cmds ;
int totalPrice = 0;
std::string info ;
Memento * mm = NULL;
public:
Register(void);
virtual ~Register(void);
void accept(Cart *);
void append(Command *);
void execute(void);
void setTotalPrice(int);
int getTotalPrice(void);
void appendInfo(std::string);
Memento * store(void);
void restore(Memento *);
};
Register.cpp
#include <iostream>
using namespace std;
#include "Register.h"
#include "Command.h"
Register::Register(void): cart (NULL) {}
Register::~Register(void)
{
for (Command * cmd : cmds )
{
delete cmd ;
}
}
void Register::accept(Cart * cart )
{
this->cart = cart ;
cmds .clear();
info = "";
totalPrice = 0;
}
void Register::append(Command * cmd )
{
cmd ->cart = this->cart ;
cmd ->reg = this;
cmds .push_back(cmd );
}
void Register::execute()
{
for (Command * cmd : cmds )
{
cmd ->execute();
}
cout << info << "\n";
}
void Register::setTotalPrice(int totalPrice )
{
this->totalPrice = totalPrice ;
}
int Register::getTotalPrice()
{
return totalPrice ;
}
void Register::appendInfo(string info )
{
this->info .append(info );
}
Memento * Register::store(void)
{
return new Memento (cart , cmds , totalPrice );
}
void Register::restore(Memento * mm )
{
cart = mm ->getCart();
cmds = mm ->getCommands();
totalPrice = mm ->getTotalPrice();
info = "";
}
Memento.h
#include <vector>
#include "Cart.h"
class Command ;
class Memento
{
private:
Cart * cart ;
std::vector <Command *> cmds ;
int totalPrice = 0;
public:
Memento(void);
Memento(Cart *, std::vector <Command *>, int);
virtual ~Memento(void);
Cart * getCart(void);
std::vector <Command *>& getCommands(void);
int getTotalPrice(void);
};
Memento.cpp
#include <iostream>
using namespace std;
#include "Memento.h"
Memento::Memento(void) {}
Memento::Memento(Cart * cart , vector <Command *> cmds , int totalPrice )
: cart (cart ), cmds (cmds ), totalPrice (totalPrice ) {}
Memento::~Memento(void) {}
Cart * Memento::getCart(void)
{
return cart ;
}
vector <Command *>& Memento::getCommands(void)
{
return cmds ;
}
int Memento::getTotalPrice(void)
{
return totalPrice ;
}
Enshu603.cs
class Enshu602
{
static void Main()
{
Register reg = new Register ();
Cart cart1 = new Cart ();
cart1 .add(new Vegetable ("大根", 125, 1));
cart1 .add(new Meat ("豚肉", 98, 250));
cart1 .add(new Vegetable ("レタス", 147, 1));
cart1 .add(new Vegetable ("トマト", 69, 4));
reg .accept(cart1 );
reg .append(new CmdPurchaseTime ());
reg .append(new CmdAccount ());
reg .append(new CmdTotalPrice ());
Memento mm = reg .store();
// 処理中断 --------------------
// 別処理
Cart cart2 = new Cart ();
cart2 .add(new Meat ("牛肉", 395, 400));
cart2 .add(new Vegetable ("じゃがいも", 98, 10));
reg .accept(cart2 );
reg .append(new CmdPurchaseTime ());
reg .append(new CmdTotalPrice ());
reg .execute(); // 会計(表示)
// 処理再開 --------------------
reg .restore(mm );
cart1 .add(new Meat ("鶏肉", 78, 200)); // 買い忘れ 購入
reg .execute(); // 会計(表示)
}
}
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
なお、オブジェクト型の代入は参照のコピーです。元の情報を書き換えると保存した情報も変わってしまいますので注意してください。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.cs
public class Memento
{
private Cart cart = null;
private List <Command > cmds = null;
private int totalPrice = 0;
public Memento(Cart cart, List <Command > cmds, int totalPrice)
{
}
public Cart getCart()
{
return cart ;
}
public List <Command > getCommmand()
{
return cmds ;
}
public int getTotalPrice()
{
return totalPrice ;
}
}
解答
Register.cs
public class Register
{
private Cart cart ;
private List <Command > cmds = new List <Command >();
private int totalPrice = 0;
private StringBuilder info = new StringBuilder ();
public Register () {}
public void accept(Cart cart )
{
this.cart = cart ;
cmds .Clear();
info .Clear();
totalPrice = 0;
}
public void append(Command cmd )
{
cmd .cart = this.cart ;
cmd .register = this;
cmds .Add(cmd );
}
public void execute()
{
foreach(Command cmd in cmds )
{
cmd .execute();
}
Console .WriteLine(info );
Console .WriteLine();
}
public void setTotalPrice(int totalPrice )
{
this.totalPrice = totalPrice ;
}
public int getTotalPrice()
{
return totalPrice ;
}
public void appendInfo(String info )
{
this.info .Append(info );
}
public Memento store()
{
return new Memento (cart , cmds , totalPrice );
}
public void restore(Memento mm )
{
cart = mm .getCart();
cmds = mm .getCommmand();
totalPrice = mm .getTotalPrice();
info .Clear();
}
}
Memento.cs
public class Memento
{
private Cart cart = null;
private List <Command > cmds = null;
private int totalPrice = 0;
public Memento(Cart cart, List <Command > cmds, int totalPrice)
{
this.cart = cart;
this.cmds = new List <Command >();
foreach(Command cmd in cmds )
{
this.cmds .Add(cmd);
}
this.totalPrice = totalPrice;
}
public Cart getCart()
{
return cart ;
}
public List <Command > getCommmand()
{
return cmds ;
}
public int getTotalPrice()
{
return totalPrice ;
}
}
Enshu603.vb
Module Enshu602
Sub Main()
Dim reg As Register = New Register ()
Dim cart1 As Cart = New Cart ()
cart1 .add(New Vegetable ("大根", 125, 1))
cart1 .add(New Meat ("豚肉", 98, 250))
cart1 .add(New Vegetable ("レタス", 147, 1))
cart1 .add(New Vegetable ("トマト", 69, 4))
reg .accept(cart1 )
reg .append(New CmdPurchaseTime ())
reg .append(New CmdAccount ())
reg .append(New CmdTotalPrice ())
Dim mm As Memento = reg .store()
' 処理中断 --------------------
' 別処理
Dim cart2 As Cart = New Cart ()
cart2 .add(New Meat ("牛肉", 395, 400))
cart2 .add(New Vegetable ("じゃがいも", 98, 10))
reg .accept(cart2 )
reg .append(New CmdPurchaseTime ())
reg .append(New CmdTotalPrice ())
reg .execute() ' 会計(表示)
' 処理再開 --------------------
reg .restore(mm)
cart1 .add(New Meat ("鶏肉", 78, 200)) ' 買い忘れ 購入
reg .execute() ' 会計(表示)
End Sub
End Module
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
なお、オブジェクト型の代入は参照のコピーです。元の情報を書き換えると保存した情報も変わってしまいますので注意してください。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.vb
Imports System.Text
Public Class Memento
Private cart As Cart = Nothing
Private cmds As List (Of Command ) = Nothing
Private totalPrice As Integer = 0
Public Sub New(cart As Cart , cmds As List (Of Command ), totalPrice As Integer)
End Sub
Public Function getCart() As Cart
Return cart
End Function
Public Function getCommmand() As List (Of Command )
Return cmds
End Function
Public Function getTotalPrice() As Integer
Return totalPrice
End Function
End Class
解答
Register.vb
Imports System.Text
public class Register
{
Private cart As Cart
Private cmds As List (Of Command ) = new List (Of Command )
Private totalPrice As Integer = 0
Private info As StringBuilder = new StringBuilder ();
Public Sub New()
End Sub
Public Sub accept(cart As Cart )
Me.cart = cart
cmds .Clear()
info .Clear()
totalPrice = 0
End Sub
Public Sub append(cmd As Command )
cmd .cart = Me.cart
cmd .register = Me
cmds .Add(cmd )
End Sub
Public Sub execute()
For Each cmd As Command In cmds
cmd .execute()
Next
Console .WriteLine(info )
Console .WriteLine()
End Sub
Public Sub setTotalPrice(totalPrice As Integer) {
Me.totalPrice = totalPrice ;
End Sub
Public Function getTotalPrice() As Integer
Return totalPrice ;
End Function
Public Sub appendInfo(info As String)
Me.info .Append(info );
End Sub
Public Function store() As Memento
Return New Memento (cart , cmds , totalPrice )
End Function
Public Sub restore(mm As Memento )
cart = mm .getCart()
cmds = mm .getCommmand()
totalPrice = mm .getTotalPrice()
info .Clear()
End Sub
End Class
Memento.vb
Imports System.Text
Public Class Memento
Private cart As Cart = Nothing
Private cmds As List (Of Command ) = Nothing
Private totalPrice As Integer = 0
Public Sub New(cart As Cart , cmds As List (Of Command ), totalPrice As Integer)
Me.cart = cart
Me.cmds = New List (Of Command )()
For Each cmd As Command In cmds
Me.cmds .Add(cmd )
Next
Me.totalPrice = totalPrice
End Sub
Public Function getCart() As Cart
Return cart
End Function
Public Function getCommmand() As List (Of Command )
Return cmds
End Function
Public Function getTotalPrice() As Integer
Return totalPrice
End Function
End Class
Enshu603.js
const Register = require("./Register.js");
const Cart = require("./Cart.js");
const Vegetable = require("./Vegetable.js");
const Meat = require("./Meat.js");
const CmdPurchaseTime = require("./CmdPurchaseTime.js");
const CmdAccount = require("./CmdAccount.js");
const CmdTotalPrice = require("./CmdTotalPrice.js");
let reg = new Register ();
let cart1 = new Cart ();
cart1 .add(new Vegetable ("大根", 125, 1));
cart1 .add(new Meat ("豚肉", 98, 250));
cart1 .add(new Vegetable ("レタス", 147, 1));
cart1 .add(new Vegetable ("トマト", 69, 4));
reg .accept(cart1 );
reg .append(new CmdPurchaseTime ());
reg .append(new CmdAccount ());
reg .append(new CmdTotalPrice ());
let mm = reg .store();
// 処理中断 --------------------
// 別処理
let cart2 = new Cart ();
cart2 .add(new Meat ("牛肉", 395, 400));
cart2 .add(new Vegetable ("じゃがいも", 98, 10));
reg .accept(cart2 );
reg .append(new CmdPurchaseTime ());
reg .append(new CmdTotalPrice ());
reg .execute(); // 会計(表示)
// 処理再開 --------------------
reg .restore(mm );
cart1 .add(new Meat ("鶏肉", 78, 200)); // 買い忘れ 購入
reg .execute(); // 会計(表示)
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.js
module.exports = class Memento {
constructor(cart , cmds , totalPrice ) {
}
getCart() {
return this.cart ;
}
getCommmand() {
return this.cmds ;
}
getTotalPrice() {
return this.totalPrice ;
}
}
解答
Register.js
const Memento = require("./Memento.js");
module.exports = class Register {
constructor() {}
accept(cart ) {
this.cart = cart ;
this.cmds = new Array();
this.info = "";
this.totalPrice = 0;
}
append(cmd ) {
cmd .cart = this.cart ;
cmd .register = this;
this.cmds .push(cmd );
}
execute() {
for(let i in this.cmds ) {
this.cmds [i ].execute();
}
process.stdout.write(this.info + "\n");
process.stdout.write("\n");
}
setTotalPrice(totalPrice ) {
this.totalPrice = totalPrice ;
}
getTotalPrice() {
return this.totalPrice ;
}
appendInfo(info ) {
this.info += info ;
}
store() {
return new Memento(this.cart , this.cmds , this.totalPrice );
}
restore(mm ) {
this.cart = mm .getCart();
this.cmds = mm .getCommmand();
this.totalPrice = mm .getTotalPrice();
this.info = "";
}
}
Memento.js
module.exports = class Memento {
constructor(cart , cmds , totalPrice ) {
this.cart = cart ;
this.cmds = cmds ;
this.totalPrice = totalPrice ;
}
getCart() {
return this.cart ;
}
getCommmand() {
return this.cmds ;
}
getTotalPrice() {
return this.totalPrice ;
}
}
Enshu603.pl
use lib './';
use Register;
use Cart;
use Vegetable;
use Meat;
use CmdPurchaseTime;
use CmdAccount;
use CmdTotalPrice;
my $reg = new Register ();
my $cart1 = new Cart ();
$cart1 ->add(new Vegetable ("大根", 125, 1));
$cart1 ->add(new Meat ("豚肉", 98, 250));
$cart1 ->add(new Vegetable ("レタス", 147, 1));
$cart1 ->add(new Vegetable ("トマト", 69, 4));
$reg ->accept($cart1 );
$reg ->append(new CmdPurchaseTime ());
$reg ->append(new CmdAccount ());
$reg ->append(new CmdTotalPrice ());
my $mm = $reg ->store();
# 処理中断 --------------------
# 別処理
my $cart2 = new Cart ();
$cart2 ->add(new Meat ("牛肉", 395, 400));
$cart2 ->add(new Vegetable ("じゃがいも", 98, 10));
$reg ->accept($cart2 );
$reg ->append(new CmdPurchaseTime ());
$reg ->append(new CmdTotalPrice ());
$reg ->execute(); # 会計(表示)
# 処理再開 --------------------
$reg ->restore($mm );
$cart1 ->add(new Meat ("鶏肉", 78, 200));
$reg ->execute(); # 会計(表示)
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.pm
package Memento {
sub new {
my ($class , $cart , $cmds , $totalPrice ) = @_ ;
}
sub getCart() {
my ($this ) = @_ ;
return $this ->{cart };
}
sub getCommmand() {
my ($this ) = @_ ;
return \@{$this ->{cmds }}; # 参照を返す
}
sub getTotalPrice() {
my ($this ) = @_ ;
return $this ->{totalPrice };
}
}
1;
解答
Register.pm
use Memento;
package Register {
sub new {
my ($class ) = @_ ;
return bless {}, $class ;
}
sub accept {
my ($this , $cart ) = @_ ;
$this ->{cart } = $cart ;
$this ->{cmds } = ();
$this ->{totalPrice } = 0;
$this ->{info } = "";
}
sub append {
my ($this , $cmd ) = @_ ;
$cmd ->{cart } = $this ->{cart };
$cmd ->{register } = $this ;
push @{$this ->{cmds }}, $cmd ;
}
sub execute {
my ($this ) = @_ ;
foreach my $cmd (@{$this ->{cmds }}) {
$cmd ->execute();
}
print $this ->{info } . "\n\n";
}
sub setTotalPrice {
my ($this , $totalPrice ) = @_ ;
$this ->{totalPrice } = $totalPrice ;
}
sub getTotalPrice {
my ($this ) = @_ ;
return $this ->{totalPrice };
}
sub appendInfo {
my ($this , $info ) = @_ ;
$this ->{info } .= $info ;
}
sub store {
my ($this ) = @_ ;
return new Memento($this ->{cart }, $this ->{cmds }, $this ->{totalPrice });
}
sub restore {
my ($this , $mm ) = @_ ;
$this ->{cart } = $mm ->getCart();
$this ->{cmds } = $mm ->getCommmand();
$this ->{totalPrice } = $mm ->getTotalPrice();
$this ->{info } = "";
}
}
1;
Memento.pm
package Memento {
sub new {
my ($class , $cart , $cmds , $totalPrice ) = @_ ;
my $this = { cart => $cart ,
cmds => $cmds ,
totalPrice => $totalPrice ,
};
return bless $this , $class ;
}
sub getCart() {
my ($this ) = @_ ;
return $this ->{cart };
}
sub getCommmand() {
my ($this ) = @_ ;
return \@{$this ->{cmds }}; # 参照を返す
}
sub getTotalPrice() {
my ($this ) = @_ ;
return $this ->{totalPrice };
}
}
1;
Enshu603.rb
require './Register'
require './Cart'
require './Vegetable'
require './Meat'
require './CmdPurchaseTime'
require './CmdAccount'
require './CmdTotalPrice'
reg = Register .new();
cart1 = Cart .new();
cart1 .add(Vegetable .new("大根", 125, 1));
cart1 .add(Meat .new("豚肉", 98, 250));
cart1 .add(Vegetable .new("レタス", 147, 1));
cart1 .add(Vegetable .new("トマト", 69, 4));
reg .accept(cart1 );
reg .append(CmdPurchaseTime .new());
reg .append(CmdAccount .new());
reg .append(CmdTotalPrice .new());
mm = reg .store();
# 処理中断 --------------------
# 別処理
cart2 = Cart .new();
cart2 .add(Meat .new("牛肉", 395, 400));
cart2 .add(Vegetable .new("じゃがいも", 98, 10));
reg .accept(cart2 );
reg .append(CmdPurchaseTime .new());
reg .append(CmdTotalPrice .new());
reg .execute(); # 会計(表示)
# 処理再開 --------------------
reg .restore(mm );
cart1 .add(Meat .new("鶏肉", 78, 200)); # 買い忘れ 購入
reg .execute(); # 会計(表示)
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.pm
class Memento {
def initialize(cart , cmds , totalPrice )
end
def getCart()
return @cart
end
def getCommmand()
return @cmds
end
def getTotalPrice()
return @totalPrice
end
end
解答
Register.rb
require './Memento'
class Register {
def initialize()
@cmds = []
end
def accept(cart )
@cart = cart
@cmds = []
@totalPrice = 0;
@info = ""
end
def append(cmd )
cmd .cart = @cart
cmd .register = self
@cmds .push(cmd )
end
def execute()
@cmds .each do |cmd |
cmd .execute()
end
print(@info + "\n\n")
end
def setTotalPrice(totalPrice )
@totalPrice = totalPrice
end
def getTotalPrice()
return @totalPrice
end
def appendInfo(info )
@info += info
end
def store()
return Memento.new(@cart , @cmds , @totalPrice );
end
def restore(mm )
@cart = mm .getCart()
@cmds = mm .getCommmand()
@totalPrice = mm .getTotalPrice()
@info = ""
end
end
Memento.pm
class Memento {
def initialize(cart , cmds , totalPrice )
@cart = cart ;
@cmds = cmds ;
@totalPrice = totalPrice ;
end
def getCart()
return @cart
end
def getCommmand()
return @cmds
end
def getTotalPrice()
return @totalPrice
end
end
Enshu603.py
from Register import Register
from Cart import Cart
from Vegetable import Vegetable
from Meat import Meat
from CmdPurchaseTime import CmdPurchaseTime
from CmdAccount import CmdAccount
from CmdTotalPrice import CmdTotalPrice
reg = Register ()
cart1 = Cart ()
cart1 .add(Vegetable ("大根", 125, 1))
cart1 .add(Meat ("豚肉", 98, 250))
cart1 .add(Vegetable ("レタス", 147, 1))
cart1 .add(Vegetable ("トマト", 69, 4))
reg .accept(cart1 )
reg .append(CmdPurchaseTime ())
reg .append(CmdAccount ())
reg .append(CmdTotalPrice ())
mm = reg .store()
# 処理中断 --------------------
# 別処理
cart2 = Cart ()
cart2 .add(Meat ("牛肉", 395, 400))
cart2 .add(Vegetable ("じゃがいも", 98, 10))
reg .accept(cart2 )
reg .append(CmdPurchaseTime ())
reg .append(CmdTotalPrice ())
reg .execute() # 会計(表示)
# 処理再開 --------------------
reg .restore(mm )
cart1 .add(Meat ("鶏肉", 78, 200)) # 買い忘れ 購入
reg .execute() # 会計(表示)
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.py
class Memento :
def __init__(self , cart , cmds , totalPrice ):
def getCart():
return self .cart
def getCommmand():
return self .cmds
def getTotalPrice():
return self .totalPrice
解答
Register.py
from Memento import Memento
class Register :
def __init__(self ):
self .cmds = []
def accept(self , cart ):
self .cart = cart
self .cmds = []
self .totalPrice = 0
self .info = ""
def append(self , cmd ):
cmd .cart = self .cart
cmd .register = self
self .cmds .append(cmd )
def execute(self ):
for cmd in self .cmds :
cmd .execute()
print(self .info )
print()
def setTotalPrice(self , totalPrice ):
self .totalPrice = totalPrice
def getTotalPrice(self ):
return self .totalPrice
def appendInfo(self , info ):
self .info += info
def store(self ):
return Memento (self .cart, self .cmds, self .totalPrice);
def restore(self , mm ):
self .cart = mm .getCart()
self .cmds = mm .getCommmand()
self .totalPrice = mm .getTotalPrice()
self .info = ""
Memento.py
class Memento :
def __init__(self , cart , cmds , totalPrice ):
self .cart = cart
self .cmds = cmds
self .totalPrice = totalPrice
def getCart():
return self .cart
def getCommmand():
return self .cmds
def getTotalPrice():
return self .totalPrice
Enshu603.php
<?php
require_once('Register.php');
require_once('Cart.php');
require_once('Vegetable.php');
require_once('Meat.php');
require_once('CmdPurchaseTime.php');
require_once('CmdAccount.php');
require_once('CmdTotalPrice.php');
$reg = new Register ();
$cart1 = new Cart ();
$cart1 ->add(new Vegetable ("大根", 125, 1));
$cart1 ->add(new Meat ("豚肉", 98, 250));
$cart1 ->add(new Vegetable ("レタス", 147, 1));
$cart1 ->add(new Vegetable ("トマト", 69, 4));
$reg ->accept($cart1 );
$reg ->append(new CmdPurchaseTime ());
$reg ->append(new CmdAccount ());
$reg ->append(new CmdTotalPrice ());
$mm = $reg ->store();
// 処理中断 --------------------
// 別処理
$cart2 = new Cart ();
$cart2 ->add(new Meat ("牛肉", 395, 400));
$cart2 ->add(new Vegetable ("じゃがいも", 98, 10));
$reg ->accept($cart2 );
$reg ->append(new CmdPurchaseTime ());
$reg ->append(new CmdTotalPrice ());
$reg ->execute(); // 会計(表示)
// 処理再開 --------------------
$reg ->restore($mm );
$cart1 ->add(new Meat ("鶏肉", 78, 200)); // 買い忘れ 購入
$reg ->execute(); // 会計(表示)
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.php
<?php
class Memento {
private $cart ; // カート
private $cmds ; // コマンド
private $totalPrice ; // 合計金額
public function __construct($cart , $cmds , $totalPrice ) {
}
public function getCart() {
return $this->cart ;
}
public function getCommmand() {
return $this->cmds ;
}
public function getTotalPrice() {
return $this->totalPrice ;
}
}
?>
解答
Register.php
<?php
require_once('Meat.php');
class Register {
protected $cart ;
protected $cmds ;
protected $totalPrice ;
protected $info ;
public function __construct() {}
public function accept($cart ) {
$this->cart = $cart ;
$this->cmds = array();
$this->totalPrice = 0;
$this->info = "";
}
public function append($cmd ) {
$cmd ->cart = $this->cart ;
$cmd ->register = $this;
$this->cmds [] = $cmd ;
}
public function execute() {
foreach($this->cmds as $cmd ) {
$cmd ->execute();
}
print($this->info . "\n\n");
}
public function setTotalPrice($totalPrice ) {
$this->totalPrice = $totalPrice ;
}
public function getTotalPrice() {
return $this->totalPrice ;
}
public function appendInfo($info ) {
$this->info .= $info ;
}
public function store() {
return new Memento($this->cart , $this->cmds , $this->totalPrice );
}
public function restore($mm ) {
$this->cart = $mm ->getCart();
$this->cmds = $mm ->getCommmand();
$this->totalPrice = $mm ->getTotalPrice();
$this->info = "";
}
}
?>
Memento.php
<?php
class Memento {
private $cart ; // カート
private $cmds ; // コマンド
private $totalPrice ; // 合計金額
public function __construct($cart , $cmds , $totalPrice ) {
$this->cart = $cart ;
$this->cmds = $cmds ;
$this->totalPrice = $totalPrice ;
}
public function getCart() {
return $this->cart ;
}
public function getCommmand() {
return $this->cmds ;
}
public function getTotalPrice() {
return $this->totalPrice ;
}
}
?>
Enshu603.ts
import {Register} from "./Register";
import {Cart} from "./Cart";
import {Vegetable} from "./Vegetable";
import {Meat} from "./Meat";
import {CmdPurchaseTime} from "./CmdPurchaseTime";
import {CmdAccount} from "./CmdAccount";
import {CmdTotalPrice} from "./CmdTotalPrice";
import {Memento} from "./Memento";
let reg :Register = new Register ();
let cart1 :Cart = new Cart ();
cart1 .add(new Vegetable ("大根", 125, 1));
cart1 .add(new Meat ("豚肉", 98, 250));
cart1 .add(new Vegetable ("レタス", 147, 1));
cart1 .add(new Vegetable ("トマト", 69, 4));
reg .accept(cart1 );
reg .append(new CmdPurchaseTime ());
reg .append(new CmdAccount ());
reg .append(new CmdTotalPrice ());
let mm :Memento = reg .store();
// 処理中断 --------------------
// 別処理
let cart2 :Cart = new Cart ();
cart2 .add(new Meat ("牛肉", 395, 400));
cart2 .add(new Vegetable ("じゃがいも", 98, 10));
reg .accept(cart2 );
reg .append(new CmdPurchaseTime ());
reg .append(new CmdTotalPrice ());
reg .execute(); // 会計(表示)
// 処理再開 --------------------
reg .restore(mm );
cart1 .add(new Meat ("鶏肉", 78, 200)); // 買い忘れ 購入
reg .execute(); // 会計(表示)
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
なお、オブジェクト型の代入は参照のコピーです。元の情報を書き換えると保存した情報も変わってしまいますので注意してください。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.ts
import {Command} from "./Command";
export
class Memento {
private cart :Cart = null;
private cmds :Array <Command > = null;
private totalPrice :number = 0;
public constructor(cart :Cart , cmds :Array <Command >, totalPrice :number) {
}
public getCart():Cart {
}
public getCommmand():Array <Command > {
}
public getTotalPrice():number {
}
}
解答
Register.ts
import { Cart } from "./Cart";
import { Command } from "./Command";
import { Memento } from "./Memento";
export
class Register {
private cart :Cart ;
private cmds :Array <Command >;
private info :string;
private totalPrice :number;
public accept(cart :Cart ) {
this.cart = cart ;
this.cmds = new Array <Command >();
this.info = "";
this.totalPrice = 0;
}
public append(cmd :Command ):void {
cmd .cart = this.cart ;
cmd .register = this;
this.cmds .push(cmd );
}
public execute():void {
for(let cmd of this.cmds ) {
cmd .execute();
}
process.stdout.write(this.info + "\n");
process.stdout.write("\n");
}
public setTotalPrice(totalPrice :number):void {
this.totalPrice = totalPrice ;
}
public getTotalPrice():number {
return this.totalPrice ;
}
public appendInfo(info :string):void {
this.info += info ;
}
public store():Memento {
return new Memento (this.cart , this.cmds , this.totalPrice );
}
public restore(mm :Memento ):void {
this.cart = mm .getCart();
this.cmds = mm .getCommmand();
this.totalPrice = mm .getTotalPrice();
this.info = "";
}
}
Memento.ts
import { Cart } from "./Cart";
import {Command} from "./Command";
export
class Memento {
private cart :Cart = null;
private cmds :Array <Command > = null;
private totalPrice :number = 0;
public public constructor(cart :Cart , cmds :Array <Command >, totalPrice :number) {
this.cart = cart ;
this.cmds = cmds ;
this.totalPrice = totalPrice ;
}
public getCart():Cart {
return this.cart ;
}
public getCommmand():Array <Command > {
return this.cmds ;
}
public getTotalPrice():number {
return this.totalPrice ;
}
}
Enshu603.swift
let reg :Register = Register ()
let cart1 :Cart = Cart ()
cart1 .add(Vegetable ("大根", 125, 1))
cart1 .add(Meat ("豚肉", 98, 250))
cart1 .add(Vegetable ("レタス", 147, 1))
cart1 .add(Vegetable ("トマト", 69, 4))
reg .accept(cart1 )
reg .append(CmdPurchaseTime ())
reg .append(CmdAccount ())
reg .append(CmdTotalPrice ())
let mm :Memento = reg .store()
// 処理中断 --------------------
// 別処理
let cart2 :Cart = Cart ()
cart2 .add(Meat ("牛肉", 395, 400))
cart2 .add(Vegetable ("じゃがいも", 98, 10))
reg .accept(cart2 )
reg .append(CmdPurchaseTime ())
reg .append(CmdTotalPrice ())
reg .execute() // 会計(表示)
// 処理再開 --------------------
reg .restore(mm )
cart1 .add(Meat ("鶏肉", 78, 200)) // 買い忘れ 購入
reg .execute() // 会計(表示)
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
なお、オブジェクト型の代入は参照のコピーです。元の情報を書き換えると保存した情報も変わってしまいますので注意してください。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.swift
public class Memento {
private var cart :Cart !
private var cmds :[Command ]!
private var totalPrice :Int = 0
public init(_ cart :Cart , _ cmds :[Command ], _ totalPrice :Int) {
}
public func getCart() -> Cart {
}
public func getCommmand() -> [Command ] {
}
public func getTotalPrice() -> Int {
}
}
解答
Register.ts
public class Register {
private var cart :Cart !
private var cmds :[Command ] = []
private var info :String = ""
private var totalPrice :Int = 0
public func accept(_ cart :Cart ) {
self.cart = cart
cmds = []
info = ""
totalPrice = 0
}
public func append(_ cmd :Command ) {
cmd .cart = self.cart
cmd .register = self
self.cmds .append(cmd )
}
public func execute() {
cmds .forEach {
$0 .execute()
}
print(info )
print()
}
public func setTotalPrice(_ totalPrice :Int) {
self.totalPrice = totalPrice
}
public func getTotalPrice() -> Int {
return totalPrice
}
public func appendInfo(_ info :String) {
self.info += info
}
public func store() -> Memento {
return Memento (cart , cmds , totalPrice )
}
public func restore(_ mm :Memento ) {
cart = mm .getCart()
cmds = mm .getCommmand()
totalPrice = mm .getTotalPrice()
info = ""
}
}
Memento.swift
public class Memento {
private var cart :Cart !
private var cmds :[Command ]!
private var totalPrice :Int = 0
public init(_ cart :Cart , _ cmds :[Command ], _ totalPrice :Int) {
self.cart = cart
self.cmds = []
cmds .forEach {
self.cmds .append($0)
}
self.totalPrice = totalPrice
}
public func getCart() -> Cart {
return cart
}
public func getCommmand() -> [Command ] {
return cmds
}
public func getTotalPrice() -> Int {
return totalPrice
}
}
Enshu603.kt
fun main() {
val reg = Register ()
val cart1 = Cart ()
cart1 .add(Vegetable ("大根", 125, 1))
cart1 .add(Meat ("豚肉", 98, 250))
cart1 .add(Vegetable ("レタス", 147, 1))
cart1 .add(Vegetable ("トマト", 69, 4))
reg .accept(cart1 )
reg .append(CmdPurchaseTime ())
reg .append(CmdAccount ())
reg .append(CmdTotalPrice ())
val mm : Memento = reg .store()
// 処理中断 --------------------
// 別処理
val cart2 = Cart ()
cart2 .add(Meat ("牛肉", 395, 400))
cart2 .add(Vegetable ("じゃがいも", 98, 10))
reg .accept(cart2 )
reg .append(CmdPurchaseTime ())
reg .append(CmdTotalPrice ())
reg .execute() // 会計(表示)
// 処理再開 --------------------
reg .restore(mm )
cart1 .add(Meat ("鶏肉", 78, 200)) // 買い忘れ 購入
reg .execute() // 会計(表示)
}
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
なお、オブジェクト型の代入は参照のコピーです。元の情報を書き換えると保存した情報も変わってしまいますので注意してください。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.kt
import java.util.Vector
class Memento (private val cart : Cart , cmds : Vector <Command >, private val totalPrice : Int) {
private var cmds : Vector <Command > = Vector()
init {
}
open fun getCart(): Cart =
open fun getCommmand(): Vector <Command > =
open fun getTotalPrice(): Int =
}
解答
Register.kt
import java.util.Vector
class Register {
private lateinit var cart : Cart
private var cmds : Vector <Command >
private val info : StringBuilder()
var totalPrice : Int = 0
fun accept(cart : Cart ) {
this.cart = cart
cmds .clear()
info .delete(0, info .length)
totalPrice = 0
}
fun append(cmd : Command ) {
cmd .cart = cart
cmd .register = this
cmds .add(cmd )
}
fun execute() {
for(cmd in cmds ) {
cmd .execute()
}
println(info )
println()
}
fun appendInfo(info : String?) {
this.info .append(info )
}
fun store() : Memento = Memento (cart , cmds , totalPrice )
fun restore(mm : Memento ) {
cart = mm .getCart()
cmds = mm .getCommmand()
totalPrice = mm .getTotalPrice()
info .delete(0, info .length)
}
}
Memento.kt
import java.util.Vector
class Memento (private val cart : Cart , cmds : Vector <Command >, private val totalPrice : Int) {
private val cmds : Vector <Command > = Vector()
init {
for (cmd in cmds ) {
this.cmds .add(cmd )
}
}
fun getCart() : Cart = cart
fun getCommmand() : Vector <Command > = cmds
fun getTotalPrice() : Int = totalPrice
}
Enshu603.scala
object Main603 {
def main(args : Array [String]) {
val reg = new Register ()
val cart1 = new Cart ()
cart1 .add(new Vegetable ("大根", 125, 1))
cart1 .add(new Meat ("豚肉", 98, 250))
cart1 .add(new Vegetable ("レタス", 147, 1))
cart1 .add(new Vegetable ("トマト", 69, 4))
reg .accept(cart1 )
reg .append(new CmdPurchaseTime ())
reg .append(new CmdAccount ())
reg .append(new CmdTotalPrice ())
val mm : Memento = reg .store()
// 処理中断 --------------------
// 別処理
val cart2 = new Cart ()
cart2 .add(new Meat ("牛肉", 395, 400))
cart2 .add(new Vegetable ("じゃがいも", 98, 10))
reg .accept(cart2 )
reg .append(new CmdPurchaseTime ())
reg .append(new CmdTotalPrice ())
reg .execute() // 会計(表示)
// 処理再開 --------------------
reg .restore(mm )
cart1 .add(new Meat ("鶏肉", 78, 200)) // 買い忘れ 購入
reg .execute() // 会計(表示)
}
}
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
なお、オブジェクト型の代入は参照のコピーです。元の情報を書き換えると保存した情報も変わってしまいますので注意してください。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.scala
import scala.collection.mutable.ListBuffer
class Memento (val cart : Cart , cmdList : ListBuffer [Command ], val totalPrice : Int) {
private var cmds = ListBuffer [Command ]()
def getCart(): Cart =
def getCommmand(): ListBuffer [Command ] =
def getTotalPrice(): Int =
}
解答
Register.scala
import scala.collection.mutable.ListBuffer
class Register {
private var cart : Cart = null
private var cmds = new ListBuffer [Command ]()
private val info = new StringBuilder()
private var totalPrice : Int = 0
def accept(cart : Cart ) {
this.cart = cart
cmds .clear()
info .delete(0, info .length)
totalPrice = 0
}
def append(cmd : Command ) {
cmd .cart = cart
cmd .register = this
cmds .addOne(cmd )
}
def execute() {
for(cmd <- cmds ) {
cmd .execute()
}
System.out.println(info )
System.out.println()
}
def setTotalPrice(totalPrice : Int) {
this.totalPrice = totalPrice
}
def getTotalPrice(): Int = totalPrice
def appendInfo(info : String) {
this.info .append(info )
}
def store() : Memento = new Memento (cart , cmds , totalPrice )
def restore(mm : Memento ) {
cart = mm .getCart()
cmds = mm .getCommmand()
totalPrice = mm .getTotalPrice()
info .delete(0, info .length)
}
}
Memento.scala
import scala.collection.mutable.ListBuffer
class Memento (val cart : Cart , cmdList : ListBuffer [Command ], val totalPrice : Int) {
private var cmds = ListBuffer [Command ]()
for (cmd <- cmdList ) {
this.cmds .addOne(cmd )
}
def getCart(): Cart = cart
def getCommmand(): ListBuffer [Command ] = cmds
def getTotalPrice(): Int = totalPrice
}
Enshu603.groovy
class Enshu603 {
static void main(String[] args ) {
Register reg = new Register ()
Cart cart1 = new Cart ()
cart1 .add(new Vegetable ("大根", 125, 1))
cart1 .add(new Meat ("豚肉", 98, 250))
cart1 .add(new Vegetable ("レタス", 147, 1))
cart1 .add(new Vegetable ("トマト", 69, 4))
reg .accept(cart1 )
reg .append(new CmdPurchaseTime ())
reg .append(new CmdAccount ())
reg .append(new CmdTotalPrice ())
Memento mm = reg .store()
// 処理中断 --------------------
// 別処理
Cart cart2 = new Cart ()
cart2 .add(new Meat ("牛肉", 395, 400))
cart2 .add(new Vegetable ("じゃがいも", 98, 10))
reg .accept(cart2 )
reg .append(new CmdPurchaseTime ())
reg .append(new CmdTotalPrice ())
reg .execute() // 会計(表示)
// 処理再開 --------------------
reg .restore(mm )
cart1 .add(new Meat ("鶏肉", 78, 200)) // 買い忘れ 購入
reg .execute() // 会計(表示)
}
}
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
なお、オブジェクト型の代入は参照のコピーです。元の情報を書き換えると保存した情報も変わってしまいますので注意してください。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.groovy
class Memento {
Cart cart = null
Vector <Command > cmds = null
int totalPrice = 0
Memento(Cart cart , Vector <Command > cmds , int totalPrice ) {
}
}
解答
Register.groovy
public class Register {
private Cart cart
private Vector <Command > cmds = new Vector <Command >()
int totalPrice = 0
private StringBuilder info = new StringBuilder ()
Register () {}
void accept(Cart cart ) {
this.cart = cart ;
cmds .clear()
totalPrice = 0
info .delete(0, info .length())
}
void append(Command cmd ) {
cmd .cart = this.cart
cmd .register = this
cmds .add(cmd )
}
void execute() {
for(Command cmd : cmds ) {
cmd .execute()
}
System.out.println(info )
System.out.println()
}
void appendInfo(String info ) {
this.info .append(info )
}
Memento store() {
return new Memento (cart , cmds , totalPrice )
}
void restore(Memento mm ) {
cart = mm .getCart()
cmds = mm .getCommmand()
totalPrice = mm .getTotalPrice()
info .delete(0, info .length())
}
}
Memento.groovy
class Memento {
Cart cart = null
Vector <Command > cmds = null
int totalPrice = 0
Memento (Cart cart , Vector <Command > cmds , int totalPrice ) {
this.cart = cart
this.cmds = new Vector <Command >()
for (Command cmd : cmds ) {
this.cmds .add(cmd )
}
this.totalPrice = totalPrice
}
}
Enshu603.go
func main() {
var reg = NewRegister ()
var cart1 = NewCart ()
cart1 .Add (NewVegetable ("大根", 125, 1))
cart1 .Add (NewMeat ("豚肉", 98, 250))
cart1 .Add (NewVegetable ("レタス", 147, 1))
cart1 .Add (NewVegetable ("トマト", 69, 4))
reg .Accept (cart1 )
reg .Append (NewCmdPurchaseTime ())
reg .Append (NewCmdAccount ())
reg .Append (NewCmdTotalPrice ())
var mm = reg .Store ()
// 処理中断 --------------------
// 別処理
var cart2 = NewCart ()
cart2 .Add (NewMeat ("牛肉", 395, 400))
cart2 .Add (NewVegetable ("じゃがいも", 98, 10))
reg .Accept (cart2 )
reg .Append (NewCmdPurchaseTime ())
reg .Append (NewCmdTotalPrice ())
reg .Execute () // 会計(表示)
// 処理再開 --------------------
reg .Restore (mm )
cart1 .Add (NewMeat ("鶏肉", 78, 200)) // 買い忘れ 購入
reg .Execute () // 会計(表示)
}
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて大文字から始まる名前にして public として宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
なお、オブジェクト型の代入は参照のコピーです。元の情報を書き換えると保存した情報も変わってしまいますので注意してください。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.go
type Memento struct {
cart *Cart
cmds []ICommand
totalPrice int
}
func NewMemento (cart Cart , cmds []ICommand , totalPrice int) *Memento {
}
解答
Register.go
import "fmt"
type Register struct {
cart *Cart
cmds = []ICommand
totalPrice int
info string
}
func (self *Register ) Accept (cart *Cart ) {
self.cart = cart
self.cmds = self.cmds [0:0]
self.totalPrice = 0
self.info = ""
}
func (self *Register ) Append (cmd ICommand ) {
cmd .SetCart (self.cart )
cmd .SetRegister (self)
self.cmds = append(self.cmds , cmd )
}
func (self *Register ) Execute () {
for _ , cmd := range self.cmds {
cmd .Execute()
}
fmt.Println(self.info )
fmt.Println()
}
func (self *Register ) AppendInfo (info string) {
self.info += info
}
func (self *Register ) Store () *Memento {
return NewMemento (self.cart , self.cmds , self.totalPrice )
}
func (self *Register ) Restore (mm *Memento ) {
self.cart = mm .cart
self.cmds = mm .cmds
self.totalPrice = mm .totalPrice
self.info = self.info [0:0]
}
func NewRegister () *Register {
return &Register {}
}
Memento.go
type Memento struct {
cart *Cart
cmds []ICommand
totalPrice int
}
func NewMemento (cart Cart , cmds []ICommand , totalPrice int) {
var cmdsCopy []ICommand
for _ , cmd := range cmds {
cmdsCopy = append(cmdsCopy , cmd )
}
return &Memento {
cart : cart ,
cmds : cmdsCopy ,
totalPrice : totalPrice ,
}
}
enshu603.d
import register;
import cart;
import vegetable;
import meat;
import cmdpurchasetime;
import cmdaccount;
import cmdtotalprice;
import memento;
int main() {
Register reg = new Register ();
Cart cart1 = new Cart ();
cart1 .add(new Vegetable ("大根", 125, 1));
cart1 .add(new Meat ("豚肉", 98, 250));
cart1 .add(new Vegetable ("レタス", 147, 1));
cart1 .add(new Vegetable ("トマト", 69, 4));
reg .accept(cart1 );
reg .append(new CmdPurchaseTime ());
reg .append(new CmdAccount ());
reg .append(new CmdTotalPrice ());
Memento mm = reg .store();
// 処理中断 --------------------
// 別処理
Cart cart2 = new Cart ();
cart2 .add(new Meat ("牛肉", 395, 400));
cart2 .add(new Vegetable ("じゃがいも", 98, 10));
reg .accept(cart2 );
reg .append(new CmdPurchaseTime ());
reg .append(new CmdTotalPrice ());
reg .execute(); // 会計(表示)
// 処理再開 --------------------
reg .restore(mm );
cart1 .add(new Meat ("鶏肉", 78, 200)); // 買い忘れ 購入
reg .execute(); // 会計(表示)
}
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
なお、オブジェクト型の代入は参照のコピーです。元の情報を書き換えると保存した情報も変わってしまいますので注意してください。
Memento クラスのコード(一部)を見ますか? はい いいえ
memento.d
import cart;
import command;
public class Memento {
private Cart cart = null;
private Command [] cmds ;
private int totalPrice = 0;
public this(Cart cart , Command [] cmds , in int totalPrice ) {
}
public Cart getCart() {
return cart ;
}
public Command [] getCommmand() {
return cmds ;
}
public int getTotalPrice() {
return totalPrice ;
}
}
解答
register.d
import std.stdio;
import cart;
import command;
import memento;
public class Register {
private Cart cart ;
private Command [] cmds ;
private int totalPrice = 0;
private string info = "";
public void accept(Cart cart ) {
this.cart = cart ;
cmds = [];
totalPrice = 0;
info = "";
}
public void append(Command cmd ) {
cmd .cart = this.cart ;
cmd .setTotalPrice = &setTotalPrice;
cmd .getTotalPrice = &getTotalPrice;
cmd .appendInfo = &appendInfo;
cmds ~= cmd ;
}
public void execute() {
foreach (Command cmd ; cmds ) {
cmd .execute();
}
printfln(info );
writeln();
}
public void setTotalPrice(in int totalPrice ) {
this.totalPrice = totalPrice ;
}
public int getTotalPrice() {
return totalPrice ;
}
public void appendInfo(in string info ) {
this.info ~= info ;
}
public Memento store() {
return new Memento (cart , cmds , totalPrice );
}
public void restore(Memento mm ) {
cart = mm .getCart();
cmds = mm .getCommmand();
totalPrice = mm .getTotalPrice();
info = "";
}
private void printfln(T...)(T args ) { // Shift JIS 出力
import std, std.windows.charset, core.vararg;
std.stdio.writeln(to!(string)(toMBSz(std.format.format(args ))));
}
}
memento.d
import cart;
import command;
public class Memento {
private Cart cart = null;
private Command [] cmds ;
private int totalPrice = 0;
public this(Cart cart , Command [] cmds , in int totalPrice ) {
this.cart = cart ;
this.cmds = [];
foreach (Command cmd ; cmds ) {
this.cmds ~= cmd ;
}
this.totalPrice = totalPrice ;
}
public Cart getCart() {
return cart ;
}
public Command [] getCommmand() {
return cmds ;
}
public int getTotalPrice() {
return totalPrice ;
}
}
Enshu603.dpr
program Enshu603;
uses
UnitVegetable,
UnitMeat,
UnitCart,
UnitRegister,
UnitCmdPurchaseTime,
UnitCmdAccount,
UnitCmdTotalPrice,
UnitMemento;
var cart1 , cart2 :Cart ;
var reg :Register ;
var mm :Memento ;
begin
reg := Register .Create();
cart1 := Cart .Create();
cart1 .add(Vegetable .Create('大根', 125, 1));
cart1 .add(Meat .Create('豚肉', 98, 250));
cart1 .add(Vegetable .Create('レタス', 147, 1));
cart1 .add(Vegetable .Create('トマト', 69, 4));
reg .accept(cart1 );
reg .append(CmdPurchaseTime .Create());
reg .append(CmdAccount .Create());
reg .append(CmdTotalPrice .Create());
mm := reg.store();
// 処理中断 --------------------
// 別処理
cart2 := Cart .Create();
cart2 .add(Meat .Create('牛肉', 395, 400));
cart2 .add(Vegetable .Create('じゃがいも', 98, 10));
reg .accept(cart2 );
reg .append(CmdPurchaseTime .Create());
reg .append(CmdTotalPrice .Create());
reg .execute(); // 会計(表示)
cart2 .Free;
// 処理再開 --------------------
reg .restore(mm );
mm .Free;
cart1 .add(Meat .Create('鶏肉', 78, 200)); // 買い忘れ 購入
reg .execute(); // 会計(表示)
cart1 .Free;
reg .Free;
end.
ヒント(Memento クラスの一部)
Memento クラスはインスタンスの持っている情報を、保存する・復元する仕組みです。
例えば、インスタンスの情報をすべて public で宣言すれば自由にアクセスでき、いろいろなクラスから保存・復元することができるようになります。しかし、それでは、そのクラスに依存したコードになってしまい、そのクラスの変更が他のクラスに多大な影響を及ぼすことになってしまいます。
そこで、カプセル化の破壊に陥ることなく保存/復元を行う仕組みとして Memento クラスを作成します(もちろん Memento クラスだけはそのクラスの情報を知っています)。
なお、オブジェクト型の代入は参照のコピーです。元の情報を書き換えると保存した情報も変わってしまいますので注意してください。
Memento クラスのコード(一部)を見ますか? はい いいえ
Memento.pas
unit UnitMemento;
interface
uses
System.Generics.Collections,
UnitCart;
type
Memento = class
private
var _cart :Cart ;
var cmds :TList <TObject >; // 循環参照の回避
var totalPrice :integer;
public
constructor Create(_cart :Cart ; cmds :TList <TObject >; totalPrice :integer);
function getCart():Cart ;
function getCommand():TList <TObject >;
function getTotalPrice():integer;
end;
implementation
constructor Memento.Create(_cart :Cart ; cmds :TList <TObject >; totalPrice :integer);
var cmd :TObject ;
begin
end;
function Memento.getCart():Cart ;
begin
Result := _cart ;
end;
function Memento.getCommand():TList <TObject >;
begin
Result := cmds ;
end;
function Memento.getTotalPrice():integer;
begin
Result := totalPrice ;
end;
end.
解答
Register.pas
unit UnitRegister;
interface
uses
System.Generics.Collections,
UnitMemento,
UnitCart;
type
Register = class
private
var _cart :Cart ;
var cmds :TList <TObject >; // 循環参照の回避
var totalPrice :integer;
var info :string;
public
procedure accept(_cart :Cart );
procedure append(_cmd :TObject );
procedure execute();
procedure setTotalPrice(totalPrice :integer);
function getTotalPrice():integer;
procedure appendInfo(info :string);
function store():Memento ;
procedure restore(mm :Memento );
end;
implementation
uses
UnitCommand;
procedure Register .accept(_cart :Cart );
begin
self._cart := _cart ;
cmds := TList <TObject >.Create();
totalPrice := 0;
info := '';
end;
procedure Register .append(_cmd :TObject );
var cmd :Command ;
begin
cmd := _cmd as Command ;
cmd ._cart := self._cart ;
cmd ._register := self;
cmds .add(cmd );
end;
procedure Register .execute();
var cmd :TObject ;
begin
for cmd in cmds do begin
(cmd as Command ).execute(); // 循環参照の回避
cmd .Free;
end;
Writeln(info );
Writeln('');
cmds .Free;
end;
procedure Register .setTotalPrice(totalPrice :integer);
begin
self.totalPrice := totalPrice ;
end;
function Register .getTotalPrice():integer;
begin
Result := totalPrice ;
end;
procedure Register .appendInfo(info :string);
begin
self.info := self.info + info ;
end;
function Register .store():Memento ;
begin
Result := Memento .Create(_cart , cmds , totalPrice );
end;
procedure Register .restore(mm :Memento );
begin
_cart := mm .getCart();
cmds := mm .getCommand();
totalPrice := mm .getTotalPrice();
info := '';
end;
end.
Memento.pas
unit UnitMemento;
interface
uses
System.Generics.Collections,
UnitCart;
type
Memento = class
private
var _cart :Cart ;
var cmds :TList <TObject >; // 循環参照の回避
var totalPrice :integer;
public
constructor Create(_cart :Cart ; cmds :TList <TObject >; totalPrice :integer);
function getCart():Cart ;
function getCommand():TList <TObject >;
function getTotalPrice():integer;
end;
implementation
constructor Memento.Create(_cart :Cart ; cmds :TList <TObject >; totalPrice :integer);
var cmd :TObject ;
begin
self._cart := _cart ;
self.cmds := TList <TObject >.Create();
for cmd in cmds do begin
self.cmds .add(cmd );
end;
self.totalPrice := totalPrice ;
end;
function Memento.getCart():Cart ;
begin
Result := _cart ;
end;
function Memento.getCommand():TList <TObject >;
begin
Result := cmds ;
end;
function Memento.getTotalPrice():integer;
begin
Result := totalPrice ;
end;
end.
演習問題6-3 (Memento)