~ubuntu-branches/ubuntu/trusty/twisted/trusty-proposed

« back to all changes in this revision

Viewing changes to doc/core/howto/design.html

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2014-01-08 00:19:41 UTC
  • mfrom: (1.3.1) (44.2.2 sid)
  • Revision ID: package-import@ubuntu.com-20140108001941-kxhzbyi4a40sc08r
Tags: 13.2.0-1ubuntu1
* Merge with Debian; remaining changes:
  - Keep the preliminary python3 support, but don't enable it.
  - Try to use plain pygtkcompat and fall back to gi.pygtkcompat, to
    avoid a DeprecationWarning, and a crash.
  - Use new io_add_watch api on new versions of pygobject.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html  PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
 
2
  <head>
 
3
<title>Twisted Documentation: Designing Twisted Applications</title>
 
4
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
 
5
  </head>
 
6
 
 
7
  <body bgcolor="white">
 
8
    <h1 class="title">Designing Twisted Applications</h1>
 
9
    <div class="toc"><ol><li><a href="#auto0">Goals</a></li><li><a href="#auto1">Example of a modular design: TwistedQuotes</a></li><ul><li><a href="#auto2">Set up the project directory</a></li><li><a href="#auto3">A Look at the Heart of the Application</a></li></ul></ol></div>
 
10
    <div class="content">
 
11
 
 
12
<span/>
 
13
 
 
14
<h2>Goals<a name="auto0"/></h2>
 
15
 
 
16
<p>This document describes how a good Twisted application is structured. It
 
17
should be useful for beginning Twisted developers who want to structure their
 
18
code in a clean, maintainable way that reflects current best practices.</p>
 
19
 
 
20
<p>Readers will want to be familiar with writing <a href="servers.html" shape="rect">servers</a> and <a href="clients.html" shape="rect">clients</a> using Twisted.</p>
 
21
 
 
22
<h2>Example of a modular design: TwistedQuotes<a name="auto1"/></h2>
 
23
 
 
24
<p><code>TwistedQuotes</code> is a very simple plugin which is a great
 
25
demonstration of
 
26
Twisted's power.  It will export a small kernel of functionality -- Quote of
 
27
the Day -- which can be accessed through every interface that Twisted supports:
 
28
web pages, e-mail, instant messaging, a specific Quote of the Day protocol, and
 
29
more.</p>
 
30
 
 
31
<h3>Set up the project directory<a name="auto2"/></h3>
 
32
 
 
33
<p>See the description of <a href="quotes.html" shape="rect">setting up the TwistedQuotes
 
34
example</a>.</p>
 
35
 
 
36
<h3>A Look at the Heart of the Application<a name="auto3"/></h3>
 
37
 
 
38
<div class="py-listing"><pre><p class="py-linenumber"> 1
 
39
 2
 
40
 3
 
41
 4
 
42
 5
 
43
 6
 
44
 7
 
45
 8
 
46
 9
 
47
10
 
48
11
 
49
12
 
50
13
 
51
14
 
52
15
 
53
16
 
54
17
 
55
18
 
56
19
 
57
20
 
58
21
 
59
22
 
60
23
 
61
24
 
62
25
 
63
26
 
64
27
 
65
28
 
66
29
 
67
30
 
68
31
 
69
32
 
70
33
 
71
34
 
72
35
 
73
36
 
74
37
 
75
38
 
76
39
 
77
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">random</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">choice</span>
 
78
 
 
79
<span class="py-src-keyword">from</span> <span class="py-src-variable">zope</span>.<span class="py-src-variable">interface</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">implements</span>
 
80
 
 
81
<span class="py-src-keyword">from</span> <span class="py-src-variable">TwistedQuotes</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">quoteproto</span>
 
82
 
 
83
 
 
84
 
 
85
<span class="py-src-keyword">class</span> <span class="py-src-identifier">StaticQuoter</span>:
 
86
    <span class="py-src-string">&quot;&quot;&quot;
 
87
    Return a static quote.
 
88
    &quot;&quot;&quot;</span>
 
89
 
 
90
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">quoteproto</span>.<span class="py-src-variable">IQuoter</span>)
 
91
 
 
92
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">quote</span>):
 
93
        <span class="py-src-variable">self</span>.<span class="py-src-variable">quote</span> = <span class="py-src-variable">quote</span>
 
