• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Question: static modelling

 
Ranch Hand
Posts: 72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I've been looking into static modelling these days. Larman's book told us basically nouns can be regarded as concepts, thus designed as objects. I remember when I studied database design, instructors also told me to look at noun for potential tables.
So can we say database design and UML class diagram are using same method? Does all the tables in the database will have a wrapper class in the application?
Thank you for clarification.
 
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In my experience, it tends to be the case that different people develop the objects and the database. There are a lot of similarities in the work though. DBAs for relational databases like to use Entity-Relation-Attribute diagrams when modelling the database. ERAs are very similar to class diagrams.
When I design classes, I don't usually start from the database. But if the DBA has done a good job, there tends to be a one-to-one correspondence between the classes and the database tables. Of course, some classes are more large-grained and through composition, you might actually be mapping one class to several tables but again, with a good database design, the mapping isn't that difficult.
 
Sheriff
Posts: 7001
6
Eclipse IDE Python C++ Debian Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I tend to think this is a dangerous oversimplification for real software. I've noticed a tendency for systems "designed" this way to have lots of classes whose sole responsibility is to hold some data (typically a constructor and a bubch of getters and setters). In good O-O design, there should be no objects which just hold data, objects should be defined by their actions and collaboratons.
A database table design is a static picture of the "categories" of information in the system. There is one of each type of table. An O-O design is a dynamic picture of the possible collaborations and relationships between objects. There can be none, one or many of each class of object.
The purpose of a database is to hold data, in a form which allows straight-forward access to all the "categories" of information in the system. Database table design needs to be aware of issues like normalization and performance.
If you start by looking at all the jobs in a system, and then group associated jobs into resposibilities, then assign those responsibilities to objects, in collaboration with other objects, your O-O design will be in much better shape.
 
lydia westland
Ranch Hand
Posts: 72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you for your replies. I do agree that behaviors and responsibility are very important in OO design. By Larman's method, we identify all kinds of nouns, i.e. entities first. That's exactly what I do for database design. And in my OO design, I seldom has classes called "User", "Customer", "Company", etc, which tends to appear as tables in database. In constrcat, I have classes called "Processor", "Scheduler", "Examiner", which are neither Actor in in Use Cases nor tables in database.
I do have questions about how to make good designs that better fit for appliations with dtabase.
As the database gets more power, Database can do a lot of jobs as well. For example, I'm involved in a project for PC scheduling. We can either use program to do the scheduling, or let database decide how to schedule a particular session. Seems the second solution is better, because database has all the information for scheduling. So I passed the input to database, and let a stored procedure handle the rest of work. In this sense, database can acts like classes and objects.
Can anyone recommend some design principles? what kind of jobs are done by database, and what done by program? All advice is appreciated.
 
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Posted by Frank Carver:
In good O-O design, there should be no objects which just hold data, objects should be defined by their actions and collaboratons


I strongly disagree. In good O-O design you may need objects which just hold data. They are particularly useful in distributed applications. I don't find the sentence "there should be no objects which just hold data" good as a general rule, though a lot of people think the same.
 
Frank Carver
Sheriff
Posts: 7001
6
Eclipse IDE Python C++ Debian Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Eduard Jodas wrote: I strongly disagree. In good O-O design you may need objects which just hold data
In my own experience many such cases have turned out not really to be needed, so I tend to deprecate such usage as a general rule. I'd like to explore the situations where you have found such objects useful. Can you give us an example situation where such an object is needed, to base a discussion around?
 
Frank Carver
Sheriff
Posts: 7001
6
Eclipse IDE Python C++ Debian Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
lydia westland wrote: So I passed the input to database, and let a stored procedure handle the rest of work. In this sense, database can acts like classes and objects.
I don't want to baldly present one of my working rules as an absolute law, but I have found that you need to be very careful when considering this. I am strongly against putting "business rules" in stored procedures - they are too difficult to change and embody a conflict of interest between database optmisation and code clarity/reusability. They also lock you in to a particular database vendor, and often into a particular version of a database product.
I speak from experience here, I've just finished working on a project where the 50,000+ lines of PL/SQL effectively locked the application into Oracle 7.3.4, a version no longer supported by Oracle!
Sure, use the power of the database to create "views" which are denormalised and more appropriate to your scheduling, but keep the algorithms themselves out in the easily-changed, easily reused, easily understood, easily tested O-O world.
 
