Cordeo: Correct typo: know => known - 2010-04-14 15:07:39

Correct typo: know => known

←Older revision Revision as of 15:07, 14 April 2010
Line 10: Line 10:
</source>
</source>
-
Interfaces contain '''public''' methods which are know to have [[ClarityOfAccessModifiers|multiple meanings]] as such they are often subject to double use. One can prevent that by usage of [[ImplementOnlyAbstractClass]] pattern, yet it may not be always the preferred solution.
+
Interfaces contain '''public''' methods which are known to have [[ClarityOfAccessModifiers|multiple meanings]] as such they are often subject to double use. One can prevent that by usage of [[ImplementOnlyAbstractClass]] pattern, yet it may not be always the preferred solution.
=== Implement Only Interface ===
=== Implement Only Interface ===

84.56.232.129: /* Reexporting API */ - 2009-04-13 05:33:34

Reexporting API

←Older revision Revision as of 05:33, 13 April 2009
Line 47: Line 47:
=== Reexporting API ===
=== Reexporting API ===
-
Possible problem may arise when the ''MyProvider'' class is part of [[API]] of its module. Then other modules can use it and indeed, can also call its methods. Then the clarity of the ''Provider'' methods lost. However this is not fault of the original ''NonMixedFactory'' [[API]], but fault of this new one which re-exports the interface.
+
Possible problem may arise when the ''MyProvider'' class is part of [[API]] of its module. Then other modules can use it and indeed, can also call its methods. Then the clarity of the ''Provider'' methods is lost. However this is not fault of the original ''NonMixedFactory'' [[API]], but fault of this new one which re-exports the interface.
The original [[API]] has still its [[clarity]], but the whole system's single meaning is compromised by additional [[API]]s. There are just tho things the author of the original [[API]] can do about this:
The original [[API]] has still its [[clarity]], but the whole system's single meaning is compromised by additional [[API]]s. There are just tho things the author of the original [[API]] can do about this:

JaroslavTulach: /* By Passing */ - 2009-04-12 18:17:45

By Passing

←Older revision Revision as of 18:17, 12 April 2009
Line 66: Line 66:
Then other modules can get access to such JPanel through AWT component hierarchy and use '''instanceof''' check and cast to safely get foreign ''Provider'' implementation which can then be ''called''.
Then other modules can get access to such JPanel through AWT component hierarchy and use '''instanceof''' check and cast to safely get foreign ''Provider'' implementation which can then be ''called''.
-
However this the fact that there is some ''JPanel'' that can be cast to ''Provider'' is an example of [[APITypes|runtime API]]. As such this means the module providing ''MyPanel'' is also providing additional [[API]] and we are in similar to situation analysed in ''Reexporting API'' section.
+
However the fact that there is some ''JPanel'' that can be cast to ''Provider'' is an example of another [[APITypes|API type]] - a kind of runtime API. This means the module providing ''MyPanel'' is also providing additional [[API]] (an information that there can be a ''JPanel'' that also implements ''Provider'') and we are in situation similar to one analysed in ''Reexporting API'' section.

JaroslavTulach: /* By Passing */ - 2009-04-12 18:13:43

By Passing

←Older revision Revision as of 18:13, 12 April 2009
Line 64: Line 64:
</source>
</source>
-
Then other modules can get access to such JPanel through AWT component hierarchy and use '''instanceof''' check to safely get foreign ''Provider'' implementation which can then be ''called''.
+
Then other modules can get access to such JPanel through AWT component hierarchy and use '''instanceof''' check and cast to safely get foreign ''Provider'' implementation which can then be ''called''.
However this the fact that there is some ''JPanel'' that can be cast to ''Provider'' is an example of [[APITypes|runtime API]]. As such this means the module providing ''MyPanel'' is also providing additional [[API]] and we are in similar to situation analysed in ''Reexporting API'' section.
However this the fact that there is some ''JPanel'' that can be cast to ''Provider'' is an example of [[APITypes|runtime API]]. As such this means the module providing ''MyPanel'' is also providing additional [[API]] and we are in similar to situation analysed in ''Reexporting API'' section.

JaroslavTulach: /* Reexporting API */ - 2009-04-12 18:12:39

Reexporting API

←Older revision Revision as of 18:12, 12 April 2009
Line 49: Line 49:
Possible problem may arise when the ''MyProvider'' class is part of [[API]] of its module. Then other modules can use it and indeed, can also call its methods. Then the clarity of the ''Provider'' methods lost. However this is not fault of the original ''NonMixedFactory'' [[API]], but fault of this new one which re-exports the interface.
Possible problem may arise when the ''MyProvider'' class is part of [[API]] of its module. Then other modules can use it and indeed, can also call its methods. Then the clarity of the ''Provider'' methods lost. However this is not fault of the original ''NonMixedFactory'' [[API]], but fault of this new one which re-exports the interface.
-
The original [[API]] has still its [[clarity]], but the whole system's single meaning is compromised by additional [[API]]s. There is not much the author of the original [[API]] can do about this, then hope others won't do silly things like this or using [[ImplementOnlyAbstractClass]] pattern. I personally prefer to hope.
+
The original [[API]] has still its [[clarity]], but the whole system's single meaning is compromised by additional [[API]]s. There are just tho things the author of the original [[API]] can do about this:
 +
