Having trouble achiving OOP zen

J

Jeremy Cowles

Hi all,

Disclaimer: This app is actually written in a different language, but I have
much respect for this group & wanted to get your input so please ignore any
minor syntactical errors.

I have a program that needs to perform an action: Inventory Adjustment.
This action takes several arguments:

Data to describe which item to adjust:
- Site
- Item
- Lot
- Serial #

The adjustment(s) to make:
- Quantity
- Expire Date

Goals: I have two user interfaces (Telnet/VT100 & Windows GUI), so I want to
use one set of validation code for both of them. Furthermore I don't want
any GUI code to be directly dependant on the DataAccess objects & methods.

So I was thinking this:

Class InventoryAdjustment
{
Private:
string site_id, item_id, lot, serial_no;

Public:
void setSite( site );
void setItem( item );
void setLot( lot );
void setSerial( serial );
void Adjust( qty, expire_dt );
};

So the validation functions look up the parameter, and throw an error if it
is not valid data, or save it for the Adjustment if it is valid: setSite(
site_id ) calls the data access object, which has a method bool
SiteIsValid(site_id), which in-turn runs the queries against our data.

Then, when Adjust( ) is called, it uses the stored data & the 2 input params
to perform the adjustment. I realize this approach is flawed, and that
perhaps something like this would be better:

Class Inventory
{
Public:
bool Adjust( site_id, item_id, lot, serial_no, qty, expire_dt );
// other actions to perform against inventory
}

But this doesn't provide any validation for the UI's. I guess I just need
some input, because I am starting to loose my mind. Am thinking too hard
about this?

TIA,
Jeremy
 
A

Alf P. Steinbach

Disclaimer: This app is actually written in a different language, but I have
much respect for this group & wanted to get your input so please ignore any
minor syntactical errors.

There is nothing concerning C++ in your question.

So it is off-topic in [comp.lang.c++].

I suggest [comp.programming], to which this reply is crossposted, and
follow-ups redirected.



I have a program that needs to perform an action: Inventory Adjustment.
This action takes several arguments:

Data to describe which item to adjust:
- Site
- Item
- Lot
- Serial #

Is _all_ of this required to identify the item?

What is 'Item'?

Anyways, to start with the above yields a class ItemId.


The adjustment(s) to make:
- Quantity
- Expire Date

These are presumably attributes of Item.


Goals: I have two user interfaces (Telnet/VT100 & Windows GUI), so I want to
use one set of validation code for both of them. Furthermore I don't want
any GUI code to be directly dependant on the DataAccess objects & methods.

So I was thinking this:

Class InventoryAdjustment
{
Private:
string site_id, item_id, lot, serial_no;

Public:
void setSite( site );
void setItem( item );
void setLot( lot );
void setSerial( serial );
void Adjust( qty, expire_dt );
};

Good brainstorming.

I suggest (1) removing the Adjust-method, in effect, the knowledge of Item
innards, (2) removing the first four methods, replace by a member of type
ItemId, which should be initialized by and only by constructor(s), (3) add
getters and setters or possibly just public members for qty and expire_dt.

Hm, with that it's something else: not a "doer" class, but a class where
each instance _specifies_ an adjustment to be made.


So the validation functions look up the parameter, and throw an error if it
is not valid data, or save it for the Adjustment if it is valid: setSite(
site_id ) calls the data access object, which has a method bool
SiteIsValid(site_id), which in-turn runs the queries against our data.

Then, when Adjust( ) is called, it uses the stored data & the 2 input params
to perform the adjustment. I realize this approach is flawed, and that
perhaps something like this would be better:

Not better: needed _in addition_.


Class Inventory
{
Public:
bool Adjust( site_id, item_id, lot, serial_no, qty, expire_dt );
// other actions to perform against inventory
}

But this doesn't provide any validation for the UI's.

Oh yes it does, it's the final server-side validation.

Earlier on you will have validated that the InventoryAdjustment
instance (which should replace the current arguments of Adjust) is
valid as far as the client side is able to determine.

It's a two-step process: validate as much as possible on the client
side, then final validation in the outermost level of server-side.


XFUT: [comp.programming]
 
J

Jeffrey Schwab

Jeremy said:
Hi all,

Disclaimer: This app is actually written in a different language, but I have
much respect for this group & wanted to get your input so please ignore any
minor syntactical errors.

I have a program that needs to perform an action: Inventory Adjustment.
This action takes several arguments:

Data to describe which item to adjust:
- Site
- Item
- Lot
- Serial #

The adjustment(s) to make:
- Quantity
- Expire Date

Goals: I have two user interfaces (Telnet/VT100 & Windows GUI), so I want to
use one set of validation code for both of them. Furthermore I don't want
any GUI code to be directly dependant on the DataAccess objects & methods.

Are you trying to implement a strict Model/View/Controller architecture?
So I was thinking this:

Class InventoryAdjustment
{
Private:
string site_id, item_id, lot, serial_no;

Public:
void setSite( site );
void setItem( item );
void setLot( lot );
void setSerial( serial );
void Adjust( qty, expire_dt );
};

