Board index » delphi » Relation of Model, Command and Selection

Relation of Model, Command and Selection


2006-04-28 04:28:29 PM
delphi55
Hi,
I thought I have master the concept of Model, Command and Selection.
However, after looking some articles. I found out something unclear:
If an interactor trigger the model's command. The command suppose to
work on the selection. However, there are chances that the command will
refer to model too. Thus, we have this design:
TCommand = class
private
fSelection: ISelection;
procedure BindSelection(const Selection: ISelection);
public
constructor Create(const aModel: IModel);
end;
If seems redundant for the Command to know both model and selection as
the model already know selection. If the command want to work on
selection, it can refer to model:
(aModel.Selection as IVisited).Accept(TVisitor.Create);
Note: aModel is a weak reference in this case.
--
Best regards,
Chau Chee Yang
E Stream Software Sdn Bhd
URL: www.sql.com.my
SQL Financial Accounting
 
 

Re:Relation of Model, Command and Selection

"Chau Chee Yang" <XXXX@XXXXX.COM>a écrit dans le message de news:
4451d22d$XXXX@XXXXX.COM...
| If an interactor trigger the model's command. The command suppose to
| work on the selection. However, there are chances that the command will
| refer to model too. Thus, we have this design:
The trick here is not to use Interactors to trigger Commands. Commands are
linked to UI "command widgets" like buttons or menu items.
| TCommand = class
| private
| fSelection: ISelection;
| procedure BindSelection(const Selection: ISelection);
| public
| constructor Create(const aModel: IModel);
| end;
|
| If seems redundant for the Command to know both model and selection as
| the model already know selection. If the command want to work on
| selection, it can refer to model:
Commands that operate on a list model like Insert, Delete, etc need to have
the list that is in the Model as well as the Selection which denotes which
item is to be deleted or to be inserted before.
Joanna
--
Joanna Carter [TeamB]
Consultant Software Engineer
 

Re:Relation of Model, Command and Selection

Quote
| TCommand = class
| private
| fSelection: ISelection;
| procedure BindSelection(const Selection: ISelection);
| public
| constructor Create(const aModel: IModel);
| end;
|
| If seems redundant for the Command to know both model and selection as
| the model already know selection. If the command want to work on
| selection, it can refer to model:

Commands that operate on a list model like Insert, Delete, etc need to have
the list that is in the Model as well as the Selection which denotes which
item is to be deleted or to be inserted before.
I don't get the ideas. For example, I have a list model and command:
TModel = class(IModel)
public
property List: TItemList;
property Selection: ISelection;
end;
TInsertCommand = class
private
fModel: pointer;
fSelection: ISelection;
public
constructor Create(const aModel: IModel);
procedure BindSelection(const aSelection: ISelection);
procedure Execute;
end;
constructor TInsertCommand.Create(const aModel: IModel);
begin
fModel := pointer(aModel);
end;
procedure TInsertCommand.BindSelection(const aSelection: ISelection);
begin
fSelection := ISelection;
end;
procedure TInsertComamnd.Execute;
begin
(fModel as IModel).List.Add('New Item');
end;
TDeleteCommand = class
private
fModel: pointer;
fSelection: ISelection;
public
constructor Create(const aModel: IModel);
procedure BindSelection(const aSelection: ISelection);
procedure Execute;
end;
procedure TDeleteCommand.Delete;
var i: integer;
M: IModel;
begin
M := fModel as IModel;
for i := 0 to M.Selection.Count - 1 do begin
M.List.DeleteItem(M.Selection.Items[i]);
end;
end;
It seems like I can perform list command without the need to use
fSelection member in Command that was assigned using BindCommand. I
still don't get the picture.
--
Best regards,
Chau Chee Yang
E Stream Software Sdn Bhd
URL: www.sql.com.my
SQL Financial Accounting
 

Re:Relation of Model, Command and Selection

"Chau Chee Yang" <XXXX@XXXXX.COM>a écrit dans le message de news:
4451ee3d$XXXX@XXXXX.COM...
| I don't get the ideas. For example, I have a list model and command:
| procedure TInsertComamnd.Execute;
| begin
| (fModel as IModel).List.Add('New Item');
| end;
Should be :
procedure TInsertComamnd.Execute;
var
IModel: modelIntf;
begin
// create new instance of list.ItemType
modelIntf := fModel as IModel;
modelIntf.List.Insert(modelIntf.List.IndexOf(fSelection[0]), newItem);
end;
| procedure TDeleteCommand.Delete;
| var i: integer;
| M: IModel;
| begin
| M := fModel as IModel;
| for i := 0 to M.Selection.Count - 1 do begin
| M.List.DeleteItem(M.Selection.Items[i]);
| end;
| end;
| It seems like I can perform list command without the need to use
| fSelection member in Command that was assigned using BindCommand. I
| still don't get the picture.
procedure TDeleteCommand.Execute;
var i: integer;
M: IModel;
begin
M := fModel as IModel;
for i := 0 to fSelection.Count - 1 do begin
M.List.DeleteItem(fSelection.Items[i]);
end;
end;
You can do things in many different ways. You could also change the
Command.Execute signature to include a Target parameter which could be the
list, that way you don't have to include the Model in the constructor for
the Command.
Don't forget, the articles you are reading are not the whole solution, they
are glimpses of early attempts to get a good design. This news group is also
part of the development process, allowing us to argue through emerging ideas
and designs that have evolved since publication :-)
Joanna
--
Joanna Carter [TeamB]
Consultant Software Engineer
 

Re:Relation of Model, Command and Selection

Joanna Carter [TeamB] writes:
Quote
"Chau Chee Yang" <XXXX@XXXXX.COM>a écrit dans le message de news:
4451ee3d$XXXX@XXXXX.COM...

