[6152] | 1 | /*
|
---|
| 2 | Copyright 2006 by Sean Luke
|
---|
| 3 | Licensed under the Academic Free License version 3.0
|
---|
| 4 | See the file "LICENSE" for more information
|
---|
| 5 | */
|
---|
| 6 |
|
---|
| 7 |
|
---|
| 8 | package ec;
|
---|
| 9 | import ec.util.Parameter;
|
---|
| 10 |
|
---|
| 11 | /*
|
---|
| 12 | * Prototype.java
|
---|
| 13 | *
|
---|
| 14 | * Created: Sat Oct 2 22:04:44 1999
|
---|
| 15 | * By: Sean Luke
|
---|
| 16 | *
|
---|
| 17 | */
|
---|
| 18 |
|
---|
| 19 | /**
|
---|
| 20 | * Prototype classes typically have one or a few <i>prototype instances</i>
|
---|
| 21 | * created during the course of a run. These prototype instances each get
|
---|
| 22 | * setup(...) called on them. From then on, all new instances of a Prototype
|
---|
| 23 | * classes are Cloned from these prototype instances.
|
---|
| 24 | *
|
---|
| 25 | * <p>The purpose of a prototype is to make it possible to ask classes,
|
---|
| 26 | * determined at run-time by user parameters, to instantiate
|
---|
| 27 | * themselves very many times without using the Reflection library, which
|
---|
| 28 | * would be very inefficient.
|
---|
| 29 | *
|
---|
| 30 | * <p>ECJ makes extensive use of Prototypes. Individuals are prototypes.
|
---|
| 31 | * Species are prototypes. Fitness objects are prototypes. Breeding
|
---|
| 32 | * pipelines and selection methods are prototypes. In the GP section,
|
---|
| 33 | * GPNodes and GPTrees are prototypes. In the Rule section, Rulesets and
|
---|
| 34 | * Rules are prototypes. In the Vector section, VectorGenes are prototypes.
|
---|
| 35 | * And so on.
|
---|
| 36 | *
|
---|
| 37 | * <p>ECJ uses Prototypes almost exclusively instead of calling <tt>new</tt>.
|
---|
| 38 | * This is because <tt>new</t> requires that you know, in your code, the exact
|
---|
| 39 | * class of the object to be created. Doing so programmatically essentially
|
---|
| 40 | * precludes being able to set up object graphs dynamically from parameter files.
|
---|
| 41 | *
|
---|
| 42 | * <p>Sadly, clone() is rather slower than calling <tt>new</tt>. However
|
---|
| 43 | * it <i>is</i> a lot faster than calling java.lang.Class.newInstance(),
|
---|
| 44 | * and somewhat faster than rolling our own "cloner" method.
|
---|
| 45 | *
|
---|
| 46 | * <p>Prototypes must be Cloneable, Serializable (through Setup), and of
|
---|
| 47 | * course, Setup.
|
---|
| 48 | *
|
---|
| 49 | * @author Sean Luke
|
---|
| 50 | * @version 1.0
|
---|
| 51 | */
|
---|
| 52 |
|
---|
| 53 | public interface Prototype extends Cloneable, Setup
|
---|
| 54 | {
|
---|
| 55 | /** Creates a new individual cloned from a prototype,
|
---|
| 56 | and suitable to begin use in its own evolutionary
|
---|
| 57 | context.
|
---|
| 58 |
|
---|
| 59 | <p>Typically this should be a full "deep" clone.
|
---|
| 60 | However, you may share certain elements with other objects
|
---|
| 61 | rather than clone hem, depending on the situation:
|
---|
| 62 |
|
---|
| 63 | <p>
|
---|
| 64 | <ul>
|
---|
| 65 | <li>If you hold objects which are shared with other instances,
|
---|
| 66 | don't clone them.
|
---|
| 67 | <li>If you hold objects which must be unique, clone them.
|
---|
| 68 | <li>If you hold objects which were given to you as a gesture
|
---|
| 69 | of kindness, and aren't owned by you, you probably shouldn't clone
|
---|
| 70 | them.
|
---|
| 71 | <li> DON'T attempt to clone: Singletons, Cliques, or Groups.
|
---|
| 72 | <li>Arrays are not cloned automatically; you may need to
|
---|
| 73 | clone an array if you're not sharing it with other instances.
|
---|
| 74 | Arrays have the nice feature of being copyable by calling clone()
|
---|
| 75 | on them.
|
---|
| 76 | </ul>
|
---|
| 77 |
|
---|
| 78 | <p><b>Implementations.</b>
|
---|
| 79 |
|
---|
| 80 | <ul>
|
---|
| 81 | <li>If no ancestor of yours implements clone(),
|
---|
| 82 | and you have no need to do clone deeply,
|
---|
| 83 | and you are abstract, then you should not declare clone().
|
---|
| 84 |
|
---|
| 85 | <li>If no ancestor of yours implements clone(),
|
---|
| 86 | and you have no need to do clone deeply,
|
---|
| 87 | and you are <b>not</b> abstract, then you should implement
|
---|
| 88 | it as follows:
|
---|
| 89 |
|
---|
| 90 | <p>
|
---|
| 91 | <tt><pre>
|
---|
| 92 | * public Object clone()
|
---|
| 93 | * {
|
---|
| 94 | * try
|
---|
| 95 | * {
|
---|
| 96 | * return super.clone();
|
---|
| 97 | * }
|
---|
| 98 | * catch ((CloneNotSupportedException e)
|
---|
| 99 | * { throw new InternalError(); } // never happens
|
---|
| 100 | * }
|
---|
| 101 | </pre></tt>
|
---|
| 102 |
|
---|
| 103 | <li>If no ancestor of yours implements clone(), but you
|
---|
| 104 | need to deep-clone some things, then you should implement it
|
---|
| 105 | as follows:
|
---|
| 106 |
|
---|
| 107 | <p>
|
---|
| 108 | <tt><pre>
|
---|
| 109 | * public Object clone()
|
---|
| 110 | * {
|
---|
| 111 | * try
|
---|
| 112 | * {
|
---|
| 113 | * MyObject myobj = (MyObject) (super.clone());
|
---|
| 114 | *
|
---|
| 115 | * // put your deep-cloning code here...
|
---|
| 116 | * }
|
---|
| 117 | * catch ((CloneNotSupportedException e)
|
---|
| 118 | * { throw new InternalError(); } // never happens
|
---|
| 119 | * return myobj;
|
---|
| 120 | * }
|
---|
| 121 | </pre></tt>
|
---|
| 122 |
|
---|
| 123 | <li>If an ancestor has implemented clone(), and you also need
|
---|
| 124 | to deep clone some things, then you should implement it as follows:
|
---|
| 125 |
|
---|
| 126 | <p>
|
---|
| 127 | <tt><pre>
|
---|
| 128 | * public Object clone()
|
---|
| 129 | * {
|
---|
| 130 | * MyObject myobj = (MyObject) (super.clone());
|
---|
| 131 | *
|
---|
| 132 | * // put your deep-cloning code here...
|
---|
| 133 | *
|
---|
| 134 | * return myobj;
|
---|
| 135 | * }
|
---|
| 136 | </pre></tt>
|
---|
| 137 | </ul>
|
---|
| 138 | */
|
---|
| 139 |
|
---|
| 140 | public Object clone();
|
---|
| 141 |
|
---|
| 142 | /** Sets up the object by reading it from the parameters stored
|
---|
| 143 | in <i>state</i>, built off of the parameter base <i>base</i>.
|
---|
| 144 | If an ancestor implements this method, be sure to call
|
---|
| 145 | super.setup(state,base); before you do anything else.
|
---|
| 146 |
|
---|
| 147 | <p>For prototypes, setup(...) is typically called once for
|
---|
| 148 | the prototype instance; cloned instances do not receive
|
---|
| 149 | the setup(...) call. setup(...) <i>may</i> be called
|
---|
| 150 | more than once; the only guarantee is that it will get
|
---|
| 151 | called at least once on an instance or some "parent"
|
---|
| 152 | object from which it was ultimately cloned. */
|
---|
| 153 |
|
---|
| 154 | public void setup(final EvolutionState state, final Parameter base);
|
---|
| 155 |
|
---|
| 156 | /** Returns the default base for this prototype.
|
---|
| 157 | This should generally be implemented by building off of the static base()
|
---|
| 158 | method on the DefaultsForm object for the prototype's package. This should
|
---|
| 159 | be callable during setup(...). */
|
---|
| 160 | public Parameter defaultBase();
|
---|
| 161 | }
|
---|
| 162 |
|
---|