Return-Path: Delivered-To: apmail-incubator-cxf-dev-archive@locus.apache.org Received: (qmail 26485 invoked from network); 4 Apr 2007 10:48:06 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 4 Apr 2007 10:48:06 -0000 Received: (qmail 33628 invoked by uid 500); 4 Apr 2007 10:48:12 -0000 Delivered-To: apmail-incubator-cxf-dev-archive@incubator.apache.org Received: (qmail 33586 invoked by uid 500); 4 Apr 2007 10:48:12 -0000 Mailing-List: contact cxf-dev-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: cxf-dev@incubator.apache.org Delivered-To: mailing list cxf-dev@incubator.apache.org Received: (qmail 33577 invoked by uid 99); 4 Apr 2007 10:48:12 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 04 Apr 2007 03:48:12 -0700 X-ASF-Spam-Status: No, hits=2.0 required=10.0 tests=HTML_MESSAGE,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (herse.apache.org: domain of sergey.beryozkin@iona.com designates 62.221.12.33 as permitted sender) Received: from [62.221.12.33] (HELO emea-smg1.iona.com) (62.221.12.33) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 04 Apr 2007 03:48:03 -0700 Received: from emea-ems1.ionaglobal.com (dutec.ie [10.2.1.125]) by emea-smg1.iona.com (Switch-3.1.7/Switch-3.1.7) with ESMTP id l34BiK6k024802 for ; Wed, 4 Apr 2007 11:44:20 GMT Received: from sberyoz ([10.2.1.195]) by emea-ems1.ionaglobal.com with Microsoft SMTPSVC(5.0.2195.6713); Wed, 4 Apr 2007 11:47:39 +0100 Message-ID: <00d101c776a6$eb6dd180$c301020a@sberyoz> From: "Sergey Beryozkin" To: References: Subject: Re: Checkstyle Date: Wed, 4 Apr 2007 11:49:28 +0100 MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_00CE_01C776AF.4D23E1A0" X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2900.3028 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3028 X-OriginalArrivalTime: 04 Apr 2007 10:47:39.0113 (UTC) FILETIME=[A9F0D590:01C776A6] X-Virus-Checked: Checked by ClamAV on apache.org ------=_NextPart_000_00CE_01C776AF.4D23E1A0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Hi I personally agree in general with what Eoghan is saying. > So the abstract base class is in my view a convenience that the user = may > choose to take advantage of, or not, as the case may be. But they = should > not be forced to do so. So AbstractWSFeature is grand, as long there's > also a WSFeature interface that the user can choose to implement > directly.=20 The argument on when to use interfaces as opposed to abstract classes = can get quite religious :-) JDK favours interfaces and used abstract classes more often as a = sceletal implementation of the interface, and it's likely the Abstract* = checkstyle rule follows the convention used to name abstract classes in = Collections, etc... It can be difficult to make the right choice. The advice from the = EffectiveJava (I looked at it to refresh my memory just before replying = to be honest :-)) highlights the fact that if the ease of evolution is = meant to be more important than the flexibility interfaces bring to the = table then abstract class can be a better choice provided that the = consequences are understood well.=20 Is it desirable for implementers to be able to retrofit their own = classes already extending something or not ? Is interface like WSFeature = has been tested a lot by having multiple impls of it and is deemed to be = right and not change in the future ? Is it realistic to expect to have a = public default implementation added to the given Abstract class so that = existing customer implementations can continue work ? If yes to first 2 questions and no to the last one then = AbstractWSFeature + WSFeature is a much more powerful combination, even = if existing classes can't extend the utility AbstractWSFeature then = they'll still be able to delegate internally to the helper extending = AbstractWSFeature (simulated multiple inheritance, from the book)...=20 Either way, perhaps the checkstyle rule might be relaxed for abstract = classes which do not implement interfaces, otherwise if they do then the = high chance is the user will want to pass the interface around rather = than the abstract class. Cheers, Sergey ----- Original Message -----=20 From: "Glynn, Eoghan" To: Sent: Wednesday, April 04, 2007 10:15 AM Subject: RE: Checkstyle Well the mumblings were more like advice to use interfaces *in addition to* abstract classes, not *instead of* abstract classes.=20 Plus some pointers to Java features/idiom like @Override, inner interfaces, composition v. inheritance, that would solve some of the problems Polar perceives. However there *is* a compelling reason for casting public APIs in terms of interfaces, as opposed to the corresponding abstract classes. We generally do not want to *force* users to extend our abstract classes and use up their one shot at implementation inheritance in doing so, just to get some boiler-plate code. Example would be Polar's HttpBasicAuthSupplier. That should be an interface, possibly also implemented by an abstract class holding the boiler-plate logic. A user may want to directly implement the interface themselves if they needed to extend a different base class for some reason, e.g. DialogBoxHttpBasicAuthSupplier extends GUIWidget implements HttpBasicAuthSupplier. So the abstract base class is in my view a convenience that the user may choose to take advantage of, or not, as the case may be. But they should not be forced to do so. So AbstractWSFeature is grand, as long there's also a WSFeature interface that the user can choose to implement directly.=20 Sure, users who make that choice would be impacted more by future additions to the interface. But in reality, not all new methods would have a sensible default impl that extensions of the abstract class can just pick up without any change. As far as the Abstract* naming convention is concerned, I'm not a big fan of such rules when forced to change my own class names, but once you get over that irritation I can see the value of the consistency that the rule brings. So I'm not pushed either way.=20 Hey, it could be a lot worse ... at least we don't have the C# IFooBar naming scheme for interfaces :) Cheers, Eoghan > -----Original Message----- > From: Dan Diephouse [mailto:dan@envoisolutions.com]=20 > Sent: 04 April 2007 00:50 > To: cxf-dev@incubator.apache.org > Subject: Re: Checkstyle >=20 > I completely agree that we should get rid of this rule. >=20 > First of all, Aegis from XFire use Type which is abstract,=20 > and I don't want to change this for migration reasons which=20 > is one of the reasons pmd is disabled for this module. >=20 > Second, I agree that the Abstract/base/factory naming is=20 > incredibly awkward. > I hear some mumblings of "just use interfaces" - but abstract=20 > classes provide a much more robust way to add features in the=20 > future. With an interface, if you add a method, it will break=20 > every class that implemented that interface. With abstract=20 > classes if you add a new method, all you need to do is=20 > provide a default implementation of it and everything will=20 > work swell in the future. So I tend to use abstract classes=20 > more and more to avoid future incompatibilities=20 > (AbstractWSFeature, AbstractServiceFactoryBean,=20 > AbstractEndpointFactory). With at least the first two, I=20 > would like to get ride of the Abstract. >=20 > - Dan >=20 > On 4/3/07, Polar Humenn wrote: > > > > Is there a "good" motivation of why "abstract" classes have to be=20 > > named "Abstract" "Base" or "Factory"? > > > > If a class is declared "abstract", I want the *compiler* to=20 > tell the=20 > > developer that s/he has not filled out a particular=20 > functionality when=20 > > s/he extends the abstract class. Not that I want it named=20 > "Abstract". > > For example, > > > > abstract class Muffin { > > ...... > > abstract Kind kind(); > > } > > > > I really don't want my code littered with method definitions like: > > > > void eat(AbstractMuffin muff) { > > > > I want it to be: > > > > void eat(Muffin muff); > > > > because that's what it is. It's not an AbstractMuffin, it's=20 > a Muffin! > > > > Can we get rid of that particular checkstyle rule? > > > > I say that, because it forces, either > > > > a) illogical names, like AbstractMuffin, to be used in definitions,=20 > > making for > > awkwardness. (i.e. eat(AbstractMuffin muff); > > > > b) default implementations, just to avoid the illogical names! > > > > This particular avoidance causes errors to be caught=20 > at run time > > instead of compile time, where it should be caught! And=20 > > sometimes causing > > a loss of time to find it. > > > > For example, with the current checkstyle rule I could be forced to=20 > > write the class with a default implementation expecting it to be=20 > > overridden. (Except there is no way to tell a compiler that). > > > > class Muffin { > > ..... > > Kind kind() { > > return Kind.BLUEBERRY; > > } > > } > > > > void eat(Muffin muff) { > > System.out.println("I'm eating a " + muff.kind() +=20 > " muffin!"); > > } > > > > and a developer goes ahead and writes: > > > > class CornMuffin extends Muffin { > > Kind kiend() { > > return Kind.CORN; > > } > > } > > > > and it compiles fine without problems. Subsequently he can't figure=20 > > out why his application still says he has a BLUEBERRY muffin,=20 > > especially when he has used "eat(new CornMuffin())". > > > > This kind of pattern complete adverted the use of compiler=20 > protections. > > > > Cheers, > > -Polar > > > > > > >=20 >=20 > -- > Dan Diephouse > Envoi Solutions > http://envoisolutions.com | http://netzooid.com/blog > ------=_NextPart_000_00CE_01C776AF.4D23E1A0--