You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Polar Humenn <ph...@iona.com> on 2007/04/03 23:10:27 UTC

Checkstyle

Is there a "good" motivation of why "abstract" classes have to be named 
"Abstract" "Base" or "Factory"?

If a class is declared "abstract", I want the *compiler* to tell the 
developer that s/he has not filled out a particular functionality when 
s/he extends the abstract class. Not that I want it named "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 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, 
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 at run time
      instead of compile time, where it should be caught! And sometimes 
causing
      a loss of time to find it.

For example, with the current checkstyle rule I could be forced to write 
the class with
a default implementation expecting it to be 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() + " 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 out 
why his application still says he has a BLUEBERRY muffin, especially 
when he has used "eat(new CornMuffin())".

This kind of pattern complete adverted the use of compiler protections.

Cheers,
-Polar



RE: Checkstyle

Posted by "Glynn, Eoghan" <eo...@iona.com>.
 

> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com] 
> Sent: 04 April 2007 21:15
> To: cxf-dev@incubator.apache.org
> Subject: Re: Checkstyle
> 
> Eoghan - does this really bug you enough that you would be 
> really upset if I changed it? 

Nope, go ahead ... 

/Eoghan


> I don't think it will kill 
> anyone if we allow classes without Abstract/Factory/Base, and 
> it will certainly make names clearer for some cases as well 
> as stop breaking the aegis stuff.
> 
> - Dan
> 
> On 4/4/07, Dan Diephouse <da...@envoisolutions.com> wrote:
> >
> >
> >
> > On 4/4/07, Glynn, Eoghan <eo...@iona.com> wrote:
> > >
> > >
> > > 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.
> >
> >
> > The whole point is to not have an interface for forward 
> compatability 
> > so users don't shoot themselves in the foot.
> >
> > For instance, JAX-WS has Endpoint, Service, Provider, and 
> ServiceDelegate.
> > Can you imagine how awkward it would be for users if they 
> were using 
> > AbstractEndpoint all the time? Interfaces for all these 
> classes would 
> > be completely redundant/useless for users as well.
> >
> > Anyway, I don't really feel like arguing this anymore, but I agree 
> > with Polar and I think we should make the change. This really won't 
> > harm anyone, and will only serve to make our code clearer.
> >
> > - Dan
> >
> >
> > --
> > Dan Diephouse
> > Envoi Solutions
> > http://envoisolutions.com | http://netzooid.com/blog
> >
> 
> 
> 
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
> 

Re: Checkstyle

Posted by Dan Diephouse <da...@envoisolutions.com>.
Eoghan - does this really bug you enough that you would be really upset if I
changed it? I don't think it will kill anyone if we allow classes without
Abstract/Factory/Base, and it will certainly make names clearer for some
cases as well as stop breaking the aegis stuff.

- Dan

On 4/4/07, Dan Diephouse <da...@envoisolutions.com> wrote:
>
>
>
> On 4/4/07, Glynn, Eoghan <eo...@iona.com> wrote:
> >
> >
> > 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.
>
>
> The whole point is to not have an interface for forward compatability so
> users don't shoot themselves in the foot.
>
> For instance, JAX-WS has Endpoint, Service, Provider, and ServiceDelegate.
> Can you imagine how awkward it would be for users if they were using
> AbstractEndpoint all the time? Interfaces for all these classes would be
> completely redundant/useless for users as well.
>
> Anyway, I don't really feel like arguing this anymore, but I agree with
> Polar and I think we should make the change. This really won't harm anyone,
> and will only serve to make our code clearer.
>
> - Dan
>
>
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
>



-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: Checkstyle

Posted by Polar Humenn <ph...@iona.com>.
Glynn, Eoghan wrote:
> *snip*
> As I said I'm agnostic to the PMD rule change. 
>
> However, I really don't see why there's such a big bones about giving
> the user a *choice* between implementing an interface and extending an
> abstract class. Especially since the class that started the whole
> debate, Polar's HttpBasicAuthSupplier, has such a tiny amount of
> implementation code in the base class. 
>
> Which now that I look at it again, I notice isn't even abstract. 

Well, first of call CXF doesn't have this/my patch to look at yet. 
Second of all, I was forced to make it a fully implemented class to 
avoid having "AbstractHttpBasicAuthSupplier" in my code, which is really 
what we are talking about. And that's what I am objecting to, is the 
rule is forcing me to do bad things.

I'm going back to making that class abstract. please.

Cheers,
-Polar

> Which
> is odd, as having a default null-returning impl for
> getUserPassForRealm() can't be for backward compatability (as we know
> this method exists right now), and the user sortta has to override it
> (otherwise their HttpBasicAuthSupplier is kinda useless). Plus the PMD
> rule at issue doesn't even apply to HttpBasicAuthSupplier as its
> non-abstract. So I'm a bit confused now about what we're even arguing
> about ...
>
> One advantage of these automated rules is to head off religious debates
> on code style. I guess we loose that if we start endless debates about
> changing the rules. But I'm also really tiring of this debate, so lets
> just draw a line under it ...
>
> /Eoghan
>  
>   
>> - Dan
>>
>>
>> --
>> Dan Diephouse
>> Envoi Solutions
>> http://envoisolutions.com | http://netzooid.com/blog
>>
>>     


RE: Checkstyle

Posted by "Glynn, Eoghan" <eo...@iona.com>.
 

> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com] 
> Sent: 04 April 2007 19:17
> To: cxf-dev@incubator.apache.org
> Subject: Re: Checkstyle
> 
> On 4/4/07, Glynn, Eoghan <eo...@iona.com> wrote:
> >
> >
> > 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.
> 
> 
> The whole point is to not have an interface for forward 
> compatability so users don't shoot themselves in the foot.


Or that we don't shoot them in the foot by extending the interface? :)

 
> For instance, JAX-WS has Endpoint, Service, Provider, and 
> ServiceDelegate.
> Can you imagine how awkward it would be for users if they 
> were using AbstractEndpoint all the time? Interfaces for all 
> these classes would be completely redundant/useless for users as well.
> 
> Anyway, I don't really feel like arguing this anymore, but I 
> agree with Polar and I think we should make the change. This 
> really won't harm anyone, and will only serve to make our 
> code clearer.


As I said I'm agnostic to the PMD rule change. 

However, I really don't see why there's such a big bones about giving
the user a *choice* between implementing an interface and extending an
abstract class. Especially since the class that started the whole
debate, Polar's HttpBasicAuthSupplier, has such a tiny amount of
implementation code in the base class. 

