Skip to content

Commit 7326b2b

Browse files
authored
Merge pull request #502 from zancas/feature.doc_design_patterns_501
Add list of design patterns to README.rst
2 parents bbaea5b + b70cfbb commit 7326b2b

1 file changed

Lines changed: 70 additions & 0 deletions

File tree

README.rst

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,76 @@ Usage
5555
pool_b = mgmt.tm.ltm.pools.pool.load(name='mypool', partition='Common')
5656
pool_b.delete()
5757
58+
Design Patterns
59+
~~~~~~~~~~~~~~~
60+
61+
I intend the SDK to be easy to use and easy to hack. These overarching goals
62+
have a strong influence on my thinking when I am reviewing contributions, this
63+
means it is in their own interest that I make them as explicit as possible!
64+
65+
The original interface specification was given to me by Shawn Wormke, who I
66+
believe was influenced by the Jira and Django projects. At the time I was
67+
reading Brett Slatkin's 'Effective Python', and I tried to follow its advice
68+
where possible.
69+
70+
List of Patterns For Contributing Developers
71+
--------------------------------------------
72+
73+
#. Hack this list to make it more correct/complete
74+
For list additions assign @zancas as the PR reviewer.
75+
#. The call operator ``()`` means: "Try to communicate with the device."
76+
This is a strong contract we offer the consumer of the SDK. If an SDK
77+
function is invoked with the call operator ``()`` the program is initiating
78+
a communication with the device. That communication may fail before
79+
reaching the wire, but it has nonetheless been initiated. Conversely, if
80+
an SDK user evaluates an SDK expression that *DOES NOT* invoke the ``()``
81+
call operator, then the SDK does *NOT* initiate a communication with the
82+
device. Any extension to the SDK that is not consistent with this contract
83+
is unlikely to be incorporated into the supported repository.
84+
#. The SDK is stupid
85+
The SDK doesn't decide things for the consumer, it's
86+
simply an interface so that Python programs can manipulate device resources
87+
without implementing custom URI/HTTP/network logic. Implications:
88+
89+
#. NO DEFAULTS
90+
The consumers of this library are themselves Python
91+
programs. The Application programmer must say what they mean in their
92+
SDK-using program. It violates a critical separation of concerns to add
93+
default values to the SDK. Don't do it! (Unless you have a good
94+
reason.)
95+
#. Failures generate exceptions
96+
If the SDK enters a surprising or
97+
unexpected state it raises an exception. That's it. It's not generally
98+
up to the SDK to implement decision logic that handles edge-cases..
99+
EXCEPT where the SDK is smoothing known issues in the device REST
100+
server. (See below.)
101+
#. The SDK never interprets responses
102+
It just records whatever response
103+
the device returns as attributes of the relevant object. (Except where
104+
handling significant inconsistencies in the device interface.)
105+
106+
#. public-nonpublic pairs
107+
e.g. 'create' and '_create' XXX add content here.
108+
#. Handle known issues in the device REST server.
109+
The SDK intends to provide
110+
a rational interface to consumers that does the right thing. This means
111+
that one case where it does NOT simply do the stupid thing is when it
112+
handles a known idiosyncrasy in the device REST server. For example, some?
113+
resources ignore 'disable' and 'enable' configuration options when they are
114+
set to 'False'. Rather than force a consumer to learn about this quirk in
115+
the server, the SDK guesses that '"disable": False' means '"enable": True'
116+
, and submits that value on the consumers behalf.
117+
#. Implement-Reimplement-Abstract
118+
Solve the problem concretely and simply, if
119+
the same problem arises again, solve it concretely, then take the two
120+
concrete solutions and use them as your specification to generate an
121+
abstraction. In the SDK this usually goes something like this:
122+
123+
#. Add logic to a concrete subclass
124+
#. Add similar logic to another concrete subclass
125+
#. Create a new method in a mixin or Abstract 'resource.py' base class and
126+
have both concrete subclasses inherit and use that method.
127+
58128

59129
Submodules
60130
~~~~~~~~~~

0 commit comments

Comments
 (0)