Hi Kevin, I guess we'll have to agree to disagree. You either consider the next person who comes along to maintain your code or you don't.
One thing I should correct you on however is that I never said I was against design for testability. What I disagree with is breaking encapsulation in order to to test code. I unit test my classes' public api and that should be enough. If its not then its a smell and I need to break up the class. As a last resort, I will break encapsulation to test. That's happening less and less as I get better at designing my classes. Also, I DON'T consider the use of getters/setters as something troubling - I have far more important issues to deal with! Cheers Rakesh On Fri, Apr 30, 2010 at 5:21 PM, Kevin Wright <[email protected]> wrote: > > > On 30 April 2010 16:24, Rakesh <[email protected]> wrote: >> >> Hi Kevin, >> >> I don't think you understand the point I am trying to make. Let me sum it >> up: >> >> 1. Source code is for humans NOT for computers. >> 2. Software development is mostly a social activity. >> 3. Good code is subjective. >> >> So with that in mind, I believe the best code is code that is easiest >> to read by the next person that comes along. All I can assume about >> this other person is that they know Java and its established idioms. >> If I stray from the established idioms then I am writing less than >> best code. >> > > Agreed, except for the part about idioms, which I frequently find to be > heavyweight, verbose and poorly maintainable. > 1. Oh so true, yet we persist in this getter/setter paradigm which largely > exists for the sake of frameworks and the need to only express functionality > via interfaces. Does anyone truly believe that this idiom is more readable > to people than public fields? > 2. Which is why I try and keep it as clean and readable as is possible, > eliminating boilerplate and endless chains or rethrown IOExceptions wherever > I can > 3. But some aspects can be largely agreed upon, such as essential vs > accidental complexity. I defy anyone to claim that this: > employees.sort ( > new Comparator{ > public int compare(Object emp1, Object emp2){ > int emp1Age = ( (Employee) emp1).getAge(); > int emp2Age = ( (Employee) emp2).getAge(); > if(emp1Age > emp2Age) { > return 1; > } else if( emp1Age < emp2Age ) { > return -1; > } else { > return 0; > } > } > }; > ); > is preferable to this: > employees.sortBy(_.age) > No setters, no getters, no interfaces, no awkward anonymous classes. Just a > clear concise expression of exactly what needs to be done > >> >> Now, to address your points: >> >> >No, I didn't learn Scala just for that, it was simply the most concise >> > example I could think of. >> >> It may not be Scala-influenced but I've seen code like that written by >> Ruby developers (I think the language automatically provides getters >> and setters for instance fields). Ruby does not seem overly concerned >> with encapsulation but that is not good in the Java world. >> >> >In general, I've been following a trend of moving towards smaller lighter >> > objects, using composition >instead of inheritance, making less >> > implementation private and instead favouring testability, etc... >Scala >> > was >> > just another step along this axis, and taught me some additional tricks >> > that >> > I was able to >port back into Java. >> >> I agree with the lighter objects and using composition instead of >> inheritance. >> >> I disagree with "making less implementation private for testability". >> If you break encapsulation for testability, then you are doing it >> wrong. I'm not saying that it I don't do it but if I do I do it >> reluctantly and because I could not see how else to do it. >> >> Now if you think this is a good idea because of your experience in >> other languages , then I consider that a negative influence on your >> Java. >> > > I couldn't disagree more, not only is design for testability a > cross-language idea, it's also the norm in many other engineering > disciplines. Just browse through Integrated Circuit specifications in any > electronics catalog and you'll see that it's very rare for them to NOT have > a test pin or two. Unit testing and the benefits of designing objects to be > so testable is now a well-established idea in programming. In my > experience, cases where you might want to make functionality private are > indicative of a code smell, and usually suggest that the class in question > is too monolithic. > >> >> As for tricks - the fact that you are reduced to "tricks" means you >> have failed your fellow developer. >> > > mere semantics... "concepts", "ideas", "patterns", "paradigms", > "approaches" would all be valid alternative words here, take your pick! > >> >> >As for "Best Practices", they change! >> >EJB v1 used to be a best practice. Then Spring came along and made >> > everything more lightweight, >then EJB3 and Guice - the trend here is >> > pretty >> > obvious. >> >> Well I think EJB v1 was a standard advocated by Sun and a lot of >> companies used it regardless of merit which was damaging. But what >> does that have to do with this thread? >> > > Surely this thread is all about merit vs the blind use of established > idioms? > >> >> >Boilerplate in Java risks getting ever more burdensome as new features >> > are added (like having to >specify type params twice when instantiating a >> > variable using generics) and Frameworks and >developers are increasingly >> > saying ENOUGH! >> >> Mostly the people complaining about the boilerplate are people who >> have tried other languages. >> These developers who are saying ENOUGH are doing what exactly? If they >> create alternative APIs like Google Collections and then share it with >> the world to see if its any good then fine. However, what happens all >> the time is that someone internally creates a pet project and then >> they do a bad job (either because it is bad or its not documented or >> its not intuitive except to the original author) and mess things up >> for the rest of us. >> > > Of course there's lots of stuff out there, but I see that quantity as a good > thing and invariably some of it will be rubbish. More importantly, it's a > fertile melting pot of different conflicting ideas - the perfect territory > for evolution to take place. > >> >> >Consider that the terms "Dependency Injection" or "IoC" were almost >> > unheard of when Java was >originally created, should we therefore not use >> > these patterns on the grounds that they're not >traditional idiomatic Java? >> >> I would argue that they are becoming idiomatic Java because things do >> change. However for everyone new piece of idiomatic Java that gets >> introduced theres a lot that doesn't and adds to the accidental >> complexity you mention later. Being generous, I could say that for >> every successful new idiom created, there is another 4 that screw up >> the code base for no good reason. >> > > Survival of the fittest :) > >> >> >You only have to look at how google collections uses type inference via >> > static factory methods to >see how much nicer it's possible for things to >> > be, or the way that Spring's db templates will convert >the (checked) >> > SqlException type to a more relevant runtime exception. Books on best >> > practices >always risk being out of date the very moment they are printed, >> > and the real state of the art exists in >blogs and mailing lists and the >> > source code for the various frameworks we use. >> >> Thats the great thing about 3rd party frameworks - someone else wrote >> them and if they are any good then they will be adopted and the >> patterns they introduce. The wider public will make things successful >> and then it will influence Java's idioms. I myself am a huge fan of >> Spring and I also advocate unchecked exceptions due to their >> influence. However, Spring is so popular, I can assume the next Java >> dev who comes along understands it and its idioms. >> >> Internal frameworks that break Java idioms are evil AFAIAC. >> > > I used to love spring when it was young and fresh. More recently I'm > sincerely hoping that the latest annotation-driven approach will invigorate > the framework, which seems to have been getting a bit too heavyweight in > later incarnations. It's a new idiom, but it's definitely cleaner. > >> >> > How much of "Effective Java" do you think will still remain a best >> > practice once we have closures >and method handles in Java 1.7? >> >> Errr, we don't have Java 7 and closures and until we do current idioms >> are to be used. Are you seriously advocating changing how we write >> code today for a feature that isn't even present in the language yet? >> Effective Java still stands. Plus there will be a 3rd addition no >> doubt then. >> >> >When I conceive the design of a system, I first think at a higher level >> > of what the various parts are >and how they interact. Only later will I >> > translate that design into the specific restrictions of my target >> > >language, >> > using the language as necessary to fit my mental model. The goal is always >> > to get as >close as possible to clearly expressing the essential complexity >> > inherent in the problem, and >minimising the accidental complexity >> > (boilerplate, etc) that the language introduces. If a newly >documented >> > design pattern or a concept learnt from another language helps me in this >> > then I will use >it, regardless of whether or not it was last year's best >> > practice. >> >> Again, if the final result is one that only you understand, then you >> have failed your fellow developer. >> >> If it reads cleanly and is easy for somebody else to understand then well >> done. >> > > clean and readable are the #1 goals > I've found that this usually arises from having a clear architecture that > closely matches the domain, instead of religiously following > language-specific idioms. > I'm a very strong advocate of both domain driven development and Knuth's > "Literate Programming", and frequently write my library classes to expose > behaviour via instances of com.google.common.base.Function so that a more > functional style can be used without having to repeatedly use abstract > classes in code that uses those libraries. > >> >> >If it is to survive and prosper as a language, then it seems important >> > that Java should evolve as >newer programming paradigms mature. And, yes, >> > that almost certainly means deprecating ideas >that were once advocated, as >> > well as accepting some cross-fertilization from other languages. Even >if >> > the only reason to do this is to better take advantage of concurrency on >> > processors that have ever->more cores then it's no bad thing. >> >> This may sound good in principle but like I've said ends up creating >> code that is hard to understand and maintain. Let the frameworks >> experiment with new idioms and then the public will decide.... >> > > clean, readable and maintainable are the #1 goals :) > Unless under *serious* time constraints, I'll always try and write code as > though it were going to be published in a magazine. Thinking like that does > absolute wonders for clarity. > >> >> Rakesh >> >> On Fri, Apr 30, 2010 at 12:56 PM, Kevin Wright >> <[email protected]> wrote: >> > No, I didn't learn Scala just for that, it was simply the most concise >> > example I could think of. >> > In general, I've been following a trend of moving towards smaller >> > lighter >> > objects, using composition instead of inheritance, making >> > less implementation private and instead favouring testability, etc... >> > Scala >> > was just another step along this axis, and taught me some additional >> > tricks >> > that I was able to port back into Java. >> > As for "Best Practices", they change! >> > EJB v1 used to be a best practice. Then Spring came along and made >> > everything more lightweight, then EJB3 and Guice - the trend here is >> > pretty >> > obvious. Boilerplate in Java risks getting ever more burdensome as new >> > features are added (like having to specify type params twice when >> > instantiating a variable using generics) and Frameworks and developers >> > are >> > increasingly saying ENOUGH! Consider that the terms "Dependency >> > Injection" >> > or "IoC" were almost unheard of when Java was originally created, should >> > we >> > therefore not use these patterns on the grounds that they're not >> > traditional >> > idiomatic Java? >> > You only have to look at how google collections uses type inference via >> > static factory methods to see how much nicer it's possible for things to >> > be, >> > or the way that Spring's db templates will convert the (checked) >> > SqlException type to a more relevant runtime exception. Books on best >> > practices always risk being out of date the very moment they are >> > printed, >> > and the real state of the art exists in blogs and mailing lists and the >> > source code for the various frameworks we use. How much of "Effective >> > Java" >> > do you think will still remain a best practice once we have closures and >> > method handles in Java 1.7? >> > >> > When I conceive the design of a system, I first think at a higher level >> > of >> > what the various parts are and how they interact. Only later will I >> > translate that design into the specific restrictions of my target >> > language, >> > using the language as necessary to fit my mental model. The goal is >> > always >> > to get as close as possible to clearly expressing the essential >> > complexity inherent in the problem, and minimising the accidental >> > complexity >> > (boilerplate, etc) that the language introduces. If a newly documented >> > design pattern or a concept learnt from another language helps me in >> > this >> > then I will use it, regardless of whether or not it was last year's best >> > practice. >> > If it is to survive and prosper as a language, then it seems important >> > that >> > Java should evolve as newer programming paradigms mature. And, yes, >> > that >> > almost certainly means deprecating ideas that were once advocated, as >> > well >> > as accepting some cross-fertilization from other languages. Even if the >> > only reason to do this is to better take advantage of concurrency on >> > processors that have ever-more cores then it's no bad thing. >> > >> > On 30 April 2010 12:10, Wildam Martin <[email protected]> wrote: >> >> >> >> On Fri, Apr 30, 2010 at 12:12, Rakesh <[email protected]> >> >> wrote: >> >> > The code written by these people is very strange to a Java-only dev >> >> > and I don't think for the better. >> >> >> >> The risk of writing bad code is certainly higher when knowing a lot of >> >> language just a little because you are more likely you mix best >> >> practices from those languages. With the focus on one or few languages >> >> you are more likely of writing better code - if it is simply because >> >> of knowing more best practices and having more experience. - So no >> >> wonder for me that you experienced that. >> >> >> >> I learned that when you learn a language you need to get a feeling >> >> about several intentions of the language design and if you do much of >> >> "language hopping", you might tend to mix things (up). >> >> >> >> >> >> > A small example is the use of final everywhere. Is the code really >> >> > better? Really? How did you cope before? Did you find lots of bugs >> >> > that were due to not using final? >> >> >> >> I think while it may make a lot of sense applying ideas from other >> >> languages where it fits new idioms should not be applied blindly. >> >> WHERE IT FITS is the key here. - Apart from that depending on some >> >> "philosophic viewpoints" code may look very different. >> >> >> >> Sample: There are people who find dealing with checked exceptions >> >> simply boilerplate and always use unchecked/runtime exceptions. Others >> >> have the religion of using checked exceptions and again others try to >> >> avoid both by using good old return codes. - So even if you have only >> >> developers how ever only did Java you might find totally different >> >> code styles. - My opinion for this example is again, that it depends - >> >> mostly also depending on the context. In one case if a file is not >> >> found you might want to throw a runtime exception because that is a >> >> major config file and in other cases you might want just to return a >> >> "false" because the method was just examining a certain status. >> >> >> >> >> >> > So, in summary, I think learning about other languages is ultimately >> >> > good experience from a personal point of view but be very careful how >> >> > it affects the code you write in other languages. >> >> >> >> Whatever language you are using you should not take care only about >> >> syntax, but also about best practices and other "soft" parameters. >> >> >> >> >> >> On Fri, Apr 30, 2010 at 12:38, Kevin Wright >> >> <[email protected]> wrote: >> >> > My Java style definitely changed since I learned Scala, and for the >> >> > better. I can give one clear example. >> >> > [...] >> >> >> >> Do you really needed to learn scala for that? This is plain valid Java. >> >> You could either use just >> >> public int x; >> >> public String s; >> >> - who cares? >> >> >> >> The thing is, that with getters and setters you have control over >> >> "dependencies". >> >> If just defining the above way you later don't have the option of >> >> changing other internal object status if the user of the API changes x >> >> for example. >> >> >> >> > Using getters/setters and making class instance variables private is >> >> > an established Java idiom. I mean its in Effective Java (Item 14). >> >> >> >> The use of getters and setters is just a best practice - even if >> >> defined by a man who should really know. But the nature of best >> >> practices is also that they are suggestions and not rules - to not >> >> apply them where it does not fit. But I guess, in this case, several >> >> frameworks rely on the case that you use them, so it might become a >> >> constraint. >> >> -- >> >> Martin Wildam >> >> >> >> -- >> >> 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. >> >> >> > >> > >> > >> > -- >> > Kevin Wright >> > >> > mail/google talk: [email protected] >> > wave: [email protected] >> > skype: kev.lee.wright >> > twitter: @thecoda >> > >> > -- >> > 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. >> > >> >> -- >> 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. >> > > > > -- > Kevin Wright > > mail/google talk: [email protected] > wave: [email protected] > skype: kev.lee.wright > twitter: @thecoda > > -- > 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. > -- 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.