Which now that I look at it again, I notice isn't even abstract. Which
is odd, as having a default null-returning impl for
getUserPassForRealm() can't be for backward compatability (as we know
this method exists right now), and the user sortta has to override it
(otherwise their HttpBasicAuthSupplier is kinda useless). Plus the PMD
rule at issue doesn't even apply to HttpBasicAuthSupplier as its
non-abstract. So I'm a bit confused now about what we're even arguing
about ...

One advantage of these automated rules is to head off religious debates
on code style. I guess we loose that if we start endless debates about
changing the rules. But I'm also really tiring of this debate, so lets
just draw a line under it ...

/Eoghan
 
> - Dan
> 
> 
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
> 

Re: Checkstyle

Posted by Dan Diephouse <da...@envoisolutions.com>.
On 4/4/07, Glynn, Eoghan <eo...@iona.com> wrote:
>
>
> 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.


The whole point is to not have an interface for forward compatability so
users don't shoot themselves in the foot.

For instance, JAX-WS has Endpoint, Service, Provider, and ServiceDelegate.
Can you imagine how awkward it would be for users if they were using
AbstractEndpoint all the time? Interfaces for all these classes would be
completely redundant/useless for users as well.

Anyway, I don't really feel like arguing this anymore, but I agree with
Polar and I think we should make the change. This really won't harm anyone,
and will only serve to make our code clearer.

- Dan


-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: Checkstyle

Posted by Polar Humenn <ph...@iona.com>.
Like I said, there are six ways to Sunday to do everything the way you 
want it.
I just disagree with that/your approach.

Cheers,
-Polar


Glynn, Eoghan wrote:
>  
>
>   
>> -----Original Message-----
>> From: Polar Humenn [mailto:phumenn@iona.com] 
>> Sent: 04 April 2007 14:57
>> To: cxf-dev@incubator.apache.org
>> Subject: Re: Checkstyle
>>
>> I would firmly have to disagree.
>>
>> You have lots of generated code that are classes, don't use 
>> interfaces, which people have to use to use the API. But I digress.
>>     
>
>
> What generated code exactly is in the form of classes (that the user has
> to extend)?
>
> At least for JAX-WS, the main bit of generated code exposed to users is
> the SEI, where the "I" stands for interface.
>
> Clearly I'm not saying don't use classes. You can't program any
> executable logic into interfaces. 
>
> What I'm saying is, if the user is to extend or implement some of our
> code, give them the option to implement an interface. What's so
> controversial or disagreeable about that?
>
>  
>   
>> If I am to use a *class* like:
>>
>>        final class UserPass {
>>            final String user;
>>            final String pass;
>>             UserPass(String u, String p) {
>>                    user = u; pass = p;
>>            }
>>            String getUser() { return user; }
>>            String getPass() { return pass; }
>>       }
>>
>> I have a contract with the an operation
>>
>>           UserPass getUserPass();
>>
>> That what I get back won't change. It wont deliver different 
>> things for subsequent calls to getUser or getPass.
>>     
>
>
> So keep UserPass as a class! 
>
> The point is that the application code wouldn't need to extend UserPass
> anyway.
>
> What they do need to extend is the HttpBasicAuthCredsSupplier. So that
> should be an interface. And also possibly an abstract class implementing
> it, if it contains any non-trivial bolier-plate code. So that the user
> has the choice to extend or implement.
>
> So assuming HttpBasicAuthCredsSupplier is an interface, then UserPass
> could be either an inner interface (if want to keep the inner/outter
> scoping), or a stand-alone class (if you want to control the
> implementation). Take your choice.
>
>
>   
>> This allows me to make certain assumptions on the calling 
>> side that I cannot make if UserPass was forced to be an 
>> interface. Such as I can cache the object instead of the 
>> results. And I have some assurance that there are no convert 
>> channels from it.
>>     
>
> Covert channels?
>  
>   
>> Sure, you can put a certain Abstract logic built "immutable" 
>> class underneath it, but it doesn't *mean* the same thing. I 
>> can't *guarantee* immutability from the calling side, if all 
>> I'm requiring it be is an interface.
>>     
>
>
> No-one is requiring UserPass to be an interface. As the user would never
> have to extend it, it doesn't really matter.
>
> But you can easily get the immutablility you want even if UserPass is an
> inner interface (assuming the inner/outter scoping was more important to
> you). As Java strings are themselves immutable, just extract the
> username & passwd fields from the returned value and re-wrap in a
> trivial immutable UserPass impl. 
>
> On the other hand, if you want to dictate the actual UserPass impl, then
> make it an outter class.
>
> No rocket science. And not worth the time that's already been burned on
> this discussion either.
>
>
>   
>> Nope, I don't buy the argument.
>>
>> The other thing, I can alleviate memory leaks somewhat 
>> because if it were an interface and somebody decided to give 
>> me an implementation of it as an inner class and I cached the 
>> object I end up keeping a reference to the whole outer class.
>>     
>
>
> A *static* inner class (like the UserPass in your patch) has no
> reference to the outter class.
>
> Only a *non-static* inner class carries a reference to an instance of
> the outter class.
>
> /Eoghan
>
>
>   
>> The basic upshot is that you can implement it any number of 6 
>> different ways to Sunday but the "contracts" *are* different, 
>> subtle as they may be.
>>
>> Cheers,
>> -Polar
>>
>> Glynn, Eoghan wrote:
>>     
>>> Well the mumblings were more like advice to use interfaces *in 
>>> addition
>>> to* abstract classes, not *instead of* abstract classes. 
>>>
>>> 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.
>>>
>>> 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.
>>>
>>> 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]
>>>> Sent: 04 April 2007 00:50
>>>> To: cxf-dev@incubator.apache.org
>>>> Subject: Re: Checkstyle
>>>>
>>>> I completely agree that we should get rid of this rule.
>>>>
>>>> First of all, Aegis from XFire use Type which is abstract, and I 
>>>> don't want to change this for migration reasons which is 
>>>>         
>> one of the 
>>     
>>>> reasons pmd is disabled for this module.
>>>>
>>>> Second, I agree that the Abstract/base/factory naming is 
>>>>         
>> incredibly 
>>     
>>>> awkward.
>>>> I hear some mumblings of "just use interfaces" - but 
>>>>         
>> abstract classes 
>>     
>>>> provide a much more robust way to add features in the 
>>>>         
>> future. With an 
>>     
>>>> interface, if you add a method, it will break every class that 
>>>> implemented that interface. With abstract classes if you add a new 
>>>> method, all you need to do is provide a default 
>>>>         
>> implementation of it 
>>     
>>>> and everything will work swell in the future.  So I tend to use 
>>>> abstract classes more and more to avoid future incompatibilities 
>>>> (AbstractWSFeature, AbstractServiceFactoryBean, 
>>>> AbstractEndpointFactory). With at least the first two, I 
>>>>         
>> would like 
>>     
>>>> to get ride of the Abstract.
>>>>
>>>> - Dan
>>>>
>>>> On 4/3/07, Polar Humenn <ph...@iona.com> wrote:
>>>>     
>>>>         
>>>>> Is there a "good" motivation of why "abstract" classes have to be 
>>>>> named "Abstract" "Base" or "Factory"?
>>>>>
>>>>> If a class is declared "abstract", I want the *compiler* to
>>>>>       
>>>>>           
>>>> tell the
>>>>     
>>>>         
>>>>> developer that s/he has not filled out a particular
>>>>>       
>>>>>           
>>>> functionality when
>>>>     
>>>>         
>>>>> s/he extends the abstract class. Not that I want it named
>>>>>       
>>>>>           
>>>> "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
>>>>>       
>>>>>           
>>>> 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, 
>>     
>>>>> 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
>>>>>       
>>>>>           
>>>> at run time
>>>>     
>>>>         
>>>>>       instead of compile time, where it should be caught! And 
>>>>> sometimes causing
>>>>>       a loss of time to find it.
>>>>>
>>>>> For example, with the current checkstyle rule I could be 
>>>>>           
>> forced to 
>>     
>>>>> write the class with a default implementation expecting it to be 
>>>>> 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() +
>>>>>       
>>>>>           
>>>> " 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 
>>     
>>>>> out why his application still says he has a BLUEBERRY muffin, 
>>>>> especially when he has used "eat(new CornMuffin())".
>>>>>
>>>>> This kind of pattern complete adverted the use of compiler
>>>>>       
>>>>>           
>>>> protections.
>>>>     
>>>>         
>>>>> Cheers,
>>>>> -Polar
>>>>>
>>>>>
>>>>>
>>>>>       
>>>>>           
>>>> --
>>>> Dan Diephouse
>>>> Envoi Solutions
>>>> http://envoisolutions.com | http://netzooid.com/blog
>>>>
>>>>     
>>>>         
>>     