Eduard Jodas
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Frank Carver wrote:
I'd like to explore the situations where you have found such objects useful. Can you give us an example situation where such an object is needed, to base a discussion around?


For example the project I'm working in know:
1. we have several POS machines with an application that holds products, customers, sales and so on. Once a week this data is refreshed/sent from/to the server via modem
2. we have a server that stores absolutely all the information, with an application for data maintennance
3. unfortunately the POS systems and the server can't communicate directly, so we are developing a bridge.
When some data changes in the server, this data is sent to the bridge (once a week). The bridge stores the data in a local database. When a POS machine calls, the bridge receives the sales and stores them in the local database. After that the bridge sends to the POS the product/customer/other data changed by the server. Once a day the server retrieves the sales data from the bridge.
So the bridge is just that, a bridge. It translates bytes received from the server into data to store it in the database. It also translates the stored data into bytes to send them to the POS and viceversa. The general architecture for the bridge is:
- the data: Product, Sale, Credit Card, etc. They are objects without responsabilities/associations. Only hold data attributes plus getter/setter methods
- ServerComunicationManager: manages communications with the server. It uses a Formatter to translate bytes into data objects and viceversa
- POSComunicationManager: manages communications with the POS. It uses another Formatter (the POS byte format is different from the server byte format) to translate Data into bytes and viceversa.
- Visualizer: shows the data currently stored in he local database
Though this example may seem extreme, there are other times where "objects which only hold data" are useful. For example the Value Object J2EE design pattern, or when you need to 'send' data across 'layers' in a stand-alone application
 
Frank Carver
Sheriff
Posts: 7001
6
Eclipse IDE Python C++ Debian Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Eduard Jodas wrote: - the data: Product, Sale, Credit Card, etc. They are objects without responsabilities/associations. Only hold data attributes plus getter/setter methods
Is there any particular reason why these objects can't just be one of the Map classes ? The description of the responsibilities you give sounds just like that to me. In particular I feel that your "data" classes have more similarities than differences, so they should probably share some fundammetal behaviour. All that seems to differ between them is the names and types of the data entries.
For efficiency reasons I have in my own "toolkit", what I call a SharedMap :- it's a class which implements Map, but internally is an Object[] and a reference to another Map of name -> index for lookup. These work well when you have lots of immutable Map-style objects with the same entries, as you don't have to keep duplicating all the entry names.
Can you describe how a Formatter typically works? If it is/can be something like:

    do some prolog

    for each field:

    ..look up a field-specific formatter

    ..format the field to the output

    do some epilog

    Then a Map class with built in Iterator support looks a much better choice than a custom data holder with duplicated code each time.
 
Eduard Jodas
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Frank Carver wrote: Is there any particular reason why these objects can't just be one of the Map classes ?
You are right. All my data classes could have been implemented using a Map. The only reason I can think of right now for not using a Map is personal dislike. When I build a Data class (from now on a Data class is a class which only has data) I'm also writing an interface: a Product has a name, a value, a description,... So, when using a Product I'm guaranteed it has a set of defined method/values. A Map doesn't guarantees that. If I change the data contained in a Product (I mean the type, name, etc) the compiler will show me an error whenever the Product is used wrong.
One of the things I don't like about Java is the lack of templates, the impossibility, for example, to restrict the type of objects contained in a Collection.
Anyway, your Map is a generic data holder while my Product is a specific data holder.
Can you describe how a Formatter typically works? If it is/can be something like
You are right, my formatters look like as you wrote.
 