94
 
 
95
 
 
96
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getQuote</span>(<span class="py-src-parameter">self</span>):
 
97
        <span class="py-src-keyword">return</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">quote</span>
 
98
 
 
99
 
 
100
 
 
101
<span class="py-src-keyword">class</span> <span class="py-src-identifier">FortuneQuoter</span>:
 
102
    <span class="py-src-string">&quot;&quot;&quot;
 
103
    Load quotes from a fortune-format file.
 
104
    &quot;&quot;&quot;</span>
 
105
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">quoteproto</span>.<span class="py-src-variable">IQuoter</span>)
 
106
 
 
107
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">filenames</span>):
 
108
        <span class="py-src-variable">self</span>.<span class="py-src-variable">filenames</span> = <span class="py-src-variable">filenames</span>
 
109
 
 
110
 
 
111
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getQuote</span>(<span class="py-src-parameter">self</span>):
 
112
        <span class="py-src-variable">quoteFile</span> = <span class="py-src-variable">file</span>(<span class="py-src-variable">choice</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">filenames</span>))
 
113
        <span class="py-src-variable">quotes</span> = <span class="py-src-variable">quoteFile</span>.<span class="py-src-variable">read</span>().<span class="py-src-variable">split</span>(<span class="py-src-string">'\n%\n'</span>)
 
114
        <span class="py-src-variable">quoteFile</span>.<span class="py-src-variable">close</span>()
 
115
        <span class="py-src-keyword">return</span> <span class="py-src-variable">choice</span>(<span class="py-src-variable">quotes</span>)
 
116
</pre><div class="caption">Twisted Quotes
 
117
Central Abstraction - <a href="listings/TwistedQuotes/quoters.py"><span class="filename">listings/TwistedQuotes/quoters.py</span></a></div></div>
 
118
 
 
119
<p>This code listing shows us what the Twisted Quotes system is all about.  The
 
120
code doesn't have any way of talking to the outside world, but it provides a
 
121
library which is a clear and uncluttered abstraction: <q>give me the quote of
 
122
the day</q>. </p>
 
123
 
 
124
<p>Note that this module does not import any Twisted functionality at all!  The
 
125
reason for doing things this way is integration.  If your <q>business
 
126
objects</q> are not stuck to your user interface, you can make a module that
 
127
can integrate those objects with different protocols, GUIs, and file formats.
 
128
Having such classes provides a way to decouple your components from each other,
 
129
by allowing each to be used independently.</p>
 
130
 
 
131
<p>In this manner, Twisted itself has minimal impact on the logic of your
 
132
program.  Although the Twisted <q>dot products</q> are highly interoperable,
 
133
they
 
134
also follow this approach.  You can use them independently because they are not
 
135
stuck to each other.  They communicate in well-defined ways, and only when that
 
136
communication provides some additional feature.  Thus, you can use <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.html" title="twisted.web">twisted.web</a></code> with <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.enterprise.html" title="twisted.enterprise">twisted.enterprise</a></code>, but neither requires the other, because
 
137
they are integrated around the concept of <a href="defer.html" shape="rect">Deferreds</a>.</p>
 
138
 
 
139
<p>Your Twisted applications should follow this style as much as possible.
 
140
Have (at least) one module which implements your specific functionality,
 
141
independent of any user-interface code.  </p>
 
142
 
 
143
<p>Next, we're going to need to associate this abstract logic with some way of
 
144
displaying it to the user.  We'll do this by writing a Twisted server protocol,
 
145
which will respond to the clients that connect to it by sending a quote to the
 
146
client and then closing the connection.  Note: don't get too focused on the
 
147
details of this -- different ways to interface with the user are 90% of what
 
148
Twisted does, and there are lots of documents describing the different ways to
 
149
do it.</p>
 
150
 
 
151
<div class="py-listing"><pre><p class="py-linenumber"> 1
 
152
 2
 
153
 3
 
154
 4
 
155
 5
 
156
 6
 
157
 7
 
158
 8
 
159
 9
 
160
10
 
161
11
 
162
12
 
163
13
 
164
14
 
165
15
 
166
16
 
167
17
 
168
18
 
169
19
 
170
20
 
171
21
 
172
22
 
173
23
 
174
24
 
175
25
 
176
26
 
177
27
 
178
28
 
179
29
 
180
30
 
181
31
 
182
32
 
183
33
 
184
34
 
185
35
 
186
36
 
187
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">zope</span>.<span class="py-src-variable">interface</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Interface</span>
 
188
 
 
189
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Factory</span>, <span class="py-src-variable">Protocol</span>
 
190
 
 
191
 
 
192
 
 
193
<span class="py-src-keyword">class</span> <span class="py-src-identifier">IQuoter</span>(<span class="py-src-parameter">Interface</span>):
 
194
    <span class="py-src-string">&quot;&quot;&quot;
 
195
    An object that returns quotes.
 
196
    &quot;&quot;&quot;</span>
 
197
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getQuote</span>():
 
198
        <span class="py-src-string">&quot;&quot;&quot;
 
199
        Return a quote.
 
200
        &quot;&quot;&quot;</span>
 
201
 
 
202
 
 
203
 
 
204
<span class="py-src-keyword">class</span> <span class="py-src-identifier">QOTD</span>(<span class="py-src-parameter">Protocol</span>):
 
205
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>(<span class="py-src-parameter">self</span>):
 
206
        <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">write</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">factory</span>.<span class="py-src-variable">quoter</span>.<span class="py-src-variable">getQuote</span>()+<span class="py-src-string">'\r\n'</span>)
 