RE: Checkstyle

Posted by "Glynn, Eoghan" <eo...@iona.com>.
 

> -----Original Message-----
> From: Polar Humenn [mailto:phumenn@iona.com] 
> Sent: 04 April 2007 14:57
> To: cxf-dev@incubator.apache.org
> Subject: Re: Checkstyle
> 
> I would firmly have to disagree.
> 
> You have lots of generated code that are classes, don't use 
> interfaces, which people have to use to use the API. But I digress.


What generated code exactly is in the form of classes (that the user has
to extend)?

At least for JAX-WS, the main bit of generated code exposed to users is
the SEI, where the "I" stands for interface.

Clearly I'm not saying don't use classes. You can't program any
executable logic into interfaces. 

What I'm saying is, if the user is to extend or implement some of our
code, give them the option to implement an interface. What's so
controversial or disagreeable about that?

 
> If I am to use a *class* like:
> 
>        final class UserPass {
>            final String user;
>            final String pass;
>             UserPass(String u, String p) {
>                    user = u; pass = p;
>            }
>            String getUser() { return user; }
>            String getPass() { return pass; }
>       }
> 
> I have a contract with the an operation
> 
>           UserPass getUserPass();
> 
> That what I get back won't change. It wont deliver different 
> things for subsequent calls to getUser or getPass.


So keep UserPass as a class! 

The point is that the application code wouldn't need to extend UserPass
anyway.

What they do need to extend is the HttpBasicAuthCredsSupplier. So that
should be an interface. And also possibly an abstract class implementing
it, if it contains any non-trivial bolier-plate code. So that the user
has the choice to extend or implement.

So assuming HttpBasicAuthCredsSupplier is an interface, then UserPass
could be either an inner interface (if want to keep the inner/outter
scoping), or a stand-alone class (if you want to control the
implementation). Take your choice.


> This allows me to make certain assumptions on the calling 
> side that I cannot make if UserPass was forced to be an 
> interface. Such as I can cache the object instead of the 
> results. And I have some assurance that there are no convert 
> channels from it.

Covert channels?
 
> Sure, you can put a certain Abstract logic built "immutable" 
> class underneath it, but it doesn't *mean* the same thing. I 
> can't *guarantee* immutability from the calling side, if all 
> I'm requiring it be is an interface.


No-one is requiring UserPass to be an interface. As the user would never
have to extend it, it doesn't really matter.

But you can easily get the immutablility you want even if UserPass is an
inner interface (assuming the inner/outter scoping was more important to
you). As Java strings are themselves immutable, just extract the
username & passwd fields from the returned value and re-wrap in a
trivial immutable UserPass impl. 

On the other hand, if you want to dictate the actual UserPass impl, then
make it an outter class.

No rocket science. And not worth the time that's already been burned on
this discussion either.


> Nope, I don't buy the argument.
> 
> The other thing, I can alleviate memory leaks somewhat 
> because if it were an interface and somebody decided to give 
> me an implementation of it as an inner class and I cached the 
> object I end up keeping a reference to the whole outer class.


A *static* inner class (like the UserPass in your patch) has no
reference to the outter class.

Only a *non-static* inner class carries a reference to an instance of
the outter class.

/Eoghan


