You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by mc...@apache.org on 2004/06/15 17:35:20 UTC
svn commit: rev 21287 - avalon/trunk/central/site/src/xdocs/central/about/cop
Author: mcconnell
Date: Tue Jun 15 08:35:20 2004
New Revision: 21287
Added:
avalon/trunk/central/site/src/xdocs/central/about/cop/
- copied from rev 21170, avalon/trunk/central/site/src/xdocs/products/runtime/system/af4/cop/
avalon/trunk/central/site/src/xdocs/central/about/cop/basics.xml
Removed:
avalon/trunk/central/site/src/xdocs/central/about/cop/index.xmlx
Modified:
avalon/trunk/central/site/src/xdocs/central/about/cop/guide-cop-in-avalon.xml
avalon/trunk/central/site/src/xdocs/central/about/cop/guide-patterns-avalon.xml
avalon/trunk/central/site/src/xdocs/central/about/cop/guide-patterns-ioc-security.xml
avalon/trunk/central/site/src/xdocs/central/about/cop/guide-patterns-ioc.xml
avalon/trunk/central/site/src/xdocs/central/about/cop/guide-patterns-soc.xml
avalon/trunk/central/site/src/xdocs/central/about/cop/guide-patterns-soii.xml
avalon/trunk/central/site/src/xdocs/central/about/cop/index.xml
avalon/trunk/central/site/src/xdocs/central/about/cop/navigation.xml
Log:
Getting the site into shape.
Added: avalon/trunk/central/site/src/xdocs/central/about/cop/basics.xml
==============================================================================
--- (empty file)
+++ avalon/trunk/central/site/src/xdocs/central/about/cop/basics.xml Tue Jun 15 08:35:20 2004
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<document>
+
+ <properties>
+ <author email="leosimons@apache.org">Leo Simons</author>
+ <title>Avalon Central</title>
+ </properties>
+
+ <body>
+ <section name="OOP best Practices">
+ <subsection name="Recursion Introduction">
+ <p>
+ Use the same interface for communication with components of
+ the same type. It allows the swapping of those components
+ for other components of the same type without breaking existing
+ code.
+ </p>
+ <p>
+ If you need additional functionality, either create proxy
+ objects that implement the interface, or add it by subclassing
+ (hence the name "Recursion Introduction"). Even if
+ there is no recursion happening, it appears to operate in the
+ same manner.
+ </p>
+ </subsection>
+ <subsection name="Eliminate Case Analysis">
+ <p>
+ Avoid testing to see if an object is an instance of a particular
+ class. Usually, if you think you need that approach then a
+ redesign will help immensely.
+ </p>
+ </subsection>
+ <subsection name="Reduce the Number of Arguments">
+ <p>
+ Methods with a half-dozen arguments are hard to read, and can
+ usually be accomplished with an object that represents that
+ set of arguments. It also makes it easier to track down the
+ problems.
+ </p>
+ </subsection>
+ <subsection name="Reduce the Size of Methods">
+ <p>
+ Most of your methods should only need to be a few lines long.
+ Methods that are very long (like 50 lines or so) are too complex,
+ and should be considered guilty of bad design until proven
+ innocent.
+ </p>
+ </subsection>
+ <subsection name="The Top of the Class Hierarchy Should be Abstract">
+ <p>
+ In many cases it is beneficial to provide an abstract base class
+ to extend for your specializations. The majority of the
+ functionality and behavior is well defined. This makes it easier
+ to decipher what the intents of the interface designer were.
+ </p>
+ </subsection>
+ <subsection name="Minimize Accesses to Variables">
+ <p>
+ This point formalizes the principles of data hiding. Try not
+ to expose class attributes to other classes, but protect them
+ by methods. If an attribute changes name, then you only have
+ one place to update the code instead of hundreds.
+ </p>
+ </subsection>
+ <subsection name="Subclasses Should be Specializations">
+ <p>
+ A [subclass] "is a" [superclass]. If what you
+ are trying to do is make a Component into a ComponentManager,
+ then you are violating the spirit of the framework. A better
+ approach is to use containment in that case (i.e. a [class]
+ "has a" [external class]).
+ </p>
+ </subsection>
+ <subsection name="Split Large Classes">
+ <p>
+ If a class has 50+ methods, then it is most likely trying to
+ do too much. Look at separating the functionality into
+ separate components. Like methods that are too long, classes
+ that violate this rule should be considered guilty of wrong
+ design until proven innocent.
+ </p>
+ </subsection>
+ <subsection name="Factor Implementation Differences Into Subcomponents">
+ <p>
+ If a subclass implements a method completely different from
+ the superclass, then it is not really a specialization. It
+ should be split off from that class hierarchy tree.
+ </p>
+ </subsection>
+ <subsection name="Separate Methods that Do Not Communicate">
+ <p>
+ Sometimes in building a framework you run into a case where
+ you have different views of the same data. In these cases,
+ you can have some attributes that describe how to generate
+ the data, and some attributes that describe the data itself.
+ It is better to separate these two views into separate classes.
+ The semantics are different enough to justify this solution.
+ </p>
+ </subsection>
+ <subsection name="Send Messages to Components instead of to This">
+ <p>
+ The point of this point is that you want to build your framework
+ based on components, and not inheritance. Avalon takes this
+ point to heart. In order to illustrate, I will give two examples
+ of the same thing. The scenario is that we have a data structure
+ that we want to output to an arbitrary format.
+ </p>
+ <p>
+ In the following example, we will use the Java <code>this</code>
+ object and an inheritance based framework. As you can see, this
+ would be a bear to maintain, and it won't easily be extended.
+ </p>
+ <source>
+abstract class AbstractExampleDocument
+{
+ // skip some code ...
+public void output(Example structure)
+{
+ if( null != structure )
+ {
+ this.format( structure );
+ }
+}
+
+ protected void format(Example structure);
+}
+ </source>
+ <p>
+ In the next example, we will use the Avalon component based
+ architecture. There is a clean separation between the purpose
+ of the objects, and you can exchange and extend formatting
+ without worrying about any other concerns.
+ </p>
+ <source>
+class DefaultExampleDocument
+{
+// skip some code ...
+public void output(Example structure)
+{
+ ExampleFormatter formatter =
+ (ExampleFormatter) manager.lookup(Roles.FORMATTER);
+ if( null != structure )
+ {
+ formatter.format(structure);
+ }
+}
+}
+ </source>
+ <p>
+ An inheritance based framework (White Box) can be converted
+ into a component based framework (Black Box) structure by
+ replacing overridden methods with method calls (message sends)
+ to components. Component based architecture is much more
+ flexible in this regard.
+ </p>
+ </subsection>
+ <subsection name="Eliminate Implicit Parameter Passing">
+ <p>
+ Just because two methods share the same information within the
+ class does not mean that it should be done in that manner.
+ Many times, the attribute that is shared should be passed
+ as a parameter of the method instead of directly accessing
+ the attribute.
+ </p>
+ </subsection>
+ </section>
+ </body>
+</document>
Modified: avalon/trunk/central/site/src/xdocs/central/about/cop/guide-cop-in-avalon.xml
==============================================================================
--- avalon/trunk/central/site/src/xdocs/products/runtime/system/af4/cop/guide-cop-in-avalon.xml (original)
+++ avalon/trunk/central/site/src/xdocs/central/about/cop/guide-cop-in-avalon.xml Tue Jun 15 08:35:20 2004
@@ -3,7 +3,7 @@
<document>
<properties>
<author email="dev@avalon.apache.org">Avalon Documentation Team</author>
- <title>Merlin Runtime</title>
+ <title>Avalon Central</title>
</properties>
<body>
Modified: avalon/trunk/central/site/src/xdocs/central/about/cop/guide-patterns-avalon.xml
==============================================================================
--- avalon/trunk/central/site/src/xdocs/products/runtime/system/af4/cop/guide-patterns-avalon.xml (original)
+++ avalon/trunk/central/site/src/xdocs/central/about/cop/guide-patterns-avalon.xml Tue Jun 15 08:35:20 2004
@@ -3,7 +3,7 @@
<document>
<properties>
<author email="dev@avalon.apache.org">Avalon Documentation Team</author>
- <title>Merlin Runtime</title>
+ <title>Avalon Central</title>
</properties>
<body>
Modified: avalon/trunk/central/site/src/xdocs/central/about/cop/guide-patterns-ioc-security.xml
==============================================================================
--- avalon/trunk/central/site/src/xdocs/products/runtime/system/af4/cop/guide-patterns-ioc-security.xml (original)
+++ avalon/trunk/central/site/src/xdocs/central/about/cop/guide-patterns-ioc-security.xml Tue Jun 15 08:35:20 2004
@@ -3,7 +3,7 @@
<document>
<properties>
<author email="dev@avalon.apache.org">Avalon Documentation Team</author>
- <title>Merlin Runtime</title>
+ <title>Avalon Central</title>
</properties>
<body>
Modified: avalon/trunk/central/site/src/xdocs/central/about/cop/guide-patterns-ioc.xml
==============================================================================
--- avalon/trunk/central/site/src/xdocs/products/runtime/system/af4/cop/guide-patterns-ioc.xml (original)
+++ avalon/trunk/central/site/src/xdocs/central/about/cop/guide-patterns-ioc.xml Tue Jun 15 08:35:20 2004
@@ -3,7 +3,7 @@
<document>
<properties>
<author email="dev@avalon.apache.org">Avalon Documentation Team</author>
- <title>Merlin Runtime</title>
+ <title>Avalon Central</title>
</properties>
<body>
Modified: avalon/trunk/central/site/src/xdocs/central/about/cop/guide-patterns-soc.xml
==============================================================================
--- avalon/trunk/central/site/src/xdocs/products/runtime/system/af4/cop/guide-patterns-soc.xml (original)
+++ avalon/trunk/central/site/src/xdocs/central/about/cop/guide-patterns-soc.xml Tue Jun 15 08:35:20 2004
@@ -3,7 +3,7 @@
<document>
<properties>
<author email="dev@avalon.apache.org">Avalon Documentation Team</author>
- <title>Merlin Runtime</title>
+ <title>Avalon Central</title>
</properties>
<body>
Modified: avalon/trunk/central/site/src/xdocs/central/about/cop/guide-patterns-soii.xml
==============================================================================
--- avalon/trunk/central/site/src/xdocs/products/runtime/system/af4/cop/guide-patterns-soii.xml (original)
+++ avalon/trunk/central/site/src/xdocs/central/about/cop/guide-patterns-soii.xml Tue Jun 15 08:35:20 2004
@@ -3,7 +3,7 @@
<document>
<properties>
<author email="dev@avalon.apache.org">Avalon Documentation Team</author>
- <title>Merlin Runtime</title>
+ <title>Avalon Central</title>
</properties>
<body>
Modified: avalon/trunk/central/site/src/xdocs/central/about/cop/index.xml
==============================================================================
--- avalon/trunk/central/site/src/xdocs/products/runtime/system/af4/cop/index.xml (original)
+++ avalon/trunk/central/site/src/xdocs/central/about/cop/index.xml Tue Jun 15 08:35:20 2004
@@ -3,11 +3,11 @@
<document>
<properties>
<author email="dev@avalon.apache.org">Avalon Documentation Team</author>
- <title>Merlin Runtime</title>
+ <title>Avalon Central</title>
</properties>
- <body>
- <section name="Introduction">
+ <body>
+ <section name="Component Oriented Programming (COP)">
<p>
Component Oriented Programming, or COP for short, takes Object Oriented
Programming one step further. Regular OOP organizes data objects into
@@ -20,9 +20,7 @@
limitation, a more rigid idea had to be formalized: the component. The key
difference between a regular object and a component is that a component is
completely replaceable.
- </p>
- </section>
- <section name="COP is not just a Buzzword">
+ </p>
<p>
There is a lot of buzz in the industry touting Component Based Design
(CBD). You will find, that the definition of a component in Avalon
@@ -36,6 +34,67 @@
it is designed. In practice, you can't implement COP without first
designing with components in mind.
</p>
+
+ <subsection name="Designing a Component">
+ <p>
+ The first step in writing the component is determining how it is going
+ to be used. There will be a number of times where you have a powerful
+ component that can be used in many different contexts. Those contexts
+ may include executing the component from the command line (separate
+ from Avalon), using it as a part of a sub system, or using it as an
+ integral part of Avalon.
+ </p>
+ <p>
+ All components are an integral part of Avalon, so there is really
+ nothing to be done beyond specifying its interface (role). It is
+ important to identify and document its social contract with the
+ rest of the system. What I mean by social contract is the order
+ of dependencies, what it needs to function, and what it supplies
+ to the rest of the system.
+ </p>
+ <p>
+ A sub system can either be part of Avalon, or live in a separate
+ context. A perfect example would be a component that can function
+ within a Servlet or Enterprise Application. Neither of those
+ contexts are native to Avalon (though they can easily be built
+ on top of Avalon).
+ </p>
+ <p>
+ It is important to do even more careful planning than in the
+ first scenario. The reason is that you want the interface to be
+ as generic as possible and still accurately represent its role.
+ </p>
+ <p>
+ Because the contexts may not be an integral part of Avalon,
+ you must take care to use the component in the same manner as
+ Avalon would. That means that you follow the order of concerns
+ that Avalon has specified for those concerns.
+ </p>
+ <p>
+ When you are designing a component to be run from the command
+ line (or directly by the operating system), try to separate
+ the main function from the component itself. This is imperative
+ in order to maintain the passive API of Avalon. By designing
+ your component in the manner stated in the previous section,
+ you have effectively minimized what the main function has to
+ do.
+ </p>
+ <p>
+ Follow the practice of having an object dedicated to the main
+ function that includes the parsing of the command line parameters
+ and initialization of the component. When the component is used
+ the exact same way in every context (including the command line),
+ you minimize the number of locations to look while debugging.
+ </p>
+ <p><i>
+ A common mistake is to combine the main function in the
+ implementation of the component. This requires violating the
+ contracts and principles that Avalon is built upon. This
+ violation of the pattern of "Inversion of Control" is
+ aptly dubbed "Subversion of Control" (thanks to Steven Coffman
+ for the name of the anti-pattern).
+ </i></p>
+ </subsection>
</section>
</body>
</document>
Modified: avalon/trunk/central/site/src/xdocs/central/about/cop/navigation.xml
==============================================================================
--- avalon/trunk/central/site/src/xdocs/products/runtime/system/af4/cop/navigation.xml (original)
+++ avalon/trunk/central/site/src/xdocs/central/about/cop/navigation.xml Tue Jun 15 08:35:20 2004
@@ -18,10 +18,11 @@
-->
<project>
- <title>Avalon Framework</title>
+ <title>Component Oriented</title>
<body>
<menu>
+ <item name="OO Best Practices" href="basics.html"/>
<item name="COP in Avalon" href="guide-cop-in-avalon.html"/>
<item name="Patterns in Avalon" href="guide-patterns-avalon.html"/>
<item name="IOC Patterns" href="guide-patterns-ioc.html"/>
---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org