| I don't get the ideas. For example, I have a list model and command:

| procedure TInsertComamnd.Execute;
| begin
| (fModel as IModel).List.Add('New Item');
| end;

Should be :

procedure TInsertComamnd.Execute;
var
IModel: modelIntf;
begin
// create new instance of list.ItemType
modelIntf := fModel as IModel;
modelIntf.List.Insert(modelIntf.List.IndexOf(fSelection[0]), newItem);
end;

| procedure TDeleteCommand.Delete;
| var i: integer;
| M: IModel;
| begin
| M := fModel as IModel;
| for i := 0 to M.Selection.Count - 1 do begin
| M.List.DeleteItem(M.Selection.Items[i]);
| end;
| end;

| It seems like I can perform list command without the need to use
| fSelection member in Command that was assigned using BindCommand. I
| still don't get the picture.

procedure TDeleteCommand.Execute;
var i: integer;
M: IModel;
begin
M := fModel as IModel;
for i := 0 to fSelection.Count - 1 do begin
M.List.DeleteItem(fSelection.Items[i]);
end;
end;

You can do things in many different ways. You could also change the
Command.Execute signature to include a Target parameter which could be the
list, that way you don't have to include the Model in the constructor for
the Command.

Don't forget, the articles you are reading are not the whole solution, they
are glimpses of early attempts to get a good design. This news group is also
part of the development process, allowing us to argue through emerging ideas
and designs that have evolved since publication :-)
Yes, it could be done as the way you propose. However, does it imply
that the Model don't need to have a selection member?
TModel = class(IModel)
public
property List: TItemList;
property Selection: ISelection; // <-- this can remove
end;
Any changes to the model that affect the selection will immediately
reflects in command's BindSelection?
However, it seems we can not remove selection from model. The selection
has to be there to hold the selected items and notify the commandset of
the changes and finally bind the selection to commands.
Then my thought back to the problem I raised in the first post. Why we
should bind selection to command where the command could have get the
selection from model?
I am sorry that I still can not get out of the endless loop. :(
--
Best regards,
Chau Chee Yang
E Stream Software Sdn Bhd
URL: www.sql.com.my
SQL Financial Accounting
 

Re:Relation of Model, Command and Selection

"Chau Chee Yang" <XXXX@XXXXX.COM>a écrit dans le message de news:
XXXX@XXXXX.COM...
| Yes, it could be done as the way you propose. However, does it imply
| that the Model don't need to have a selection member?
No, don't forget the selection is a list that can be empty and when you bind
a Command to the Selection it then is able to see that list. Some Commands
will (de)activate themselves depending on the state of the Selection.
You can also have a CommandSet where the Commands are added/removed
depending on the state of the Selection in the Model.
| However, it seems we can not remove selection from model. The selection
| has to be there to hold the selected items and notify the commandset of
| the changes and finally bind the selection to commands.
Correct
| Then my thought back to the problem I raised in the first post. Why we
| should bind selection to command where the command could have get the
| selection from model?
Play with the different ideas and let us know what conclusions you reach
after you have stress-tested the options in a real-world scenario.
Joanna
--
Joanna Carter [TeamB]
Consultant Software Engineer
 

Re:Relation of Model, Command and Selection

Quote
| However, it seems we can not remove selection from model. The selection
| has to be there to hold the selected items and notify the commandset of
| the changes and finally bind the selection to commands.

Correct

| Then my thought back to the problem I raised in the first post. Why we
| should bind selection to command where the command could have get the
| selection from model?

Play with the different ideas and let us know what conclusions you reach
after you have stress-tested the options in a real-world scenario.
If I follow a way you proposed:
"You can do things in many different ways. You could also change the
Command.Execute signature to include a Target parameter which could be
the list, that way you don't have to include the Model in the
constructor for the Command."
procedure TDeleteCommand.Execute(const aList);
var i: integer;
begin
for i := 0 to fSelection.Count - 1 do begin
aList.DeleteItem(fSelection.Items[i]);
end;
end;
Then the command doesn't need to know Model and the BindSelection is
necessary in this case.
However, if the Command.Execute will refer to some properties in Model
if an item can be delete, then we need the model in command:
procedure TDeleteCommand.Execute;
var i: integer;
M: IModel;
begin
M := fModel as IModel;
if M.CanDelete then begin
for i := 0 to M.Selection.Count - 1 do begin
M.List.DeleteItem(M.Selection.Items[i]);
end;
end;
end;
Of course the including of list parameter in execute method is a more
reusable ways that don't depends on model.
I still don't see why there is a need to bind selection to command in
later situation. Can we also design the command not known of selection
too but to get it from model. Or we must bind selection in most
situations. Perhaps there are drawbacks I not known yet...
--
Best regards,
Chau Chee Yang
E Stream Software Sdn Bhd
URL: www.sql.com.my
SQL Financial Accounting
 

Re:Relation of Model, Command and Selection

Joanna Carter [TeamB] writes:
Quote
"Chau Chee Yang" <XXXX@XXXXX.COM>a écrit dans le message de news:
XXXX@XXXXX.COM...

| Yes, it could be done as the way you propose. However, does it imply
| that the Model don't need to have a selection member?

No, don't forget the selection is a list that can be empty and when you bind
a Command to the Selection it then is able to see that list. Some Commands
will (de)activate themselves depending on the state of the Selection.

You can also have a CommandSet where the Commands are added/removed
depending on the state of the Selection in the Model.
Now I got what you meant. The usage of BindSelection is to provide a
mechanism to inform the Command to perform some initial task. A typical
example is enable/disable the command.
Thank you.
--
Best regards,
Chau Chee Yang
E Stream Software Sdn Bhd
URL: www.sql.com.my
SQL Financial Accounting