> The basic upshot is that you can implement it any number of 6 
> different ways to Sunday but the "contracts" *are* different, 
> subtle as they may be.
> 
> Cheers,
> -Polar
> 
> Glynn, Eoghan wrote:
> > Well the mumblings were more like advice to use interfaces *in 
> > addition
> > to* abstract classes, not *instead of* abstract classes. 
> >
> > 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.
> >
> > 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.
> >
> > 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]
> >> Sent: 04 April 2007 00:50
> >> To: cxf-dev@incubator.apache.org
> >> Subject: Re: Checkstyle
> >>
> >> I completely agree that we should get rid of this rule.
> >>
> >> First of all, Aegis from XFire use Type which is abstract, and I 
> >> don't want to change this for migration reasons which is 
> one of the 
> >> reasons pmd is disabled for this module.
> >>
> >> Second, I agree that the Abstract/base/factory naming is 
> incredibly 
> >> awkward.
> >> I hear some mumblings of "just use interfaces" - but 
> abstract classes 
> >> provide a much more robust way to add features in the 
> future. With an 
> >> interface, if you add a method, it will break every class that 
> >> implemented that interface. With abstract classes if you add a new 
> >> method, all you need to do is provide a default 
> implementation of it 
> >> and everything will work swell in the future.  So I tend to use 
> >> abstract classes more and more to avoid future incompatibilities 
> >> (AbstractWSFeature, AbstractServiceFactoryBean, 
> >> AbstractEndpointFactory). With at least the first two, I 
> would like 
> >> to get ride of the Abstract.
> >>
> >> - Dan
> >>
> >> On 4/3/07, Polar Humenn <ph...@iona.com> wrote:
> >>     
> >>> Is there a "good" motivation of why "abstract" classes have to be 
> >>> named "Abstract" "Base" or "Factory"?
> >>>
> >>> If a class is declared "abstract", I want the *compiler* to
> >>>       
> >> tell the
> >>     
> >>> developer that s/he has not filled out a particular
> >>>       
> >> functionality when
> >>     
> >>> s/he extends the abstract class. Not that I want it named
> >>>       
> >> "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
> >>>       
> >> 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, 
> >>> 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
> >>>       
> >> at run time
> >>     
> >>>       instead of compile time, where it should be caught! And 
> >>> sometimes causing
> >>>       a loss of time to find it.
> >>>
> >>> For example, with the current checkstyle rule I could be 
> forced to 
> >>> write the class with a default implementation expecting it to be 
> >>> 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() +
> >>>       
> >> " 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 
> >>> out why his application still says he has a BLUEBERRY muffin, 
> >>> especially when he has used "eat(new CornMuffin())".
> >>>
> >>> This kind of pattern complete adverted the use of compiler
> >>>       
> >> protections.
> >>     
> >>> Cheers,
> >>> -Polar
> >>>
> >>>
> >>>
> >>>       
> >> --
> >> Dan Diephouse
> >> Envoi Solutions
> >> http://envoisolutions.com | http://netzooid.com/blog
> >>
> >>     
> 
> 

Re: Checkstyle

Posted by Polar Humenn <ph...@iona.com>.
I would firmly have to disagree.

You have lots of generated code that are classes, don't use interfaces, 
which people have to use to use the API. But I digress.

If I am to use a *class* like:

       final class UserPass {
           final String user;
           final String pass;
            UserPass(String u, String p) {
                   user = u; pass = p;
           }
           String getUser() { return user; }
           String getPass() { return pass; }
      }

I have a contract with the an operation

          UserPass getUserPass();

That what I get back won't change. It wont deliver different things for 
subsequent calls to getUser or getPass.

This allows me to make certain assumptions on the calling side that I 
cannot make if UserPass was forced to be an interface. Such as I can 
cache the object instead of the results. And I have some assurance that 
there are no convert channels from it.

Sure, you can put a certain Abstract logic built "immutable" class 
underneath it, but it doesn't *mean* the same thing. I can't *guarantee* 
immutability from the calling side, if all I'm requiring it be is an 
interface.

Nope, I don't buy the argument.

The other thing, I can alleviate memory leaks somewhat because if it 
were an interface and somebody decided to give me an implementation of 
it as an inner class and I cached the object I end up keeping a 
reference to the whole outer class.

The basic upshot is that you can implement it any number of 6 different 
ways to Sunday but the "contracts" *are* different, subtle as they may be.

Cheers,
-Polar

Glynn, Eoghan wrote:
> Well the mumblings were more like advice to use interfaces *in addition
> to* abstract classes, not *instead of* abstract classes. 
>
> 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. 
>
> 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. 
>
> 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] 
>> Sent: 04 April 2007 00:50
>> To: cxf-dev@incubator.apache.org
>> Subject: Re: Checkstyle
>>
>> I completely agree that we should get rid of this rule.
>>
>> First of all, Aegis from XFire use Type which is abstract, 
>> and I don't want to change this for migration reasons which 
>> is one of the reasons pmd is disabled for this module.
>>
>> Second, I agree that the Abstract/base/factory naming is 
>> incredibly awkward.
>> I hear some mumblings of "just use interfaces" - but abstract 
>> classes provide a much more robust way to add features in the 
>> future. With an interface, if you add a method, it will break 
>> every class that implemented that interface. With abstract 
>> classes if you add a new method, all you need to do is 
>> provide a default implementation of it and everything will 
>> work swell in the future.  So I tend to use abstract classes 
>> more and more to avoid future incompatibilities 
>> (AbstractWSFeature, AbstractServiceFactoryBean, 
>> AbstractEndpointFactory). With at least the first two, I 
>> would like to get ride of the Abstract.
>>
>> - Dan
>>
>> On 4/3/07, Polar Humenn <ph...@iona.com> wrote:
>>     
>>> Is there a "good" motivation of why "abstract" classes have to be 
>>> named "Abstract" "Base" or "Factory"?
>>>
>>> If a class is declared "abstract", I want the *compiler* to 
>>>       
>> tell the 
>>     
>>> developer that s/he has not filled out a particular 
>>>       
>> functionality when 
>>     
>>> s/he extends the abstract class. Not that I want it named 
>>>       
>> "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 
>>>       
>> 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, 
>>> 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 
>>>       
>> at run time
>>     
>>>       instead of compile time, where it should be caught! And 
>>> sometimes causing
>>>       a loss of time to find it.
>>>
>>> For example, with the current checkstyle rule I could be forced to 
>>> write the class with a default implementation expecting it to be 
>>> 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() + 
>>>       
>> " 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 
>>> out why his application still says he has a BLUEBERRY muffin, 
>>> especially when he has used "eat(new CornMuffin())".
>>>
>>> This kind of pattern complete adverted the use of compiler 
>>>       
>> protections.
>>     
>>> Cheers,
>>> -Polar
>>>
>>>
>>>
>>>       
>> --
>> Dan Diephouse
>> Envoi Solutions
>> http://envoisolutions.com | http://netzooid.com/blog
>>
>>     


Re: Checkstyle

Posted by Polar Humenn <ph...@iona.com>.
So, I propose to remove the "AbstractClassName" module from checkstyle.

Should there be more argument, a vote, or somebody just does it?
I'm not a committer.

I'd like this done before I submit a patch for HTTPConduit stuff.

Cheers,
-Polar

