On Sun, Feb 22, 2009 at 11:23 PM, Christian Catchpole <
[email protected]> wrote:
>
> I guess there is no right or wrong to most patterns, it's just a
> matter of taste. My person opinion is that ThreadLocals are a bit of
> a hack. I'm an advocate for optimizing interfaces, reducing boiler
> plate and minimizing code. But I drew the line when it breaks some
> fundamental paradigms.
>
> Readers will have heard me complain about the "returning self" builder
> pattern.
>
> new Thing().setOne().setTwo()
Ah, this reminds me...
I've grown more and more fond of using instance-initializers.
It produces more declarative looking code:
someArea = new JTextArea(10, 20){
{
setLineWrap(true);
setBorder(BorderFactory.createLineBorder(Color.BLACK));
setMaximumSize(new
Dimension(100,100));
setBackground(Color.RED);
}};
Pros with this approach is that you don't loiter the code, it's apparent
that the code belongs to the created instance,
you can make all "construction-time only" methods into "protected" so
they're not accessible from outside object creation (thus encouraging
information hiding etc)
This allows you to write stuff like:
public abstract class Foo
{
private Bar bar;
private Baz baz;
protected void setBar(Bar bar) { this bar = bar; }
protected void setBaz(Baz baz) { this baz = baz; }
public Bar getBar() { return this.bar; }
public Baz getBaz() { return this.baz; }
}
then in other package:
{
Foo myFoo = new Foo(){{
setBar(someBar);
setBaz(someBaz);
}};
myFoo.setBar(null); //Not visible
myFoo.getBar(); //Visible
}
>
> Why should the API change so my code can be a little more compact?
>
> There is talk of adding 'returning self' as a language feature. I
> can't understand why we don't implement a globally applicable language
> feature that doesn't change APIs and works on existing code. Having a
> method return (this) at the end is somewhat broken.. If not just plain
> strange.
>
> using (new Thing()) { setOne(); setTwo() } // override the default
> 'this.' within the block.
>
> But that's another thread. :)
>
> I guess ThreadLocal is more of an accepted pattern, even if I don't
> like it.
>
> ThreadLocal assumes you code is running on that and only that thread.
> It also can cause problem with garbage collection (entities don't get
> collected when they should).
>
> On Feb 23, 7:20 am, Christian Hvid <[email protected]> wrote:
> > There is a built-in connection pool and you are right; there is no
> > overhead in closing and opening a pooled connection.
> >
> > But you still have to say what database is used. And here it is the
> > database the caller is using unless explicitly stated otherwise.
> >
> > Wrt. ThreadLocal - the way it is used here is a bit like context
> > passing in AspectJ.
> >
> > I don't think it is evil. It is just not commonly used in Java. But it
> > has its merits and here it serves the purpose of reducing boiler plate
> > code.
> >
> > On Feb 22, 9:51 pm, Christian Catchpole <[email protected]>
> > wrote:
> >
> > > I think stageful statics are evil. I think ThreadLocal should be cast
> > > into a large pit and burried. :)
> >
> > > Isn't connection management a non-issue in web containers and even
> > > stand along apps with a good connection pool. When you open and close
> > > a connection, you are just borrowing a slot in a pool. There is no
> > > expense to it. In fact the pool will do clever things such as match
> > > prepared statements to connections which it has already been prepared
> > > on.
> >
> > > I'm simply suggesting that you might be able to get away with hiding
> > > the connection management.
> >
> > > I'm not trying to discourage your work. I have written a persistence
> > > layer which takes a completely different approach again.
> >
> > > Nice name by the way. :)
> >
> > > On Feb 23, 5:58 am, Christian Hvid <[email protected]> wrote:
> >
> > > > :-D
> >
> > > > Great, exactly.
> >
> > > > This is the point - it removes a lot of code - it is magic - and thus
> > > > smells of ... air - unless you are used to it.
> >
> > > > You avoid carrying around a JDBC connection object or a reference to
> > > > something like jdbcTemplate.
> >
> > > > Suppose you write a web application and in your servlet code or page
> > > > code you have a single try finally block that opens and closes the
> > > > database connection.
> >
> > > > Within that block you call into your business code and your business
> > > > code uses various database queries - all against the connection that
> > > > you manage with the try catch block.
> >
> > > > The reason it is a stack of connections and just one connection - is
> > > > that a stack allows you to use multiple databases / connections - so
> > > > this would work:
> >
> > > > public long accountBalance(int accountId) {
> > > > openConnection("accounting");
> > > > try {
> > > > return queryScalar(Integer.class, "select balance from account
> > > > where id=?", accountId);
> > > > } finally {
> > > > closeConnection();
> > > > }
> >
> > > > }
> >
> > > > int accountId = 27;
> >
> > > > try {
> > > > openConnection("logging");
> > > > update("insert into log(account_id, balance) values(?, ?)",
> > > > accountId, accountBalance(accountId));} finally {
> >
> > > > closeConnection();
> >
> > > > }
> >
> > > > On Feb 22, 7:59 pm, Robert Fischer <[email protected]
> >
> > > > wrote:
> >
> > > > > Now you've shifted the problem from a plumbing issue to a magical
> state issue. This is a major code
> > > > > smell and complicates the API in nonobvious (to the user) ways.
> >
> > > > > (Of course, I'm the guy who also finalizes his method arguments.
> So I've got some wacky opinions
> > > > > relative to Java norms.)
> >
> > > > > ~~ Robert.
> >
> > > > > Christian Hvid wrote:
> > > > > > But you can leave it up to the caller to open the connection -
> meaning
> > > > > > you just don't open or close any connections.
> >
> > > > > > public int getUserCount() {
> > > > > > return queryScalar(Integer.class, "select count(*) from
> people");
> > > > > > }
> >
> > > > > > And then have the calling code open and close the connection:
> >
> > > > > > openConnection();
> > > > > > try {
> > > > > > ...
> > > > > > getUserCount();
> > > > > > ...
> > > > > > } finally {
> > > > > > closeConnection();
> > > > > > }
> >
> > > > > > (The idea is that there is a stack of connections and when you do
> > > > > > something you always use the connection at the top of the stack.)
> >
> > > > > > On Feb 22, 7:24 pm, Robert Fischer <
> [email protected]>
> > > > > > wrote:
> > > > > >> The problem is this code:
> >
> > > > > >> public int getUserCount() {
> > > > > >> openConnection();
> > > > > >> try {
> > > > > >> return queryScalar(Integer.class, "select
> count(*) from people");
> > > > > >> } finally {
> > > > > >> closeConnection();
> > > > > >> }
> >
> > > > > >> }
> >
> > > > > >> That's 1 semantically meaningful line surrounded by 5 lines of
> boilerplate plumbing. Which means
> > > > > >> that it's really 1/6th actual code, and 5/6th noise. That's a
> pretty poor signal to noise ratio.
> >
> > > > > >> It's even worse when you're dealing with raw JDBC calls, since
> you have to think about preparing
> > > > > >> statements and managing connections and data sets and the like.
> >
> > > > > >> ~~ Robert.
> >
> > > > > >> Christian Hvid wrote:
> > > > > >>> I don't understand - why would that be a problem? (That you
> have
> > > > > >>> explictly open and close your database connection).
> > > > > >>> On Feb 22, 7:09 pm, Robert Fischer <
> [email protected]>
> > > > > >>> wrote:
> > > > > >>>> +1 for Spring JDBC: it manages all that
> openConnection/closeConnection noise for you, which means
> > > > > >>>> that your JDBC code can *also* start to be expressive.
> > > > > >>>> ~~ Robert.
> > > > > >>>> Rakesh wrote:
> > > > > >>>>> have you looked at Spring JDBC? It has a similar interface
> and manages
> > > > > >>>>> the connections for you.
> > > > > >>>>> I think if you go down a non-orm route and want to have lots
> of sql,
> > > > > >>>>> Ibatis is quite common - not used it so can't say for sure.
> > > > > >>>>> Spring JDBC though is very nice and have used it extensively.
> > > > > >>>>> Rakesh
> > > > > >>>>> On Sun, Feb 22, 2009 at 2:21 PM, Christian Hvid
> > > > > >>>>> <[email protected]> wrote:
> > > > > >>>>>> Hi Java people.
> > > > > >>>>>> I have been toying with simplier ways of doing embedded SQL
> in Java.
> > > > > >>>>>> And would like your comments on this one?
> > > > > >>>>>>http://code.google.com/p/chalkmine/
> > > > > >>>>>> It allows you to write code like this:
> > > > > >>>>>> openConnection();
> > > > > >>>>>> try {
> > > > > >>>>>> int count = queryScalar(Integer.class, "select count(*)
> from
> > > > > >>>>>> people");
> > > > > >>>>>> System.out.println("There are "+count+" people in the
> bin.");
> > > > > >>>>>> } finally {
> > > > > >>>>>> closeConnection();
> > > > > >>>>>> }
> > > > > >>>>>> or
> > > > > >>>>>> openConnection();
> > > > > >>>>>> try {
> > > > > >>>>>> List<Person> people = queryList(Person.class, "select
> name,
> > > > > >>>>>> time_in_the_bin from people");
> > > > > >>>>>> for (Person p : people)
> > > > > >>>>>> System.out.println(p.getName()+" has been
> "+p.getTimeInTheBin()
> > > > > >>>>>> +" hours in the bin.");
> > > > > >>>>>> } finally {
> > > > > >>>>>> closeConnection();
> > > > > >>>>>> }
> > > > > >>>>>> (Provided that Person has a constructor matching the types
> of name,
> > > > > >>>>>> time_in_the_bin. Probably Person(String, int).)
> > > > > >>>>>> Where the methods openConnection, queryScalar, queryList,
> > > > > >>>>>> closeConnection are statically imported.
> > > > > >>>>>> openConnection() figures out the name of the calling class,
> looks up a
> > > > > >>>>>> configuration, opens a connection and puts in a ThreadLocal
> container.
> > > > > >>>>>> queryScalar(Class, String, ...) performs a query with a
> single row
> > > > > >>>>>> result that is "cast" to the given class.
> > > > > >>>>>> queryList(Class, String, ...) performs a query and returns
> the result
> > > > > >>>>>> as a list of the given class.
> > > > > >>>>>> I would like to turn it into a full-fledged open source
> project.
> > > > > >>>>>> But since it is incredibly hard for a new open source
> project to gain
> > > > > >>>>>> traction I would like to figure out whether it is
> interesting enough
> > > > > >>>>>> first.
> > > > > >>>>>> -- Christian
> > > > > >>>> --
> > > > > >>>> ~~ Robert Fischer.
> > > > > >>>> Grails Training http://GroovyMag.com/training
> > > > > >>>> Smokejumper Consultinghttp://SmokejumperIT.com
> > > > > >>>> Enfranchised Mind Bloghttp://EnfranchisedMind.com/blog
> > > > > >>>> Check out my book, "Grails Persistence with GORM and GSQL"!
> http://www.smokejumperit.com/redirect.html
> > > > > >> --
> > > > > >> ~~ Robert Fischer.
> > > > > >> Grails Training http://GroovyMag.com/training
> > > > > >> Smokejumper Consultinghttp://SmokejumperIT.com
> > > > > >> Enfranchised Mind Bloghttp://EnfranchisedMind.com/blog
> >
> > > > > >> Check out my book, "Grails Persistence with GORM and GSQL"!
> http://www.smokejumperit.com/redirect.html
> >
> > > > > --
> > > > > ~~ Robert Fischer.
> > > > > Grails Training http://GroovyMag.com/training
> > > > > Smokejumper Consultinghttp://SmokejumperIT.com
> > > > > Enfranchised Mind Bloghttp://EnfranchisedMind.com/blog
> >
> > > > > Check out my book, "Grails Persistence with GORM and GSQL"!
> http://www.smokejumperit.com/redirect.html
> >
>
--
Viktor Klang
Senior Systems Analyst
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "The
Java Posse" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/javaposse?hl=en
-~----------~----~----~----~------~----~------~--~---