207
        <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">loseConnection</span>()
 
208
 
 
209
 
 
210
 
 
211
<span class="py-src-keyword">class</span> <span class="py-src-identifier">QOTDFactory</span>(<span class="py-src-parameter">Factory</span>):
 
212
    <span class="py-src-string">&quot;&quot;&quot;
 
213
    A factory for the Quote of the Day protocol.
 
214
 
 
215
    @type quoter: L{IQuoter} provider
 
216
    @ivar quoter: An object which provides L{IQuoter} which will be used by
 
217
        the L{QOTD} protocol to get quotes to emit.
 
218
    &quot;&quot;&quot;</span>
 
219
    <span class="py-src-variable">protocol</span> = <span class="py-src-variable">QOTD</span>
 
220
 
 
221
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">quoter</span>):
 
222
        <span class="py-src-variable">self</span>.<span class="py-src-variable">quoter</span> = <span class="py-src-variable">quoter</span>
 
223
</pre><div class="caption">Twisted
 
224
Quotes Protocol Implementation - <a href="listings/TwistedQuotes/quoteproto.py"><span class="filename">listings/TwistedQuotes/quoteproto.py</span></a></div></div>
 
225
 
 
226
<p>This is a very straightforward <code>Protocol</code> implementation, and the
 
227
pattern described above is repeated here.  The Protocol contains essentially no
 
228
logic of its own, just enough to tie together an object which can generate
 
229
quotes (a <code class="python">Quoter</code>) and an object which can relay
 
230
bytes to a TCP connection (a <code class="python">Transport</code>).  When a
 
231
client connects to this server, a <code class="python">QOTD</code> instance is
 
232
created, and its <code class="python">connectionMade</code> method is called.
 
233
</p>
 
234
 
 
235
<p> The <code class="python">QOTDFactory</code>'s role is to specify to the
 
236
Twisted framework how to create a <code class="python">Protocol</code> instance
 
237
that will handle the connection.  Twisted will not instantiate a <code class="python">QOTDFactory</code>; you will do that yourself later, in a <code class="shell">twistd</code> plug-in.
 
238
</p>
 
239
 
 
240
<p>Note: you can read more specifics of <code class="python">Protocol</code> and <code class="python">Factory</code> in the <a href="servers.html" shape="rect">Writing
 
241
Servers</a> HOWTO.</p>
 
242
 
 
243
<p>Once we have an abstraction -- a <code>Quoter</code> -- and we have a
 
244
mechanism to connect it to the network -- the <code>QOTD</code> protocol -- the
 
245
next thing to do is to put the last link in the chain of functionality between
 
246
abstraction and user.  This last link will allow a user to choose a <code>Quoter</code> and configure the protocol. Writing this configuration is
 
247
covered in the <a href="application.html" shape="rect">Application HOWTO</a>.</p>
 
248
 
 
249
</div>
 
250
 
 
251
    <p><a href="index.html">Index</a></p>
 
252
    <span class="version">Version: 13.2.0</span>
 
253
  </body>
 
254
</html>
 
 
b'\\ No newline at end of file'