Sergey Beryozkin wrote:
> Thanks, I agree that my generalization was wrong...I was still think 
> about abstract classes as the sceletal impls of the non-trivial 
> interfaces when suggetsing that...
>
> Cheers, Sergey
>
> ----- Original Message ----- From: "Polar Humenn" <ph...@iona.com>
> To: <cx...@incubator.apache.org>
> Sent: Wednesday, April 04, 2007 3:23 PM
> Subject: Re: Checkstyle
>
>
>>
>> abstract class Myclass implements java.util.Observer
>>
>> Does the the class name really have to be an "AbstractObserver"?
>>
>> Cheers,
>> -Polar
>>
>> Sergey Beryozkin wrote:
>>>> I really don't like such generalizations. Just because there is a 
>>>> "high chance" that "the user" will do something doesn't afford a
>>>> regulation for prerequisites.
>>>
>>> This is fare enough...Just out of curiosity and for my own 
>>> education, I'd be interested to see a practical example showing why 
>>> would someone write the abstract class implementing the interface 
>>> and then have this abstract class as one of the (in or out) 
>>> parameters in the method signature...
>>>
>>> Thanks, Sergey
>>>
>>>
>>>
>>>> Sergey Beryozkin wrote:
>>>>> *snip*
>>>>>
>>>>> 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.
>>>>>
>>>>
>>>> I really don't like such generalizations. Just because there is a 
>>>> "high chance" that "the user" will do something doesn't afford a
>>>> regulation for prerequisites.
>>>>
>>>> Cheers,
>>>> -Polar
>>>
>>
>


Re: Checkstyle

Posted by Sergey Beryozkin <se...@iona.com>.
Thanks, I agree that my generalization was wrong...I was still think about abstract classes as the sceletal impls of the non-trivial 
interfaces when suggetsing that...

Cheers, Sergey

----- Original Message ----- 
From: "Polar Humenn" <ph...@iona.com>
To: <cx...@incubator.apache.org>
Sent: Wednesday, April 04, 2007 3:23 PM
Subject: Re: Checkstyle


>
> abstract class Myclass implements java.util.Observer
>
> Does the the class name really have to be an "AbstractObserver"?
>
> Cheers,
> -Polar
>
> Sergey Beryozkin wrote:
>>> I really don't like such generalizations. Just because there is a "high chance" that "the user" will do something doesn't afford 
>>> a
>>> regulation for prerequisites.
>>
>> This is fare enough...Just out of curiosity and for my own education, I'd be interested to see a practical example showing why 
>> would someone write the abstract class implementing the interface and then have this abstract class as one of the (in or out) 
>> parameters in the method signature...
>>
>> Thanks, Sergey
>>
>>
>>
>>> Sergey Beryozkin wrote:
>>>> *snip*
>>>>
>>>> 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.
>>>>
>>>
>>> I really don't like such generalizations. Just because there is a "high chance" that "the user" will do something doesn't afford 
>>> a
>>> regulation for prerequisites.
>>>
>>> Cheers,
>>> -Polar
>>
> 


Re: Checkstyle

Posted by Polar Humenn <ph...@iona.com>.
abstract class Myclass implements java.util.Observer

Does the the class name really have to be an "AbstractObserver"?

Cheers,
-Polar

Sergey Beryozkin wrote:
>> I really don't like such generalizations. Just because there is a 
>> "high chance" that "the user" will do something doesn't afford a
>> regulation for prerequisites.
>
> This is fare enough...Just out of curiosity and for my own education, 
> I'd be interested to see a practical example showing why would someone 
> write the abstract class implementing the interface and then have this 
> abstract class as one of the (in or out) parameters in the method 
> signature...
>
> Thanks, Sergey
>
>
>
>> Sergey Beryozkin wrote:
>>> *snip*
>>>
>>> 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.
>>>
>>
>> I really don't like such generalizations. Just because there is a 
>> "high chance" that "the user" will do something doesn't afford a
>> regulation for prerequisites.
>>
>> Cheers,
>> -Polar
>


Re: Checkstyle

Posted by Sergey Beryozkin <se...@iona.com>.
> I really don't like such generalizations. Just because there is a "high chance" that "the user" will do something doesn't afford a
> regulation for prerequisites.

This is fare enough...Just out of curiosity and for my own education, I'd be interested to see a practical example showing why would 
someone write the abstract class implementing the interface and then have this abstract class as one of the (in or out) parameters 
in the method signature...

Thanks, Sergey



> Sergey Beryozkin wrote:
>> *snip*
>>
>> 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.
>>
>
> I really don't like such generalizations. Just because there is a "high chance" that "the user" will do something doesn't afford a
> regulation for prerequisites.
>
> Cheers,
> -Polar


Re: Checkstyle

Posted by Polar Humenn <ph...@iona.com>.
Sergey Beryozkin wrote:
> *snip*
>
> 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.
>   

I really don't like such generalizations. Just because there is a "high 
chance" that "the user" will do something doesn't afford a regulation 
for prerequisites.

Cheers,
-Polar

Re: Checkstyle

Posted by Sergey Beryozkin <se...@iona.com>.
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. 

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. 
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)... 

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 ----- 
From: "Glynn, Eoghan" <eo...@iona.com>
To: <cx...@incubator.apache.org>
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. 

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. 

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. 

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] 
> Sent: 04 April 2007 00:50
> To: cxf-dev@incubator.apache.org
> Subject: Re: Checkstyle
> 
> I completely agree that we should get rid of this rule.
> 
> First of all, Aegis from XFire use Type which is abstract, 
> and I don't want to change this for migration reasons which 
> is one of the reasons pmd is disabled for this module.
> 
> Second, I agree that the Abstract/base/factory naming is 
> incredibly awkward.
> I hear some mumblings of "just use interfaces" - but abstract 
> classes provide a much more robust way to add features in the 
> future. With an interface, if you add a method, it will break 
> every class that implemented that interface. With abstract 
> classes if you add a new method, all you need to do is 
> provide a default implementation of it and everything will 
> work swell in the future.  So I tend to use abstract classes 
> more and more to avoid future incompatibilities 
> (AbstractWSFeature, AbstractServiceFactoryBean, 
> AbstractEndpointFactory). With at least the first two, I 
> would like to get ride of the Abstract.
> 
> - Dan
> 
> On 4/3/07, Polar Humenn <ph...@iona.com> wrote:
> >
> > Is there a "good" motivation of why "abstract" classes have to be 
> > named "Abstract" "Base" or "Factory"?
> >
> > If a class is declared "abstract", I want the *compiler* to 
> tell the 
> > developer that s/he has not filled out a particular 
> functionality when 
> > s/he extends the abstract class. Not that I want it named 
> "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 
> 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, 
> > 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 
> at run time
> >       instead of compile time, where it should be caught! And 
> > sometimes causing
> >       a loss of time to find it.
> >
> > For example, with the current checkstyle rule I could be forced to 
> > write the class with a default implementation expecting it to be 
> > 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() + 
> " 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 
> > out why his application still says he has a BLUEBERRY muffin, 
> > especially when he has used "eat(new CornMuffin())".
> >
> > This kind of pattern complete adverted the use of compiler 
> protections.
> >
> > Cheers,
> > -Polar
> >
> >
> >
> 
> 
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
> 

