Skip to content

Commit 741c3bb

Browse files
committed
Architecture: Addressing Feedback
1 parent 41cf3b9 commit 741c3bb

File tree

1 file changed

+18
-15
lines changed

1 file changed

+18
-15
lines changed

ARCHITECTURE.md

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ WooCommerce iOS's architecture is the result of a **massive team effort** which
55
coding rounds, and most of all: the sum of past experiences on the platform.
66

77
The goal of the current document is to discuss several principles that strongly influenced our current architecture approach, along with providing
8-
details on how each one of the layer works internally.
8+
details on how each one of the layers work internally.
99

1010

1111

@@ -17,7 +17,7 @@ Throughout the entire architecture design process, we've priorized several key c
1717

1818
1. **Do NOT Reinvent the Wheel**
1919

20-
Our main goal is to exploit as much as possible all of the things the platform already offers thru it's SDK,
20+
Our main goal is to exploit as much as possible all of the things the platform already offers through its SDK,
2121
for obvious reasons.
2222

2323
The -non extensive- list of tools we've built upon include: [CoreData, NotificationCenter, KVO]
@@ -42,8 +42,8 @@ Throughout the entire architecture design process, we've priorized several key c
4242

4343
3. **Immutability**
4444

45-
For a wide variety of reasons, we've opted for exposing Mutable Entities **ONLY** to our Service Layer.
46-
The main app's ViewControllers can access to [Remote, Cached] Entities only through ReadOnly instances.
45+
For a wide variety of reasons, we've opted for exposing Mutable Entities **ONLY** to our Service Layer (Yosemite.framework).
46+
The main app's ViewControllers can gain access to [Remote, Cached] Entities only through ReadOnly instances.
4747

4848
(A) Thread Safe: We're shielded from known CoreData Threading nightmares
4949
(B) A valid object will always remain valid. This is not entirely true with plain NSManagedObjects!
@@ -73,14 +73,14 @@ replace CoreData with any other database. Key notes:
7373
1. **CoreDataManager**
7474

7575
In charge of bootstrapping the entire CoreData stack: contains a NSPersistentContainer instance, and
76-
is responsible for loading both, the Data Model and the actual `.sqlite` file.
76+
is responsible for loading both the Data Model and the actual `.sqlite` file.
7777

7878
2. **StorageManagerType**
7979

8080
Defines the public API that's expected to be conformed by any actual implementation that intends to contain
8181
and grant access to StorageType instances.
8282
83-
**Conformed by CoreDatManager.**
83+
**Conformed by CoreDataManager.**
8484

8585
3. **StorageType**
8686

@@ -181,7 +181,7 @@ of performing this task for us:
181181
Related Endpoints are expected to be accessible by means of a concrete `Remote` implementation. The `Remote` base class offers few
182182
convenience methods for enqueuing requests and parsing responses in a standard and cohesive way `(Mappers)`.
183183

184-
`Remote(s)` receive a Network concrete instance via it's initializer. This allows us to Unit Test it's behavior, by means of the `MockupNetwork`
184+
`Remote(s)` receive a Network concrete instance via its initializer. This allows us to Unit Test it's behavior, by means of the `MockupNetwork`
185185
tool, which was designed to simulate Backend Responses.
186186

187187

@@ -196,7 +196,7 @@ Storage layers.
196196

197197
### Main Concepts
198198

199-
We've borrowed several concepts from the [WordPress's FluxC library](https://github.com/wordpress-mobile/WordPress-FluxC-Android), and tailored them down
199+
We've borrowed several concepts from the [WordPress FluxC library](https://github.com/wordpress-mobile/WordPress-FluxC-Android), and tailored them down
200200
for the iOS platform (and our specific requirements):
201201

202202

@@ -207,6 +207,9 @@ for the iOS platform (and our specific requirements):
207207

208208
*Allowed* to have a Closure Callback to indicate Success / Failure scenarios.
209209
210+
**NOTE:** Success callbacks can return data, but the "preferred" mechanism is via the EntityListener or
211+
ResultsController tools.
212+
210213
2. **Stores**
211214

212215
Stores offer sets of related API's that allow you to perform related tasks. Typically each Model Entity will have an
@@ -247,15 +250,15 @@ for the iOS platform (and our specific requirements):
247250
SomeAction >> Dispatcher >> SomeStore
248251
249252
A. [Main App] SomeAction is built and enqueued in the main dispatcher
250-
B. [Yosemite] The dispatcher looks up for processors that support SomeAction.Type
253+
B. [Yosemite] The dispatcher looks up for the processor that support SomeAction.Type, and relays the Action.
251254
C. [Yosemite] SomeStore receives the action, and performs a task
252255
D. [Yosemite] Upon completion, SomeStore *may* (or may not) run the Action's callback (if any).
253256

254257
2. Observing a Collection of Entities
255258

256259
ResultsController >> Observer
257260

258-
A. [Main App] An observer (typically a ViewController) initializes a ResultsController, and subscribes to it's callbacks
261+
A. [Main App] An observer (typically a ViewController) initializes a ResultsController, and subscribes to its callbacks
259262
B. [Yosemite] ResultsController listens to Storage Layer changes that match the target criteria (Entity / Predicate)
260263
C. [Yosemite] Whenever there are changes, the observer gets notified
261264
D. [Yosemite] ResultsController *grants ReadOnly Access* to the stored entities
@@ -276,7 +279,7 @@ It's important to note that in the proposed architecture Model Entities must be
276279

277280
A. **Storage.framework**
278281

279-
New entities are defined in the CoreData Model, and it's code is generated thru the Model Editor.
282+
New entities are defined in the CoreData Model, and its code is generated thru the Model Editor.
280283
281284
B. **Networking.framework**
282285

@@ -288,7 +291,7 @@ In order to avoid code duplication we've taken a few shortcuts:
288291
This allows us to avoid the need for importing `Networking` in the main app, and also lets us avoid reimplementing, yet again,
289292
the same entities that have been defined twice.
290293

291-
* Since ResultsController uses internally a FRC, the Storage.Model *TYPE* is required for it's initialization.
294+
* Since ResultsController uses internally a FRC, the Storage.Model *TYPE* is required for its initialization.
292295
We may revisit and fix this shortcoming in upcoming iterations.
293296

294297
As a workaround to prevent the need for `import Storage` statements, all of the Storage.Entities that are used in
@@ -304,13 +307,13 @@ into a ReadOnly instance:
304307

305308
* **ReadOnlyConvertible**
306309

307-
Protocol conformed by all of the Storage.Entities, allows us to obtain a ReadOnly Type matching the Receiver's Payload.
308-
Additionally, this protocol define an API to update the receiver's fields, given a ReadOnly instance (potentially a Backend
310+
Protocol implemented by all of the Storage.Entities, allows us to obtain a ReadOnly Type matching the Receiver's Payload.
311+
Additionally, this protocol defines an API to update the receiver's fields, given a ReadOnly instance (potentially a Backend
309312
response we've received from the Networking layer)
310313

311314
* **ReadOnlyType**
312315

313-
Protocol conformed by *STRONG* Storage.Entities. Allows us to determine if a ReadOnly type represents a given Mutable instance.
316+
Protocol implemented by *STRONG* Storage.Entities. Allows us to determine if a ReadOnly type represents a given Mutable instance.
314317
Few notes that led us to this approach:
315318

316319
A. Why is it only supported by *Strong* stored types?: because in order to determine if A represents B, a

0 commit comments

Comments
 (0)