* hope others won't do such silly things during re-export
 +
* use [[ImplementOnlyAbstractClass]] pattern
 +
I personally prefer to just hope. So far it work fine, I have not found a module that would improperly re-export my [[API]] interfaces.
=== By Passing ===
=== By Passing ===

JaroslavTulach: /* Silly Usage */ - 2009-04-12 18:09:37

Silly Usage

←Older revision Revision as of 18:09, 12 April 2009
Line 30: Line 30:
There is no way some other module using [[API]] could get access to instance of such ''Provider'' implementation. As such the ''Provider'' methods has just a single meaning: ''implement me!''.
There is no way some other module using [[API]] could get access to instance of such ''Provider'' implementation. As such the ''Provider'' methods has just a single meaning: ''implement me!''.
-
=== Silly Usage ===
+
=== Self Usage ===
One might argue, that the same module (e.g. compilation and runtime unit) can start to access its own implementation:
One might argue, that the same module (e.g. compilation and runtime unit) can start to access its own implementation:

JaroslavTulach at 17:57, 12 April 2009 - 2009-04-12 17:57:35

←Older revision Revision as of 17:57, 12 April 2009
Line 1: Line 1:
-
By exposing a [[Java]] '''interface''' in an [[API]] one usually creates two sides of an [[API]]. One for [[ClientAPI|clients]] that may call methods on instances assignable to that interface and one for [[ProviderAPI|providers]] that may implement that interface. This is often not really desirable. Each of these [[API]] types has different [[evolution]] characteristics. Also the [[clarity]] of such interface methods may not be as clear as it could. More about this in [[ClarityOfAccessModifiers]] and [[ClarityOfTypes]].
+
By exposing a [[Java]] '''interface''' in an [[API]] one usually creates [[3SidesToEveryAPI|two sides of an API]]. One for [[ClientAPI|clients]] that may call methods on instances assignable to that interface and one for [[ProviderAPI|providers]] that may implement that interface. This is often not really desirable. Each of these [[API]] types has different [[evolution]] characteristics. Also the [[clarity]] of such interface methods may not be as clear as it could. More about this in [[ClarityOfAccessModifiers]] and [[ClarityOfTypes]].
Most common example of such ''interface'' with double purpose is ''java.lang.Runnable''. Everyone implements it, there is a lot of methods in [[Java]] standard libraries that also accept it. Another group of such interfaces includes almost all [[JavaBean]]s listeners. Implementing ''java.beans.PropertyChangeListener'' is example [[ProviderAPI]]. Almost everyone wrote such code at least once. Also, as [[JavaBean]]s specification is common, a lot of programmers also used the interface in [[ClientAPI|client]] way after adding following code into their classes:
Most common example of such ''interface'' with double purpose is ''java.lang.Runnable''. Everyone implements it, there is a lot of methods in [[Java]] standard libraries that also accept it. Another group of such interfaces includes almost all [[JavaBean]]s listeners. Implementing ''java.beans.PropertyChangeListener'' is example [[ProviderAPI]]. Almost everyone wrote such code at least once. Also, as [[JavaBean]]s specification is common, a lot of programmers also used the interface in [[ClientAPI|client]] way after adding following code into their classes:

JaroslavTulach at 16:57, 12 April 2009 - 2009-04-12 16:57:16

←Older revision Revision as of 16:57, 12 April 2009
Line 10: Line 10:
</source>
</source>
-
Interfaces contain '''public''' methods which are know to have [[ClarityOfAccessModifiers|multiple meanings]] as such they are often subject to double use. One can prevent that by usage of [[ImplementOnlyAbstractClasses]], yet it may not be always the preferred solution.
+
Interfaces contain '''public''' methods which are know to have [[ClarityOfAccessModifiers|multiple meanings]] as such they are often subject to double use. One can prevent that by usage of [[ImplementOnlyAbstractClass]] pattern, yet it may not be always the preferred solution.
=== Implement Only Interface ===
=== Implement Only Interface ===

JaroslavTulach: New page: By exposing a Java '''interface''' in an API one usually creates two sides of an API. One for clients that may call methods on instances assignable to that interf... - 2009-04-12 16:49:27

New page: By exposing a Java '''interface''' in an API one usually creates two sides of an API. One for clients that may call methods on instances assignable to that interf...

New page