RE: Checkstyle

Posted by "Glynn, Eoghan" <eo...@iona.com>.

Well the mumblings were more like advice to use interfaces *in addition
to* abstract classes, not *instead of* abstract classes. 

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. 

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. 

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] 
> Sent: 04 April 2007 00:50
> To: cxf-dev@incubator.apache.org
> Subject: Re: Checkstyle
> 
> I completely agree that we should get rid of this rule.
> 
> First of all, Aegis from XFire use Type which is abstract, 
> and I don't want to change this for migration reasons which 
> is one of the reasons pmd is disabled for this module.
> 
> Second, I agree that the Abstract/base/factory naming is 
> incredibly awkward.
> I hear some mumblings of "just use interfaces" - but abstract 
> classes provide a much more robust way to add features in the 
> future. With an interface, if you add a method, it will break 
> every class that implemented that interface. With abstract 
> classes if you add a new method, all you need to do is 
> provide a default implementation of it and everything will 
> work swell in the future.  So I tend to use abstract classes 
> more and more to avoid future incompatibilities 
> (AbstractWSFeature, AbstractServiceFactoryBean, 
> AbstractEndpointFactory). With at least the first two, I 
> would like to get ride of the Abstract.
> 
> - Dan
> 
> On 4/3/07, Polar Humenn <ph...@iona.com> wrote:
> >
> > Is there a "good" motivation of why "abstract" classes have to be 
> > named "Abstract" "Base" or "Factory"?
> >
> > If a class is declared "abstract", I want the *compiler* to 
> tell the 
> > developer that s/he has not filled out a particular 
> functionality when 
> > s/he extends the abstract class. Not that I want it named 
> "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 
> 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, 
> > 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 
> at run time
> >       instead of compile time, where it should be caught! And 
> > sometimes causing
> >       a loss of time to find it.
> >
> > For example, with the current checkstyle rule I could be forced to 
> > write the class with a default implementation expecting it to be 
> > 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() + 
> " 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 
> > out why his application still says he has a BLUEBERRY muffin, 
> > especially when he has used "eat(new CornMuffin())".
> >
> > This kind of pattern complete adverted the use of compiler 
> protections.
> >
> > Cheers,
> > -Polar
> >
> >
> >
> 
> 
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
> 

Re: Checkstyle

Posted by Dan Diephouse <da...@envoisolutions.com>.
I completely agree that we should get rid of this rule.

First of all, Aegis from XFire use Type which is abstract, and I don't want
to change this for migration reasons which is one of the reasons pmd is
disabled for this module.

Second, I agree that the Abstract/base/factory naming is incredibly awkward.
I hear some mumblings of "just use interfaces" - but abstract classes
provide a much more robust way to add features in the future. With an
interface, if you add a method, it will break every class that implemented
that interface. With abstract classes if you add a new method, all you need
to do is provide a default implementation of it and everything will work
swell in the future.  So I tend to use abstract classes more and more to
avoid future incompatibilities (AbstractWSFeature,
AbstractServiceFactoryBean, AbstractEndpointFactory). With at least the
first two, I would like to get ride of the Abstract.

- Dan

On 4/3/07, Polar Humenn <ph...@iona.com> wrote:
>
> Is there a "good" motivation of why "abstract" classes have to be named
> "Abstract" "Base" or "Factory"?
>
> If a class is declared "abstract", I want the *compiler* to tell the
> developer that s/he has not filled out a particular functionality when
> s/he extends the abstract class. Not that I want it named "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 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,
> 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 at run time
>       instead of compile time, where it should be caught! And sometimes
> causing
>       a loss of time to find it.
>
> For example, with the current checkstyle rule I could be forced to write
> the class with
> a default implementation expecting it to be 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() + " 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 out
> why his application still says he has a BLUEBERRY muffin, especially
> when he has used "eat(new CornMuffin())".
>
> This kind of pattern complete adverted the use of compiler protections.
>
> Cheers,
> -Polar
>
>
>


-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

RE: Checkstyle

Posted by "Glynn, Eoghan" <eo...@iona.com>.
 

> -----Original Message-----
> From: Polar Humenn [mailto:phumenn@iona.com] 
> Sent: 03 April 2007 22:52
> To: cxf-dev@incubator.apache.org
> Subject: Re: Checkstyle
> 
> 
> That of course is a simple example that works well with that pattern.
> However, if I don't want the interface. If my abstract class 
> carries other things that are  specific to the class, but do 
> not adhere to an interface very well, like having inner classes,
> 
> abstract class Muffin {
>          class Bits { ... }
> 
>          abstract Bits getBits();
> }


Bits could be modelled as an inner interface within an outter Muffin
interface. So the "inner-ness" of Bits doesn't force Muffin to be a
class. 

But yeah, in general I agree that you don't always want to use an
interface. But most of the time in Java, the
concrete_class--extends-->abstract_class--implements-->interface pattern
works well.


> or common method name collisions:
> 
> Especially if you have interfaces like :
> 
> interface Toaster {
>          String getManufacturer():
>        .....
> }
> 
> interface Washer {
>         String getManufacturer();
>         .....
> }
> 
> and some developer decides he doesn't want separate classes:
> 
> class MyAppliances implements Toaster, Washer { }
> 
> The compiler doesn't complain. (at least it didn't a while 
> ago, is that still so)?


Such name clashes are exactly why Java outlawed multiple class
inheritence.

AFAIK the reasoning is that this isn't an issue when implementing
multiple interfaces because there's no potentially different inherited
implementations of getManufacturer(). So the two getManufacturer()
methods can be treated as being the *same thing*.