Frank Carver
Sheriff
Posts: 7001
6
Eclipse IDE Python C++ Debian Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Eduard Jodas wrote: The only reason I can think of right now for not using a Map is personal dislike.
I understand that. Many times I have felt the same way. I came to Java from a C and C++ background, and it's a natural feeling, I guess. Map (like all the collections) feels somehow too "loose", for any specific task.
When I build a Data class (from now on a Data class is a class which only has data) I'm also writing an interface: a Product has a name, a value, a description,... So, when using a Product I'm guaranteed it has a set of defined method/values. A Map doesn't guarantees that.
After spending a while writing some SmallTalk, I feel I came to a better understanding of what "pure" O-O feels like. Strangely, the unspecific nature of the collections now seems like a benefit rather than a drawback.
Using a single class for all such data holders reduces code size and testing effort, and allows additional data groups to be added to the system, or the details changed of which fields are in which groups, with no new classes and the changes/recompilation/re-testing can be localised to where the changes are actually needed. I have found this sort of flexibility invaluable in the kind of single-ended communication you describe.
A recent project involved making requests to a legacy C++/PLSQL system which could only give back simply-formatted data (typically TSV text). To get this information into a useful form I could have created a "bean" data holder for each sort of information, but instead chose a single Map-style class. Given a "fetcher" object (details of where to call and what to pass in) a factory for this class could create one and populate it with the results from the legacy system using the SharedMap I referred to above.
If a call returned multiple TSV rows, it was simple to create a List of these Maps, and the client code had no dependency on any of the communication-specific classes.
If I change the data contained in a Product (I mean the type, name, etc) the compiler will show me an error whenever the Product is used wrong.
The "flip side" of this, of course, is that often even a small change to such a class can mean files to edit across the whole system. I prefer, these days, to decouple such things as much as possible, and deal in standard API classes wherever I can.
Anyway, your Map is a generic data holder while my Product is a specific data holder.
Sure. It's just a design philosophy choice, I guess.
 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Frank wrote:
I tend to think this is a dangerous oversimplification for real software. I've noticed a tendency for systems "designed" this way to have lots of classes whose sole responsibility is to hold some data
Good point. I didn't mean to imply that all classes are like this. You often have several layers in an application and it's in the layers that deal with persistence that you tend to find a close correspondence between classes and tables.
As for the Value Object (which Martin Fowler prefers to call the Data Transfer Object) I think it's a useful pattern as long as you don't abuse it. As for using a Map instead, if you're working with a framework, a Map may not be feasible. For example, Struts makes heavy use of reflection to populate ActionForm objects, which, apart from the validate() method, are pretty much data-only objects.
 
Frank Carver
Sheriff
Posts: 7001
6
Eclipse IDE Python C++ Debian Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Junilu wrote: Struts makes heavy use of reflection to populate ActionForm objects, which, apart from the validate() method, are pretty much data-only objects
Hmm. The use of reflection often seems like a "code smell" to me. I can't help thinking that a Map of names to objects wouldn't need reflection to determine what "fields" were needed. You could populate the form just using an Iterator and a few 'instanceof's!
That said, I'm not very familiar with Struts, although it gets a lot of mention here at the Ranch. I will put it in my queue to evaluate it before I offer any more opinions
 
lydia westland
Ranch Hand
Posts: 72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

1. we have several POS machines with an application that holds products, customers, sales and so on. Once a week this data is refreshed/sent from/to the server via modem


Eduard, so your application keeps running all the time, and stores all thed data into the memory? Then does it take up huge memory? how about your system crashes? those data are gone or be exported into harddisk?
From my point of view, once a week reading/writing with the bridge is dangeous.
 
lydia westland
Ranch Hand
Posts: 72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

use the power of the database to create "views" which are denormalised and more appropriate to your scheduling, but keep the algorithms themselves out in the easily-changed, easily reused, easily understood, easily tested O-O world.


Frank, I like your points. but scheduling does need a lot of existing infomation in the database. I am afraid if the performance will be affected if I have too many ResultSet operations. In addition, I can use only one stored procedure to make it. if not, I have to write hundrends of lines of codes in the programe. Seems the solution with database is neat.
It may be DBMS platform dependent. but if we use SQL as much as we can, when we tranfere from one platform to another, we only need modify grammer and syntacs, leaving business logic unchanged. I don't have much experience on this, and I guess it may not be a lot of work.
 
Frank Carver
Sheriff
Posts: 7001
6
Eclipse IDE Python C++ Debian Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't think software design decisions should really be driven by fear. It's been my experience that reasonably well-crafted Java working on ResultSets is often as fast or faster than equaivalent PL/SQL for real problems. But I strongly recommend that you spend a little time coding some realistic tests both ways for your application. No opinion carries more weight than hard evidence.
Stored Procedures are good at making SQL calls to the database, probably faster than Java outside the database. However, stored procedures are not very good at processing data in any other sort of data structure, and the kind of things you typically need in complex algorithms often have to be simulated using temporary tables and the like. This sort of thing can be much slower with stored procedures.
Please don't make assumptions, experiment!
 
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Frank Carver:
I don't think software design decisions should really be driven by fear.


