JaroslavTulach at 03:55, 26 May 2012 - 2012-05-26 03:55:04

←Older revision Revision as of 03:55, 26 May 2012
Line 1: Line 1:
-
Having an [[abstract class]] with package private [[InvisibleAbstractMethod|invisible abstract method]] effectively prevents anyone using such [[API]] to subclass it. This can be considered as [[good]] [[:APIDesignPatterns|API design pattern]], especially if such pattern is used since initial version of the [[API]].
+
Having a package private [[InvisibleAbstractMethod|invisible abstract method]] in an [[abstract class]] effectively prevents anyone using such [[API]] to subclass it. This can be considered as [[good]] [[:APIDesignPatterns|API design pattern]], especially if such pattern is used since initial version of the [[API]].
However it can also turn into a huge anti-pattern. Adding first package private ''abstract'' method into an abstract class is in fact an incompatible change. If the class used to be subclassable before, this prevents the subclassing and as such classes that used to compile may compile no more.
However it can also turn into a huge anti-pattern. Adding first package private ''abstract'' method into an abstract class is in fact an incompatible change. If the class used to be subclassable before, this prevents the subclassing and as such classes that used to compile may compile no more.

Demo at 07:44, 18 May 2012 - 2012-05-18 07:44:23

←Older revision Revision as of 07:44, 18 May 2012
Line 1: Line 1:
-
Having an '''abstract''' class with package private [[InvisibleAbstractMethod|invisible abstract method]] effectively prevents anyone using such [[API]] to subclass it. This can be considered as [[good]] [[:APIDesignPatterns|API design pattern]], especially if such pattern is used since initial version of the [[API]].
+
Having an [[abstract class]] with package private [[InvisibleAbstractMethod|invisible abstract method]] effectively prevents anyone using such [[API]] to subclass it. This can be considered as [[good]] [[:APIDesignPatterns|API design pattern]], especially if such pattern is used since initial version of the [[API]].
However it can also turn into a huge anti-pattern. Adding first package private ''abstract'' method into an abstract class is in fact an incompatible change. If the class used to be subclassable before, this prevents the subclassing and as such classes that used to compile may compile no more.
However it can also turn into a huge anti-pattern. Adding first package private ''abstract'' method into an abstract class is in fact an incompatible change. If the class used to be subclassable before, this prevents the subclassing and as such classes that used to compile may compile no more.

Apidesign at 12:11, 20 March 2012 - 2012-03-20 12:11:41

←Older revision Revision as of 12:11, 20 March 2012
Line 1: Line 1:
-
Having an '''abstract''' class with package private ''abstract'' method effectively prevents anyone using such [[API]] to subclass it. This can be considered as [[good]] [[:APIDesignPatterns|API design pattern]], especially if such pattern is used since initial version of the [[API]].
+
Having an '''abstract''' class with package private [[InvisibleAbstractMethod|invisible abstract method]] effectively prevents anyone using such [[API]] to subclass it. This can be considered as [[good]] [[:APIDesignPatterns|API design pattern]], especially if such pattern is used since initial version of the [[API]].
However it can also turn into a huge anti-pattern. Adding first package private ''abstract'' method into an abstract class is in fact an incompatible change. If the class used to be subclassable before, this prevents the subclassing and as such classes that used to compile may compile no more.
However it can also turn into a huge anti-pattern. Adding first package private ''abstract'' method into an abstract class is in fact an incompatible change. If the class used to be subclassable before, this prevents the subclassing and as such classes that used to compile may compile no more.

Apidesign at 12:10, 20 March 2012 - 2012-03-20 12:10:19

←Older revision Revision as of 12:10, 20 March 2012
Line 41: Line 41:
-
Some people complained about unnecessary complexity of various [[OOP]] access modifiers - and they were likely right, but this case is worse (from the point of an [[API]] designer) - a change to an implementation detail may change the published [[API]]s!
+
Some people complained about unnecessary complexity of various [[OOP]] access modifiers - and they were likely right, but this case is worse (from the point of an [[API]] designer). So far [[API]] authors needed to care only about '''public''' and '''protected''' elements (as described for example in [[ClarityOfAccessModifiers]]), but it seems that we need to paly attention also to non-visible ones - a change to an implementation detail may change the published [[API]]s!
[[Category:APIDesignPatterns:Evolution]]
[[Category:APIDesignPatterns:Evolution]]
[[Category:APIDesignPatterns:Anti]]
[[Category:APIDesignPatterns:Anti]]

Apidesign at 12:07, 20 March 2012 - 2012-03-20 12:07:17

←Older revision Revision as of 12:07, 20 March 2012
Line 29: Line 29:
<source lang="bash">
<source lang="bash">
-
Warning: public class api.AbstractClass can't be extended because contains the following member:
+
Warning: public class api.AbstractClass cannot be extended because contains the following member:
method abstract void api.AbstractClass.youWillNeverImplementMe()
method abstract void api.AbstractClass.youWillNeverImplementMe()
</source>
</source>

Apidesign at 12:06, 20 March 2012 - 2012-03-20 12:06:49

←Older revision Revision as of 12:06, 20 March 2012
Line 29: Line 29:
<source lang="bash">
<source lang="bash">
-
Warning: public class api.AbstractClass can't be extended because contains the following member: method abstract void api.AbstractClass.youWillNeverImplementMe()
+
Warning: public class api.AbstractClass can't be extended because contains the following member:
 +
method abstract void api.AbstractClass.youWillNeverImplementMe()
</source>
</source>

Apidesign at 12:06, 20 March 2012 - 2012-03-20 12:06:22