But while Java allows multiple interface inheritence, it can't force you
to properly model the domain. In this case the correct relationship
between MyAppliance and Washer is probably composition as opposed to
inheritence. MyApplicance is-a Toaster, but MyApplicance is not a
Washer, rather its composed of a washer and a bunch of other stuff. So:

class MyAppliances implements Toaster {
    private Washer washer = new Washer() { 
       public String getManufacturer() {
          return "WasherCo";
       }
    }

    public String getManufacturer() {
       return "AcmeCrop";
    }

    public Washer getWasher() {
       return washer;
    }
}

So now myApp.getManufacturer() and myApp.getWasher().getManufacturer()
can return different values as expected.

Cheers,
Eoghan

> Cheers,
> -Polar
> 
> Glynn, Eoghan wrote:
> > Remember Java, unlike C++, has interfaces as well as 
> abstract classes.
> >
> > So the typical Java idiom is more like:
> >
> > interface Muffin {
> >     Kind kind();
> > }
> >
> > abstract class AbstractMuffin implements Muffin {
> >     // common impl ...
> >
> >     public abstract kind();
> > }
> >
> > class BlueBerryMuffin extends AbstractMuffin {  
> >     public Kind kind() {
> >         return Kind.BLUEBERRY;
> >     }
> > }
> >
> > The key here is that parameter types and other interactions 
> are all done
> > in terms of the interface type, Muffin.
> >
> > So your objection in terms of method signature like 
> eat(AbstractMuffin
> > m) goes away. In java this parameter would usually be of 
> the interface
> > type, e.g. eat(Muffin m).
> >
> >
> > The misspelt method that was supposed to be overriding a 
> default impl
> > can actually be compiler-enforced in Java, using the @Override
> > annotation [1].
> >
> > So the following code:
> >
> > class CornMuffin extends AbstractMuffin {  
> >     @Override
> >     public Kind keind() {
> >         return Kind.CORN;
> >     }
> > }
> >
> > will fail to compile.
> >
> > /Eoghan
> >
> > [1] http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Override.html
> >
> >   
> >> -----Original Message-----
> >> From: Polar Humenn [mailto:phumenn@iona.com] 
> >> Sent: 03 April 2007 22:10
> >> To: cxf-dev@incubator.apache.org
> >> Subject: Checkstyle
> >>
> >> Is there a "good" motivation of why "abstract" classes have 
> >> to be named "Abstract" "Base" or "Factory"?
> >>
> >> If a class is declared "abstract", I want the *compiler* to 
> >> tell the developer that s/he has not filled out a particular 
> >> functionality when s/he extends the abstract class. Not that 
> >> I want it named "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 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, 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 
> at run time
> >>       instead of compile time, where it should be caught! And 
> >> sometimes causing
> >>       a loss of time to find it.
> >>
> >> For example, with the current checkstyle rule I could be 
> >> forced to write the class with a default implementation 
> >> expecting it to be 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() + " 
> >> 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 out why his application still says he has a BLUEBERRY 
> >> muffin, especially when he has used "eat(new CornMuffin())".
> >>
> >> This kind of pattern complete adverted the use of compiler 
> >> protections.
> >>
> >> Cheers,
> >> -Polar
> >>
> >>
> >>
> >>     
> 
> 

Re: Checkstyle

Posted by Polar Humenn <ph...@iona.com>.
That of course is a simple example that works well with that pattern.
However, if I don't want the interface. If my abstract class carries 
other things that are  specific to the class, but do not adhere to an 
interface very well, like having inner classes,

abstract class Muffin {
         class Bits { ... }

         abstract Bits getBits();
}

or common method name collisions:

Especially if you have interfaces like :

interface Toaster {
         String getManufacturer():
       .....
}

interface Washer {
        String getManufacturer();
        .....
}

and some developer decides he doesn't want separate classes:

class MyAppliances implements Toaster, Washer {
}

The compiler doesn't complain. (at least it didn't a while ago, is that 
still so)?


Cheers,
-Polar

Glynn, Eoghan wrote:
> Remember Java, unlike C++, has interfaces as well as abstract classes.
>
> So the typical Java idiom is more like:
>
> interface Muffin {
>     Kind kind();
> }
>
> abstract class AbstractMuffin implements Muffin {
>     // common impl ...
>
>     public abstract kind();
> }
>
> class BlueBerryMuffin extends AbstractMuffin {  
>     public Kind kind() {
>         return Kind.BLUEBERRY;
>     }
> }
>
> The key here is that parameter types and other interactions are all done
> in terms of the interface type, Muffin.
>
> So your objection in terms of method signature like eat(AbstractMuffin
> m) goes away. In java this parameter would usually be of the interface
> type, e.g. eat(Muffin m).
>
>
> The misspelt method that was supposed to be overriding a default impl
> can actually be compiler-enforced in Java, using the @Override
> annotation [1].
>
> So the following code:
>
> class CornMuffin extends AbstractMuffin {  
>     @Override
>     public Kind keind() {
>         return Kind.CORN;
>     }
> }
>
> will fail to compile.
>
> /Eoghan
>
> [1] http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Override.html
>
>   
>> -----Original Message-----
>> From: Polar Humenn [mailto:phumenn@iona.com] 
>> Sent: 03 April 2007 22:10
>> To: cxf-dev@incubator.apache.org
>> Subject: Checkstyle
>>
>> Is there a "good" motivation of why "abstract" classes have 
>> to be named "Abstract" "Base" or "Factory"?
>>
>> If a class is declared "abstract", I want the *compiler* to 
>> tell the developer that s/he has not filled out a particular 
>> functionality when s/he extends the abstract class. Not that 
>> I want it named "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 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, 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 at run time
>>       instead of compile time, where it should be caught! And 
>> sometimes causing
>>       a loss of time to find it.
>>
>> For example, with the current checkstyle rule I could be 
>> forced to write the class with a default implementation 
>> expecting it to be 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() + " 
>> 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 out why his application still says he has a BLUEBERRY 
>> muffin, especially when he has used "eat(new CornMuffin())".
>>
>> This kind of pattern complete adverted the use of compiler 
>> protections.
>>
>> Cheers,
>> -Polar
>>
>>
>>
>>     


Re: Proposing minor change to AbstractBeanDefinitionParser.getJaxbPackage()

Posted by Dan Diephouse <da...@envoisolutions.com>.
I suppose thats fine.

You might also want to consider returning multiple packages:

protected String getJaxbPackage() {
 return "foo.bar1:foo.bar2:another,package";
}

Reagrds,
- Dan

