summaryrefslogtreecommitdiff
path: root/Business Logic/trunk/src/org/cacert/birdshack/bl/design.html
blob: 16b0b05662fca9f2a93818afc05d222425e33bcf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
<html><head><title>Some design notes</title></head>

<body>

<p>
(@law)
</p>

<p>
I have changed the design or structure somewhat.
model/* is highly similar, api/controller is not.
</p>

<pre>
                                         +-----------------+
                                         | business logic  |
      +---------------+                  |   multi-level   |
      |  net-facing   |         handle() |   handler       |
  --->|  protocol     |----\------------>| - tree          |
      |  handler      |     \            |     |           |     _____
      |          Q    |      \           |     |           |    /     \
      +---------------+    /----\        |   method()- - - |-->|\_____/|
                  ^       /      \       |     |     \- - -|<--|       |
                   \     |  Bird  |      |     /           |   | store |
                    \-----\ - - -/----<--| - -/            |   |       |
                           \----/  ok()  |                 |    \_____/
                                         +-----------------+
                                                   \
                                                    \    _____________
                                                     \--( tailfeather )
                                                         ~~~~~~~~~~~~~
</pre>

<h2> The Handler Calling convention </h2
<p>
The calling into the handling code was done by means of something like:
</p>
<pre>
       Controller.handleRequest(Request, Response);
</pre>
<p>
Now it is by means of:
</p>
<pre>
       Handler.handle(Bird);
</pre>

<p>
A Bird (we can pick another name) is an object (Interface) that knows about the request and the response, and can do that response.  It hides the whole lot.
</p>

<p>
In this model, the single object is passed around from method to method until one method decides to deal with it.  Then, that method does the work, and once done, it calls the result method within the Bird.  Like this:
</p>

<pre>
    void handlerOne(Bird b)
    {
        if (b.isTypeBlue())
            handlerTwo(b);                    // no, not me, find another method
        else {
            String name = b.getName();        // handle some stuff
            String result = doRedCode(name);
            if (null != result)               // deliver the result
                b.ok(result);
            else
                b.fail(404);
        }
        // note, no returns nor exceptions
    }
</pre>

<p>
There are several advantages to this model:
</p>

<ol type="a">
<li>  this sweeps away the assumptions inherent in request-response models.  Now, the various alternatives can be hidden in a Bird derivative. </li>
For servlets, servlet/ServletBird will carry the response within. </li>
<li>  testing code can create a lightweight Bird, and the business logic won't know any different. </li>
<li>  the design does not involve clunky params calling in the forward direction. </li>
<li>  Also, it removes any response load direction on the code in the backwards direction.  It drops the temptation to use Exception handling.  There is no return or exception to send, you have to deliver the result directly into the Bird.  End of story. </li>
</ol>

<p>
(This design evolved in my server code for payments systems when demands were made on it over time to do with messaging flows.)
</p>


<h2> The Handler design </h2>

<p>
The Handler's internal design is basically a big multi-layer tree switch
that just selects on various pieces of info until it finds a
method willing to do the job...
It's not elegant or structured, but given the REST design,
it seems difficult to do anything but.
More or less the same as api/Controller was.
</p>

<p>
I could see for example a big table-driven approach.
But that tends to be even less transparent.  Hence, it
opens questions as to security.
</p>

<p>
Quite why the handler wants to be a big object following a Handler interface,
I am not sure.  In my old project it was because there were several
handlers doing different things, and one set of startup code ran
the lot.  So far, I don't see a need for several hendlers in this
project, so maybe the need isn't there.  But it's easier for me
to think this way ;-)
</p>

<h2> The Store Object </h2>

<p>
Each handler needs to be given an object that acts as its store.
</p>
<p>
The benefit is that we can write a lightweight store like UnbackedStore
which will simply hold data for the running of the program.
This allows good automated testing.
</p>
<p>
This could be a bit like a Hibernate interface, in that the object
can be switched under the handler code without any impact.
But I'm not sure here, I've never used Hibernate.
</p>

<h2> The Store API </h2>

<p>
The uncertain part for me today is figuring out the store API.
</p>

<p>
These requirements:
</p>

<ol type="a">
   <li> every entity has its own unique, persistent ID </li>
   <li> every referring entity holds the ID of any interesting entities (my member holds the ID list for all my assurances) </li>
</ol>
<p>
means that the entire database can be modelled as a network or graph.
(We'd need some implementation details:  a starting point, an
object that is simply a list of references, such as "list of all members,"
and perhaps an index list, such as "all certs and their members.")
</p>

<p>
The implication of this is that we can use an object database
that simply does that:  store objects, and get them indexed by ID.
This has quite solid advantages because it
(a) matches the OO style, and
(b) matches the REST style.
And perhaps (c) it is what I did in my last project, and (d) I have
an ODB (object database) that does precisely that.
</p>


<p>
It has the oddity that we can't do selects any more.
Something to think about later.
</p>

<p>
But I'm a bit cautious of going too far along this path.
At the moment I see the trick here
is to design the store API such that it can
reasonably easily handle both models:  OO and SQL.
Right now, store/ResourceInferface looks ODB only.
Also, I'd like to see Hibernate modelled in code,
so I can understand its assumptions.
</p>

<h2> Model </h2>


<p>
The Model is mostly the same.  There are two differences:
</p>

<p>
Firstly, I've changed the Id to be Rid, our own defined object.
I'm pretty convinced we'll need to modify our Id in time...
Currently, it is just "hasAString".
</p>

<h3> Import / Export </h3>

<p>
We need some way to recover and export the objects
into text.  Especially for REST, also for the storage
in various forms (ODB, Tx and error logging),
and for any internal messaging.
Preferably this is the same way for all uses.
If this is possible then the easiest way might
be an interface with input / output in the BirdShackObject.
If not, we need some mess of Factories, one for each layout,
likely.
</p>

<p>
There appear to be these options:
</p>

<ol type="i">
 <li>  XML.  Blech. </li>
 <li>  JSON.  OK. </li>
 <li>  Serialize.  Does not guarantee
robust semantics over time, it's not meant for persistance,
and can break between versions.
It's also not easy to examine and prove, for security reasons.
 </li>
 <li> Externalize.  Not sure? </li>
 <li> Custom. Has a higher load on clients, but ensures better security.  </li>
</ol>

<p>
If we can agree on one method for external transport in REST,
like JSON, then it might be simple.
To that end, I've added an externalise paramater called
prepareForFlight().  (Yes, the name can change.)
Comes with a constructor like Class(String flight);
But this all depends on above,
I've not added any JSON code as yet
(and don't know how..............).
</p>

</body></html>