Note:
Please refer to the App architecture diagram.drawio file if you would like to have a clear sight of the diagram.
Drag and drop the file on the website of the Draw.io.

- Implemented modular system by respecting S.O.L.I.D. principle to create
Item,Order,CoreDataandSharedlayer and composing them inCompositionlayer. There are sublayers in theItemandOrder, includingFeature (business logic),Local,UIandStub. With such clear separation, they can be separated into different modules if needed.
- Includes
商品列表(includes pagination),商品詳情and購物車scenes.
- Includes
確認訂單and歷史訂單紀錄(includes pagination) scenes.
- Acted as an adapter between
CoreDataframework andLocalsublayer ofItemandOrderby implementingLocal-specific abstraction.
- Shared UI components and helpers between
ItemandOrder.
- Acted as all layers' client to initialize all components this application needs.
- Also decorated components differently based on the requirements.
- Defined feature abstraction components instead of concrete types. This way, the system can be more flexible when facing requirements changes by creating different implementations of the abstraction and composing them differently without altering the existed components.
- Also, other sublayers are able to be developed in parallel by following the defined abstraction.
- Implemented MVVM as UI architecture to separate iOS-specific components (import UIKit) from feature logic (platform-agnostic) by using platform-agnostic presentation components (ViewModel). This way, the ViewModel can be reused across platforms if needed.
- Used closure as binding strategy to achieve simplest way of binding.
- Implemented multiple MVVMs in one scene to avoid components holding too many responsibilities (massive view controller).
- Used
Composerto reduce the complexity of creating a scene with multiple MVVMs from clients point of view. - Decoupled UIViewControllers by using closure callback to send UIViewController navigation events to its client intead of creating another UIViewController within an UIViewController.
- Hid the frameworks' details by depending on a local-specific abstraction (invert the dependency). This way, I can easily switch the frameworks based on the needs without altering current system.
- Separated the frameworks' details from business logic also make the framework components easy to test, develop and maintain since it just obeys the command.
- Created local-specific models to decouple
CoreDatasublayer fromFeaturesublayer and other components inLocalsublayer.
- Only for this assignment-specific case. Normally it would be a
APIsublayer and applied the same concept in theLocalsublayer.
- Dispatched the UI-specific results from background queue to main queue by
MainThreadDispatchDecoratorto eliminate duplicate code in UI layer. - Decoupled
OrderfromItemlayer by usingOrderSaverWithCartDeleterDecoratorfor cart deletion after completing the checkout process.
- Decoupled
Localsublayer fromCoreDataby usingCoreDataStore.
- Instead of making the application crash when the creation of CoreData stack failed, used
NullStoreto provide empty implementation.
Xcode 13 or later
iOS 15.0 or later
Swift 5 or later
Wayne Cheng|h88377@gmail.com
JKOAssignment is released under the MIT license.