On 4/3/07, Bhole, Ulhas <ul...@iona.com> wrote:
>
> Hi,
>
> I have a configurartion usecase where I need to decide the package name
> based on the element that is getting parsed in
> org.apache.cxf.configuration.spring.AbstractBeanDefinitionParser.mapElem
> entToJaxbProperty() method.
>
> Currently it calls on to getJaxbPackage() which doesn't provided
> flexibility of returning different pacakge names based on the item being
> processed.
>
> I have a scenario where my configuration schema imports some other
> schema for the types and wires it's own configuration type which contain
> elemements of some local type plus elements of some types from imported
> schema.
>
> If we can modify the getJaxbPackage() method to pass in namespace URI of
> the item being processed it will allow the me to decide what package
> name to return.
>
> Original code looks like:
>
> protected void mapElementToJaxbProperty(Element parent,
> BeanDefinitionBuilder bean, QName name,
>                                             String string, Class<?> c) {
>         Node data = null;
>      ...
>         if (data == null) {
>             return;
>         }
>
>         JAXBContext context = null;
>         Object obj = null;
>         try {
>             context = JAXBContext.newInstance(getJaxbPackage(),
> getClass().getClassLoader());
>             Unmarshaller u = context.createUnmarshaller();
>         ...
>     }
>
>     protected String getJaxbPackage() {
>         return "";
>     }
>
> Proposed change is:
>
> protected void mapElementToJaxbProperty(Element parent,
> BeanDefinitionBuilder bean, QName name,
>                                             String string, Class<?> c) {
>         Node data = null;
>      ...
>         if (data == null) {
>             return;
>         }
>
>         JAXBContext context = null;
>         Object obj = null;
>         try {
>             context =
> JAXBContext.newInstance(getJaxbPackage(data.getNamespaceURI()),
> getClass().getClassLoader());
>             Unmarshaller u = context.createUnmarshaller();
>         ...
>     }
>
>     protected String getJaxbPackage(String uri) {
>         return "";
>     }
>
>
> There are 4 classes currently which extends this class (2 in http config
> and 2 in JMS config) which will need the change along with the change I
> mentioned but it will allow a flexibility in other usecases where the
> configuration is composed of elements from multiple schemas and multiple
> namespaces.
>
> Any objections?
>
> Regards,
>
> Ulhas Bhole
>
>


-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Proposing minor change to AbstractBeanDefinitionParser.getJaxbPackage()

Posted by "Bhole, Ulhas" <ul...@iona.com>.
Hi, 

I have a configurartion usecase where I need to decide the package name
based on the element that is getting parsed in
org.apache.cxf.configuration.spring.AbstractBeanDefinitionParser.mapElem
entToJaxbProperty() method.

Currently it calls on to getJaxbPackage() which doesn't provided
flexibility of returning different pacakge names based on the item being
processed. 

I have a scenario where my configuration schema imports some other
schema for the types and wires it's own configuration type which contain
elemements of some local type plus elements of some types from imported
schema. 

If we can modify the getJaxbPackage() method to pass in namespace URI of
the item being processed it will allow the me to decide what package
name to return. 

Original code looks like:

protected void mapElementToJaxbProperty(Element parent,
BeanDefinitionBuilder bean, QName name,
                                            String string, Class<?> c) {
        Node data = null;
     ...
        if (data == null) {
            return;
        }

        JAXBContext context = null;
        Object obj = null;
        try {
            context = JAXBContext.newInstance(getJaxbPackage(),
getClass().getClassLoader());
            Unmarshaller u = context.createUnmarshaller();
        ...
    }

    protected String getJaxbPackage() {
        return "";
    }

Proposed change is:

protected void mapElementToJaxbProperty(Element parent,
BeanDefinitionBuilder bean, QName name,
                                            String string, Class<?> c) {
        Node data = null;
     ...
        if (data == null) {
            return;
        }

        JAXBContext context = null;
        Object obj = null;
        try {
            context =
JAXBContext.newInstance(getJaxbPackage(data.getNamespaceURI()),
getClass().getClassLoader());
            Unmarshaller u = context.createUnmarshaller();
        ...
    }

    protected String getJaxbPackage(String uri) {
        return "";
    }


There are 4 classes currently which extends this class (2 in http config
and 2 in JMS config) which will need the change along with the change I
mentioned but it will allow a flexibility in other usecases where the
configuration is composed of elements from multiple schemas and multiple
namespaces.

Any objections?

Regards,

Ulhas Bhole


RE: Checkstyle

Posted by "Glynn, Eoghan" <eo...@iona.com>.

Remember Java, unlike C++, has interfaces as well as abstract classes.

So the typical Java idiom is more like:

interface Muffin {
    Kind kind();
}

abstract class AbstractMuffin implements Muffin {
    // common impl ...

    public abstract kind();
}

class BlueBerryMuffin extends AbstractMuffin {  
    public Kind kind() {
        return Kind.BLUEBERRY;
    }
}

The key here is that parameter types and other interactions are all done
in terms of the interface type, Muffin.

So your objection in terms of method signature like eat(AbstractMuffin
m) goes away. In java this parameter would usually be of the interface
type, e.g. eat(Muffin m).


The misspelt method that was supposed to be overriding a default impl
can actually be compiler-enforced in Java, using the @Override
annotation [1].

So the following code:

class CornMuffin extends AbstractMuffin {  
    @Override
    public Kind keind() {
        return Kind.CORN;
    }
}

will fail to compile.

/Eoghan

[1] http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Override.html

> -----Original Message-----
> From: Polar Humenn [mailto:phumenn@iona.com] 
> Sent: 03 April 2007 22:10
> To: cxf-dev@incubator.apache.org
> Subject: Checkstyle
> 
> Is there a "good" motivation of why "abstract" classes have 
> to be named "Abstract" "Base" or "Factory"?
> 
> If a class is declared "abstract", I want the *compiler* to 
> tell the developer that s/he has not filled out a particular 
> functionality when s/he extends the abstract class. Not that 
> I want it named "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 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, 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 at run time
>       instead of compile time, where it should be caught! And 
> sometimes causing
>       a loss of time to find it.
> 
> For example, with the current checkstyle rule I could be 
> forced to write the class with a default implementation 
> expecting it to be 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() + " 
> 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 out why his application still says he has a BLUEBERRY 
> muffin, especially when he has used "eat(new CornMuffin())".
> 
> This kind of pattern complete adverted the use of compiler 
> protections.
> 
> Cheers,
> -Polar
> 
> 
>