←Older revision Revision as of 12:06, 20 March 2012
Line 1: Line 1:
-
Having an '''abstract''' class with package private ''abstract'' method effectively prevents anyone to subclass it. That can be considered as [[good]] [[:APIDesignPatterns|API design pattern]], especially if that is something one starts with.
+
Having an '''abstract''' class with package private ''abstract'' method effectively prevents anyone using such [[API]] to subclass it. This can be considered as [[good]] [[:APIDesignPatterns|API design pattern]], especially if such pattern is used since initial version of the [[API]].
-
However it can also turn into a huge anti-pattern. Adding first package private ''abstract'' method into an abstract class is in fact an incompatible change. If the class used to be subclassable before, this prevents the subclassing and as such classes that used to compile may compile no longer.
+
However it can also turn into a huge anti-pattern. Adding first package private ''abstract'' method into an abstract class is in fact an incompatible change. If the class used to be subclassable before, this prevents the subclassing and as such classes that used to compile may compile no more.
-
The hidden catch is that tools like [[Sigtest]] are unlikely to catch this situation, as they don't care about package private methods! Some people complained about unnecesary complexity of various [[OOP]] access modifiers - and they were likely right, but this case worse (from the point of an [[API]] designer) - a change to an implementation detail may change the published [[API]]s!
+
If the original version of a class contains one abstract method:
-
[[TBD]]
+
<source lang="java">
 +
package api;
 +
/** version 1.0 */
 +
public abstract class AbstractClass {
 +
public abstract void subclassMeAndImplementMe();
 +
}
 +
</source>
 +
 
 +
and later somebody adds a new ''implementation detail'':
 +
 
 +
<source lang="java">
 +
package api;
 +
/** version 2.0 */
 +
public abstract class AbstractClass {
 +
public abstract void subclassMeAndImplementMe();
 +
// hidden, not public new method
 +
abstract void youWillNeverImplementMe();
 +
}
 +
</source>
 +
then we are facing an incompatible change. Inspite of not changing the visible methods of the class at all!
 +
 
 +
The hidden catch is that tools like [[Sigtest]] are unlikely to catch this situation, as they don't care about package private methods! [[Sigtest]] only emits a warning:
 +
 
 +
<source lang="bash">
 +
Warning: public class api.AbstractClass can't be extended because contains the following member: method abstract void api.AbstractClass.youWillNeverImplementMe()
 +
</source>
 +
 
 +
However warning is not enough, this is an incompatible change and it should be reported as such. The error should be same as in case somebody makes the ''youWillNeverImplementMe'' method '''public abstract'''. In such situation [[sigtest]] properly reports error:
 +
 
 +
<source lang="bash">
 +
Class api.AbstractClass:
 +
"E5.2 - Adding abstract methods" : method public abstract void api.AbstractClass.youWillNeverImplementMe()
 +
</source>
 +
 
 +
 
 +
Some people complained about unnecessary complexity of various [[OOP]] access modifiers - and they were likely right, but this case is worse (from the point of an [[API]] designer) - a change to an implementation detail may change the published [[API]]s!
[[Category:APIDesignPatterns:Evolution]]
[[Category:APIDesignPatterns:Evolution]]
[[Category:APIDesignPatterns:Anti]]
[[Category:APIDesignPatterns:Anti]]

JaroslavTulach at 23:26, 9 March 2012 - 2012-03-09 23:26:26

←Older revision Revision as of 23:26, 9 March 2012
Line 1: Line 1:
Having an '''abstract''' class with package private ''abstract'' method effectively prevents anyone to subclass it. That can be considered as [[good]] [[:APIDesignPatterns|API design pattern]], especially if that is something one starts with.
Having an '''abstract''' class with package private ''abstract'' method effectively prevents anyone to subclass it. That can be considered as [[good]] [[:APIDesignPatterns|API design pattern]], especially if that is something one starts with.
-
However it can also turn into a huge anti-pattern. Adding first package private ''abstract'' method into an abstract class is in fact an incompatible change. If the class used to be subclassable before, this prevents it and as such classes that used to compile may compile no longer.
+
However it can also turn into a huge anti-pattern. Adding first package private ''abstract'' method into an abstract class is in fact an incompatible change. If the class used to be subclassable before, this prevents the subclassing and as such classes that used to compile may compile no longer.
-
The hidden catch is that tools like [[Sigtest]] are unlikely to catch this situation, as they don't care about package private methods!
+
The hidden catch is that tools like [[Sigtest]] are unlikely to catch this situation, as they don't care about package private methods! Some people complained about unnecesary complexity of various [[OOP]] access modifiers - and they were likely right, but this case worse (from the point of an [[API]] designer) - a change to an implementation detail may change the published [[API]]s!
[[TBD]]
[[TBD]]

JaroslavTulach: New page: Having an '''abstract''' class with package private ''abstract'' method effectively prevents anyone to subclass it. That can be considered as good [[:APIDesignPatterns|API design patte... - 2012-03-09 17:41:12

New page: Having an '''abstract''' class with package private ''abstract'' method effectively prevents anyone to subclass it. That can be considered as good [[:APIDesignPatterns|API design patte...

New page

Having an '''abstract''' class with package private ''abstract'' method effectively prevents anyone to subclass it. That can be considered as [[good]] [[:APIDesignPatterns|API design pattern]], especially if that is something one starts with.

However it can also turn into a huge anti-pattern. Adding first package private ''abstract'' method into an abstract class is in fact an incompatible change. If the class used to be subclassable before, this prevents it and as such classes that used to compile may compile no longer.

The hidden catch is that tools like [[Sigtest]] are unlikely to catch this situation, as they don't care about package private methods!

[[TBD]]


[[Category:APIDesignPatterns:Evolution]]
[[Category:APIDesignPatterns:Anti]]