I don't think that fear is the problem. But you should think hard about *what* to fear. (Kent Beck even makes the interesting notion that every process is motivated by fear, btw)
You seem to suggest that instead of fearing that you get an unavoidable performance problem by putting to few logic into the database, you should fear to make wrong assumptions by skipping the experiment.
I think that last fear would be very well advised...
 
Eduard Jodas
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Lydia Westland wrote Eduard, so your application keeps running all the time, and stores all thed data into the memory? Then does it take up huge memory? how about your system crashes? those data are gone or be exported into harddisk?
The POS have flash cards where to store data. In fact I'm just the bridge builder. The bridge automates a task that has been done manualy for some time.
Frank, I like your points. but scheduling does need a lot of existing infomation in the database. I am afraid if the performance will be affected if I have too many ResultSet operations. In addition, I can use only one stored procedure to make it. if not, I have to write hundrends of lines of codes in the programe. Seems the solution with database is neat
One year ago I was involved in another project with Java an Oracle. The project had some processes that needed to be reliable and fast, and used a lot of data from the database. So we decided to develop them with PL/SQL. The Java client had just to call a stored procedure and that was all.
It worked fine at first until some of the processes started to grow in complexity. PL/SQL is not (or was not) O-O and the algorithm design suffered from that. After some time, some of the processes were so huge and bad coded/designed that maintennance work was unbearible. Each modification took a long time and introduced bugs. They were difficult to test so the processes weren't reliable anymore. And even worse, they were slowing down the overall database performance so other applications were 'damaged'.
At last some of the biggest processes were translated to Java: O-O design, better testability and maintenability. The better design allowed us to improve the algorithm so the performance was not so bad. And the database performance was better.
My conclusion: use stored procedures when a task is easy-to-code, needs to be really fast (the net is very slow) and it won't consume a lot of database resources.
 
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Frank Carver:
Eduard Jodas wrote: - the data: Product, Sale, Credit Card, etc. They are objects without responsabilities/associations. Only hold data attributes plus getter/setter methods
Is there any particular reason why these objects can't just be one of the Map classes ? The description of the responsibilities you give sounds just like that to me. In particular I feel that your "data" classes have more similarities than differences, so they should probably share some fundammetal behaviour. All that seems to differ between them is the names and types of the data entries.
For efficiency reasons I have in my own "toolkit", what I call a SharedMap :- it's a class which implements Map, but internally is an Object[] and a reference to another Map of name -> index for lookup. These work well when you have lots of immutable Map-style objects with the same entries, as you don't have to keep duplicating all the entry names.
.


Hi Frank.
I have now become interested in your idea of using maps to store data, based on whats here and in the other thread where we discussed the generic XML API .Thread.
However i am still not clear on how exactly these maps would be used - how you set the names, value types etc. If possible could you post an example to show how exactly you do this?
Thanks,
John
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Frank Carver:
If I change the data contained in a Product (I mean the type, name, etc) the compiler will show me an error whenever the Product is used wrong.
The "flip side" of this, of course, is that often even a small change to such a class can mean files to edit across the whole system. I prefer, these days, to decouple such things as much as possible, and deal in standard API classes wherever I can.


What type of change would force you to edit files across the system when using an explicit Person class, but not when using a Map?
 
Frank Carver
Sheriff
Posts: 7001
6
Eclipse IDE Python C++ Debian Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ilja wrote: What type of change would force you to edit files across the system when using an explicit Person class, but not when using a Map?
Moving it to a different package or changing its name, for example. For you, with Eclipse's automated refactoring at your fingertips, these sweeping changes are not usually a problem. But with manual refactoring it can be a headache and bug source.
That's what I mean by "decoupling" in this case. By choosing as many of my argument and return types from standard APIs as possible, I can help make sure that the impact of things like name and package changes are localized. And as a "free extra", such classes are both much easier to reuse in different projects without dragging in the whole rest of the old project, and easier to test with a smaller toolbox of Mock Objects.
I'm not saying that this is always the best strategy, but in my experience, choosing argument types to be as "basic" (i.e. Map rather than HashMap) and "standard" (i.e. from java. or javax.) as possible for the application can make refactoring and reuse easier.
 
it's a teeny, tiny, wafer thin ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic