Skip to content

Commit 6c8f84b

Browse files
authored
Merge pull request #2 from madetech/kotlin-draft
Kotlin draft
2 parents a053b82 + 061ec30 commit 6c8f84b

File tree

8 files changed

+136
-1
lines changed

8 files changed

+136
-1
lines changed

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,18 @@ In Made Tech Flavour Clean Architecture we stick to the name "UseCase"
3131

3232
# Domain
3333

34-
These contain the "Entity" objects
34+
Domain objects are the center of your system.
35+
Their purpose is to model the domain, in the Object-Oriented world.
36+
37+
The challenge is determining what behaviours lie within Domain objects, and what behaviours lie within Use Cases.
38+
39+
A good rule of thumb is that behaviours within Domain objects *must be valid for all Use Cases across the system.*
40+
41+
It is cheaper to specialise Use Cases, resulting in an anemic domain model, then evolve the systems towards generalisations once patterns emerge.
42+
43+
## Alternative names
44+
45+
* Entities
3546

3647
# Gateways
3748

kotlin/Domain.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Domain
2+

kotlin/Gateway.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Gateway
2+
3+
Contains IO adapters (e.g. files, database or API calls)
4+
These construct Domain objects for use by Use Cases, and, save Domain objects given to it

kotlin/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Made Tech Flavour Clean Architecture: Kotlin
2+
3+
Example project: [MLD Klean Architecture (Continuous Feedback)](https://github.com/madetech/dojos/tree/67eb97d93135ae0fc54bada70e2d2656f7873b88/mld-klean-architecture)
4+
5+
## [Testing](../learn/ATDD.md)
6+
### Spek
7+
8+
#### Acceptance Test
9+
An executing [example can be found here](https://github.com/madetech/dojos/blob/67eb97d93135ae0fc54bada70e2d2656f7873b88/mld-klean-architecture/src/test/kotlin/io/continuousfeedback/core/test/acceptance/TeamNotificationsSpec.kt).
10+
11+
#### Unit Test
12+
An executing [example can be found here](https://github.com/madetech/dojos/blob/67eb97d93135ae0fc54bada70e2d2656f7873b88/mld-klean-architecture/src/test/kotlin/io/continuousfeedback/core/test/unit/CreateTeamMemberSpec.kt).
13+
14+
15+
## Production Code
16+
17+
Customer code should be housed within a Client package e.g. ```com.acmeindustries.widget```
18+
19+
Non-customer specfic code should be housed within a MadeTech namespace e.g. ```com.madetech.authentication```
20+
21+
* [Use Cases](UseCases.md) use_case/
22+
* [Domain](Domain.md) domain/
23+
* [Gateway](Gateway.md) gateway/

kotlin/Spek.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Spek

kotlin/UseCases.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Use Cases
2+
3+
Use Cases can be both asynchronous and synchronous.
4+
5+
The primary difference is that a synchronous Use Case will return it's result, and an asynchronous Use Case will call a callback with it's result.
6+
7+
It is possible to generalise the boundary interfaces of these two types of Use Cases.
8+
9+
## Asynchronous Example
10+
11+
Asynchronous use cases provide greater control over rendering to the UI. However they add complexities to testing.
12+
13+
An [example generalisation can be found here](https://github.com/madetech/dojos/blob/master/mld-klean-architecture/src/main/kotlin/com/madetech/clean/usecase/AsynchronousUseCase.kt),
14+
with [a derivative here](https://github.com/madetech/dojos/blob/master/mld-klean-architecture/src/main/kotlin/io/continuousfeedback/core/usecase/CreateTeamMember.kt) for a specific use case.
15+
16+
```kotlin
17+
package com.acmeindustries.widget.usecase
18+
19+
interface ViewWidgets {
20+
fun execute(request: Request, presenter: Presenter)
21+
22+
data class Request(...)
23+
interface Presenter {
24+
fun onSuccess()
25+
fun onError()
26+
}
27+
}
28+
```
29+
30+
31+
## Synchronous Example
32+
33+
Synchronous Use Cases provide a simpler interface for testing, but can make representing failure paths and control over the UI harder to maintain.
34+
35+
```kotlin
36+
package com.acmeindustries.widget.usecase
37+
38+
interface ViewWidgetPerFooBarReport {
39+
fun execute(request: Request): Response
40+
41+
data class Request(public val fromDate: String, public val endDate: String)
42+
data class Response(...)
43+
}
44+
```
45+
46+
```kotlin
47+
package com.acmeindustries.widget
48+
49+
import com.acmeindustries.widget.usecase.ViewWidgetPerFooBarReport
50+
import com.acmeindustries.widget.usecase.ViewWidgetPerFooBarReport.*
51+
import com.acmeindustries.widget.domain.Widget
52+
53+
class WidgetPerFooBarReport(val widgetGateway: WidgetGateway) : ViewWidgetPerFooBarReport {
54+
fun execute(request: Request): Response {
55+
val widgets = widgetGateway.all()
56+
//secret sauce here
57+
return Response(...) //return response populated with data
58+
}
59+
}
60+
61+
interface WidgetGateway {
62+
fun all(): List<Widget>
63+
}
64+
```

learn/ATDD.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# ATDD
2+
3+
## Acceptance Testing
4+
5+
The purpose of acceptance testing is to test an entire system via it's boundary only.
6+
It serves as a *stand-in*, and documentation for the implementation of the future UI of your system.
7+
Anything that you are coupled to in your acceptance tests, you are also going to be coupled to in your UI.
8+
9+
This means an acceptance test, cannot depend on the following types of objects:
10+
11+
- Domain objects
12+
- Gateways
13+
14+
It must only depend on the *Boundary* of your system.
15+
16+
**The purpose of acceptance tests** is to measure success towards the goal of meeting the customer's needs, and reduces the
17+
occurrence of gold plating
18+
19+
## Unit Testing
20+
21+
Unit Tests are able to break these rules of acceptance tests.
22+
It is meant to serve as documentation of the behaviour of lower level components.
23+
Since these tests are lower level it is possible to test-drive the system into performing every possible permutation of behaviour under a test situation.
24+
25+
This gives the property of [(semantic stability)](https://www.madetech.com/blog/semantically-stable-test-suites) .
26+

learn/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ In extension to the Agile manifesto, clean architecture's core values and belief
2323
* Any aspect of the codebase should be considered opportunity for refactoring at any time.
2424
* The SOLID and Package principles are core guiding principles used to determine the Clean Architecture paradigm.
2525

26+
## Other guides
27+
28+
* [ATDD](ATDD.md)
29+
2630
## Core Skills
2731

2832
* Able to describe

0 commit comments

Comments
 (0)