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