From: Graham K. <gr...@da...> - 2004-03-26 10:39:42
|
I have been trying to abstract away database (JDBC) access using these two principles: http://www.mockobjects.com/wiki/OnlyMockYourOwnInterfaces http://www.mockobjects.com/wiki/MockableAdapter Not being able to find a practical example to plagiarise I tried writing my own. A database basically allows the 'put'ing of data and the 'get'ing of data (save / load or executeUpdate / executeQuery). So first cut is (with verbosity removed): public interface Database { // Or should it be DatabaseAdapter ? ReturnType get(String sql); int put(String sql); // Returns number of rows affected } 1) GET What should ReturnType be ? It comes back from the database as a ResultSet, which is an interface and provides everything the caller needs. But it's java.sql.ResultSet, hence not an interface we own. 2) PUT With an INSERT or UPDATE we don't really want to generate the full sql as a string ourselves. It is up to the database vendor to decide how to convert / escape / quote a Date or String, so we really want a PreparedStatement. But again that's java.sql.PreparedStatement. 3) Exceptions Internally SQLException will be flying around, but we can easily wrap that into our own client friendly DatabaseException. But if we are returning ResultSet and allowing PreparedStatement then the caller has to deal with SQLException anyway, so why force them to have two catch clauses ? Our current best effort is (again without the ceremony of javadoc): public interface Database { ResultSet get(String sql) throws DatabaseException; int put(String sql) throws DatabaseException; PreparedStatement prepareStatement(String sql) throws DatabaseException; void close(ResultSet rs); void close(PreparedStatement statement); } and we mock ResultSet and PreparedStatement. I would love to hear how other people have solved this problem. Thanks in advance, Graham. |
From: Steve F. <st...@m3...> - 2004-03-27 23:53:16
|
It sounds like you're trying to write this bottom-up, that is implement a generic db layer and then apply it. You might want to think about writing your persisitence services from the viewpoint of its clients, one case at a time, and then refactoring. Take a case where you need some kind of persistence. Write an interface that provides that persistence /in terms of the client/, using mocks to get you through the test. Now that interface becomes the client of the next persistence layer, gradually becoming more general until you hit JDBC. Combined with Remove Duplication, and Tell, Don't Ask, this should generate a persistence library. Either that, or use something like Hibernate... S. Graham King wrote: > I have been trying to abstract away database (JDBC) access using these > two principles: http://www.mockobjects.com/wiki/OnlyMockYourOwnInterfaces > http://www.mockobjects.com/wiki/MockableAdapter > > Not being able to find a practical example to plagiarise I tried writing > my own. A database basically allows the 'put'ing of data and the > 'get'ing of data (save / load or executeUpdate / executeQuery). > So first cut is (with verbosity removed): > > public interface Database { // Or should it be DatabaseAdapter ? > ReturnType get(String sql); > int put(String sql); // Returns number of rows affected > } > [...] |
From: Graham K. <gr...@da...> - 2004-04-01 08:47:27
|
Nat, Steve, I've been thinking this through and I'm afraid I'm still in the dark. Let's say I have a requirement to create users (say we're writing an admin tool for some other application). The username and password are filled in, some controller gets those, does 'User user = new User(username, password)' and then it must save it to the database. So 'user.save()'. In that save method I used to have JDBC, which for testing I mocked using the mock jdbc classes from mockobjects.com. But if I also have lots of other classes it gets tedious to write all that setup code for the mock objects, and this is why I'm trying to put my own interface between me and jdbc, so I can mock that interface instead of jdbc. What should user.save() do ? Thanks in advance, Graham. Steve Freeman wrote: > It sounds like you're trying to write this bottom-up, that is > implement a generic db layer and then apply it. You might want to > think about writing your persisitence services from the viewpoint of > its clients, one case at a time, and then refactoring. > > Take a case where you need some kind of persistence. Write an > interface that provides that persistence /in terms of the client/, > using mocks to get you through the test. Now that interface becomes > the client of the next persistence layer, gradually becoming more > general until you hit JDBC. Combined with Remove Duplication, and > Tell, Don't Ask, this should generate a persistence library. > > Either that, or use something like Hibernate... > > S. > > Graham King wrote: > >> I have been trying to abstract away database (JDBC) access using >> these two principles: >> http://www.mockobjects.com/wiki/OnlyMockYourOwnInterfaces >> http://www.mockobjects.com/wiki/MockableAdapter >> >> Not being able to find a practical example to plagiarise I tried >> writing my own. A database basically allows the 'put'ing of data and >> the 'get'ing of data (save / load or executeUpdate / executeQuery). >> So first cut is (with verbosity removed): >> >> public interface Database { // Or should it be DatabaseAdapter ? >> ReturnType get(String sql); >> int put(String sql); // Returns number of rows affected >> } > > > [...] > > > |
From: Steve F. <st...@m3...> - 2004-04-03 22:33:45
|
Sorry, I see what you're getting at. You're going in the right direction. There are interesting questions like when does a User object acquire access to a Database object? There are mutiple ways to do it: perhaps have the User talk to a query builder which constructs an object that can be passed to the persistence layer, perhaps just have the User talk SQL (maybe having a thin veneer of stored procedures in the database, depending on your religion), etc, etc. The main thing is to boil the JDBC access down to as few places as possible, as you seem to be doing. Back to you original question. Do we have one ready? No, but I believe there are a few good ones out there on the net. Not sure which to recommend. S. Graham King wrote: > Nat, Steve, > > I've been thinking this through and I'm afraid I'm still in the dark. > > Let's say I have a requirement to create users (say we're writing an > admin tool for some other application). The username and password are > filled in, some controller gets those, does 'User user = new > User(username, password)' and then it must save it to the database. So > 'user.save()'. > > In that save method I used to have JDBC, which for testing I mocked > using the mock jdbc classes from mockobjects.com. But if I also have > lots of other classes it gets tedious to write all that setup code for > the mock objects, and this is why I'm trying to put my own interface > between me and jdbc, so I can mock that interface instead of jdbc. > > What should user.save() do ? > > Thanks in advance, > Graham. > > Steve Freeman wrote: > >> It sounds like you're trying to write this bottom-up, that is >> implement a generic db layer and then apply it. You might want to >> think about writing your persisitence services from the viewpoint of >> its clients, one case at a time, and then refactoring. >> >> Take a case where you need some kind of persistence. Write an >> interface that provides that persistence /in terms of the client/, >> using mocks to get you through the test. Now that interface becomes >> the client of the next persistence layer, gradually becoming more >> general until you hit JDBC. Combined with Remove Duplication, and >> Tell, Don't Ask, this should generate a persistence library. >> >> Either that, or use something like Hibernate... >> >> S. >> >> Graham King wrote: >> >>> I have been trying to abstract away database (JDBC) access using >>> these two principles: >>> http://www.mockobjects.com/wiki/OnlyMockYourOwnInterfaces >>> http://www.mockobjects.com/wiki/MockableAdapter >>> >>> Not being able to find a practical example to plagiarise I tried >>> writing my own. A database basically allows the 'put'ing of data and >>> the 'get'ing of data (save / load or executeUpdate / executeQuery). >>> So first cut is (with verbosity removed): >>> >>> public interface Database { // Or should it be DatabaseAdapter ? >>> ReturnType get(String sql); >>> int put(String sql); // Returns number of rows affected >>> } >> >> >> > [...] >> >> >> > > > ------------------------------------------------------- > This SF.Net email is sponsored by: IBM Linux Tutorials > Free Linux tutorial presented by Daniel Robbins, President and CEO of > GenToo technologies. Learn everything from fundamentals to system > administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click > _______________________________________________ > Mockobjects-java-users mailing list > Moc...@li... > https://lists.sourceforge.net/lists/listinfo/mockobjects-java-users > |