|
| 1 | +This is a Kotlin Multiplatform project targeting Android, iOS, Web, Desktop, Server. |
| 2 | + |
| 3 | +Clean architecture overview (MNIST demo) |
| 4 | +- Presentation (UI/ViewModel): Compose screens and view models. UI talks only to use cases, not to model types or storage. |
| 5 | +- Domain (Entities + Use Cases + Ports): |
| 6 | + - Entities: image and model identifiers used by the demo (for example, ModelId). |
| 7 | + - Use cases: LoadModel and ClassifyDigit orchestrate model loading and classification. |
| 8 | + - Ports (interfaces): DigitClassifier, ModelWeightsRepository. |
| 9 | +- Data (Repositories + Data Sources): ModelWeightsRepositoryImpl composes cache and local resource readers to provide model weights. |
| 10 | +- Framework/DI (Platform Adapters): expect/actual ResourceReader and a lightweight ServiceLocator for wiring dependencies. |
| 11 | + |
| 12 | +Simple class diagram (Mermaid) |
| 13 | + |
| 14 | +```mermaid |
| 15 | +classDiagram |
| 16 | + class ServiceLocator |
| 17 | + class ModelId |
| 18 | +
|
| 19 | + class DigitClassifierFactory { |
| 20 | + +create(modelId: ModelId): DigitClassifier |
| 21 | + } |
| 22 | +
|
| 23 | + class DigitClassifier { |
| 24 | + +suspend loadModel(modelId: ModelId) |
| 25 | + +classify(image): Int |
| 26 | + } |
| 27 | +
|
| 28 | + class ModelWeightsRepository { |
| 29 | + +suspend getWeights(modelId: ModelId): ByteArray |
| 30 | + } |
| 31 | +
|
| 32 | + class ModelWeightsRepositoryImpl |
| 33 | + class ModelWeightsCacheDataSource |
| 34 | + class ModelWeightsLocalDataSource |
| 35 | + class ResourceReader { |
| 36 | + +suspend read(path: String): ByteArray? |
| 37 | + } |
| 38 | +
|
| 39 | + class LoadModel |
| 40 | + class ClassifyDigit |
| 41 | +
|
| 42 | + ServiceLocator --> DigitClassifierFactory : provides |
| 43 | + ServiceLocator --> ModelWeightsRepository : provides |
| 44 | + DigitClassifierFactory --> DigitClassifier : creates |
| 45 | +
|
| 46 | + LoadModel --> ModelWeightsRepository : getWeights() |
| 47 | + LoadModel --> DigitClassifier : loadModel() |
| 48 | + ClassifyDigit --> DigitClassifier : classify() |
| 49 | +
|
| 50 | + ModelWeightsRepository <|.. ModelWeightsRepositoryImpl |
| 51 | + ModelWeightsRepositoryImpl --> ModelWeightsCacheDataSource |
| 52 | + ModelWeightsRepositoryImpl --> ModelWeightsLocalDataSource |
| 53 | + ModelWeightsLocalDataSource --> ResourceReader |
| 54 | +``` |
| 55 | + |
| 56 | +Entry points for developers |
| 57 | +- ServiceLocator: central place to wire platform resources and obtain a classifier. |
| 58 | + - Configure once at app startup: ServiceLocator.configure(resourceReader, digitClassifierFactory) |
| 59 | + - Get a classifier by model id: ServiceLocator.provideDigitClassifier(modelId) |
| 60 | +- Use cases: |
| 61 | + - LoadModel(modelWeightsRepository, digitClassifier).invoke(modelId) |
| 62 | + - ClassifyDigit(digitClassifier).invoke(image) |
| 63 | + |
| 64 | +See also |
| 65 | +- PRD-clean.md describes the architecture in detail, design goals, and boundaries between layers. |
| 66 | +- clean-task.md tracks the implementation checklist and testing/migration items. |
| 67 | + |
| 68 | +* `/composeApp` is for code that will be shared across your Compose Multiplatform applications. |
| 69 | + It contains several subfolders: |
| 70 | + - `commonMain` is for code that’s common for all targets. |
| 71 | + - Other folders are for Kotlin code that will be compiled for only the platform indicated in the folder name. |
| 72 | + For example, if you want to use Apple’s CoreCrypto for the iOS part of your Kotlin app, |
| 73 | + `iosMain` would be the right folder for such calls. |
| 74 | + |
| 75 | +* `/iosApp` contains iOS applications. Even if you’re sharing your UI with Compose Multiplatform, |
| 76 | + you need this entry point for your iOS app. This is also where you should add SwiftUI code for your project. |
| 77 | + |
| 78 | +* `/server` is for the Ktor server application. |
| 79 | + |
| 80 | +* `/shared` is for the code that will be shared between all targets in the project. |
| 81 | + The most important subfolder is `commonMain`. If preferred, you can add code to the platform-specific folders here too. |
| 82 | + |
| 83 | + |
| 84 | +Learn more about [Kotlin Multiplatform](https://www.jetbrains.com/help/kotlin-multiplatform-dev/get-started.html), |
| 85 | +[Compose Multiplatform](https://github.com/JetBrains/compose-multiplatform/#compose-multiplatform), |
| 86 | +[Kotlin/Wasm](https://kotl.in/wasm/)… |
| 87 | + |
| 88 | +We would appreciate your feedback on Compose/Web and Kotlin/Wasm in the public Slack channel [#compose-web](https://slack-chats.kotlinlang.org/c/compose-web). |
| 89 | +If you face any issues, please report them on [GitHub](https://github.com/JetBrains/compose-multiplatform/issues). |
| 90 | + |
| 91 | +You can open the web application by running the `:composeApp:wasmJsBrowserDevelopmentRun` Gradle task. |
0 commit comments