By exposing a [[Java]] '''interface''' in an [[API]] one usually creates two sides of an [[API]]. One for [[ClientAPI|clients]] that may call methods on instances assignable to that interface and one for [[ProviderAPI|providers]] that may implement that interface. This is often not really desirable. Each of these [[API]] types has different [[evolution]] characteristics. Also the [[clarity]] of such interface methods may not be as clear as it could. More about this in [[ClarityOfAccessModifiers]] and [[ClarityOfTypes]].

Most common example of such ''interface'' with double purpose is ''java.lang.Runnable''. Everyone implements it, there is a lot of methods in [[Java]] standard libraries that also accept it. Another group of such interfaces includes almost all [[JavaBean]]s listeners. Implementing ''java.beans.PropertyChangeListener'' is example [[ProviderAPI]]. Almost everyone wrote such code at least once. Also, as [[JavaBean]]s specification is common, a lot of programmers also used the interface in [[ClientAPI|client]] way after adding following code into their classes:
<source lang="java">
public void addPropertyChangeListener(PropertyChangeListener l) { this.listener = l; }
public void removePropertyChangeListener(PropertyChangeListener l) { this.listener = null; }
protected final void fireChange() {
this.listener.firePropertyChange(new PropertyChangeEvent(this, null, null, null));
}
</source>

Interfaces contain '''public''' methods which are know to have [[ClarityOfAccessModifiers|multiple meanings]] as such they are often subject to double use. One can prevent that by usage of [[ImplementOnlyAbstractClasses]], yet it may not be always the preferred solution.

=== Implement Only Interface ===

On the other hand, the algorithm to redesign multi meaning classes into [[ClarityOfTypes|types with clear meanings]] suggests to use create '''interface''' ''Provider'' and claims that such interface methods have just a single meaning. Can '''interface''' have just a single meaning? [[Talk:ClarityOfTypes|parren questioned that]]:

The ''Provider'' '''interface''' is a '''public''' interface residing
within a public class. I can implement this interface and throw it
around at will. For that reason, instances of the interface are
accessible to clients of the API. For the same reason, they say to me:
''implement me and do whatever you want with me, including call me''.

Sort of true, but I still insist that the interface methods have only single meaning within its [[API]]. Imagine there is thousands users of following [[API]]:

<source lang="java" snippet="sidemeanings.Mixed.Clean.Factory"/>

These usages are packaged in their own modules (independent compilation units) and they do not know about each other. They only compile against and use the above [[API]]. Each of them can create a class that implements the ''Provider'' interface. However the only useful thing that can be done with such class, is to create its instance and pass it into the ''NonMixedFactory.create'' method. But that method keeps the instance for private purposes and does not let any other user of the [[API]] to access it.

There is no way some other module using [[API]] could get access to instance of such ''Provider'' implementation. As such the ''Provider'' methods has just a single meaning: ''implement me!''.

=== Silly Usage ===

One might argue, that the same module (e.g. compilation and runtime unit) can start to access its own implementation:

<source lang="java">
class MyProvider implements Provider { ... }

Provider p = new MyProvider();
p.toBeImplementedBySubclass();
</source>

True, this is possible use. More ''misuse'' than a use however. One could call the ''MyProvider'' methods directly by declaring the variable to be of ''MyProvider'' type. So the usage of ''Provider'' in this example is unnecessary.

However even with ''Provider'' variable, the meaning of ''Provider'' in the ''NonMixedFactory'' [[API]] is still clear. That fact that one module decides to internally misuse it can't affect that.

=== Reexporting API ===

Possible problem may arise when the ''MyProvider'' class is part of [[API]] of its module. Then other modules can use it and indeed, can also call its methods. Then the clarity of the ''Provider'' methods lost. However this is not fault of the original ''NonMixedFactory'' [[API]], but fault of this new one which re-exports the interface.

The original [[API]] has still its [[clarity]], but the whole system's single meaning is compromised by additional [[API]]s. There is not much the author of the original [[API]] can do about this, then hope others won't do silly things like this or using [[ImplementOnlyAbstractClass]] pattern. I personally prefer to hope.

=== By Passing ===

Last way for the ''Provider'' implementation to get into hands of other modules is escaping through some other [[API]]. For example one could:

<source lang="java">
class MyPanel extends JPanel implements NonMixedFactory.Provider {
...
}
</source>

Then other modules can get access to such JPanel through AWT component hierarchy and use '''instanceof''' check to safely get foreign ''Provider'' implementation which can then be ''called''.

However this the fact that there is some ''JPanel'' that can be cast to ''Provider'' is an example of [[APITypes|runtime API]]. As such this means the module providing ''MyPanel'' is also providing additional [[API]] and we are in similar to situation analysed in ''Reexporting API'' section.


[[Category:APIDesignPatterns]]
[[Category:APIDesignPatterns:Clarity]]
[[Category:APIDesignPatterns:Creational]]