So the validation functions look up the parameter, and throw an error if it
is not valid data, or save it for the Adjustment if it is valid: setSite(
site_id ) calls the data access object, which has a method bool
SiteIsValid(site_id), which in-turn runs the queries against our data.

Then, when Adjust( ) is called, it uses the stored data & the 2 input params
to perform the adjustment. I realize this approach is flawed, and that
perhaps something like this would be better:

Class Inventory
{
Public:
bool Adjust( site_id, item_id, lot, serial_no, qty, expire_dt );
// other actions to perform against inventory
}

But this doesn't provide any validation for the UI's. I guess I just need
some input, because I am starting to loose my mind. Am thinking too hard
about this?

TIA,
Jeremy

How about this:

struct InventoryController
{
void Adjust( Site, Item, Lot, SerialNo, ExpirationDate );
}

-Jeff
 
V

Victor Bazarov

Jeremy Cowles said:
Disclaimer: This app is actually written in a different language, but I have
much respect for this group & wanted to get your input so please ignore any
minor syntactical errors.
[...]

2 recommendations:
"Advanced C++: Programming Styles and Idioms" by James Coplien

Victor
 
C

Cy Edmunds

Jeremy Cowles said:
Hi all,

Disclaimer: This app is actually written in a different language, but I have
much respect for this group & wanted to get your input so please ignore any
minor syntactical errors.

I have a program that needs to perform an action: Inventory Adjustment.
This action takes several arguments:

Data to describe which item to adjust:
- Site
- Item
- Lot
- Serial #

The adjustment(s) to make:
- Quantity
- Expire Date

Goals: I have two user interfaces (Telnet/VT100 & Windows GUI), so I want to
use one set of validation code for both of them. Furthermore I don't want
any GUI code to be directly dependant on the DataAccess objects & methods.

So I was thinking this:

Class InventoryAdjustment
{
Private:
string site_id, item_id, lot, serial_no;

Public:
void setSite( site );
void setItem( item );
void setLot( lot );
void setSerial( serial );
void Adjust( qty, expire_dt );
};

So the validation functions look up the parameter, and throw an error if it
is not valid data, or save it for the Adjustment if it is valid: setSite(
site_id ) calls the data access object, which has a method bool
SiteIsValid(site_id), which in-turn runs the queries against our data.

Then, when Adjust( ) is called, it uses the stored data & the 2 input params
to perform the adjustment. I realize this approach is flawed, and that
perhaps something like this would be better:

Class Inventory
{
Public:
bool Adjust( site_id, item_id, lot, serial_no, qty, expire_dt );
// other actions to perform against inventory
}

But this doesn't provide any validation for the UI's. I guess I just need
some input, because I am starting to loose my mind. Am thinking too hard
about this?

TIA,
Jeremy

I don't quite follow exactly what your requirements are, but generally
speaking I have found it useful to write an "abstract UI" which does all the
logical operations (e.g. input validation) but knows nothing about buttons
and things, and a "concrete UI" which knows about buttons and things but
knows as little as possible about the logic. In your case I think you would
write two concrete UI's, one for Telnet and one for Windows GUI. If you do
it right you won't have much trouble adding a third for a web interface,
etc.
 
J

Jerry Coffin

[ ... ]
I have a program that needs to perform an action: Inventory Adjustment.
This action takes several arguments:

IMO, it should take two arguments.
Data to describe which item to adjust:
- Site
- Item
- Lot
- Serial #

IMO, these should be combined into an item_identifier or something on
that order.
The adjustment(s) to make:
- Quantity
- Expire Date

and these should be combined into an item_data or something on that
order.

[ ... ]
Public:
void setSite( site );
void setItem( item );
void setLot( lot );
void setSerial( serial );
void Adjust( qty, expire_dt );

IMO, this is a rather poor design -- at least as I read things, it means
that adjusting one item requires that you call 5 functions in a row.
Furthermore, calling Adjust() when you haven't just called the other
four functions is probably an error. IOW, you're creating a modal
interface, which is something you _generally_ want to avoid if you can.

In this case it's easy to avoid: you have:

int adjust(item_identifier const &item, item_data const &data) {

real_item *r;

if ( !verify(item))
return BAD_ID;

if ( NULL == (r=lookup(item)))
return NO_ITEM;

if ( ! real_item->set_value(data))
return BAD_VALS;
}

Note that doing this in a single operation does NOT prevent you from
checking all the parameters. For the moment, I've used a single,
generic BAD_ID to identify all bad IDs, but in reality, you can have
verify return a value indicating what was bad in the ID, and pass that
through to the outside world. Likewise with the values -- if a value is
out of bounds (for example) your return could indicate which one and
what was bad about the value.

Keep in mind that all the OOP stuff is, in the end, supposed to make
your programs simpler, largely by making an object more independent and
intelligent. An object that takes five function calls to accomplish one
simple action defeats the purpose.
 
J

Jeremy Cowles

So I should: stop posting in the wrong group, read a book about OOP models
in C++, remove my validation code from he actual logic, and make a layer
between the physical UI and the logic.

Thanks, everyone, for your replies.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top