In previous entries in the series, we learned the importance of a model and an ubiquitous language. We also understand that our app has to deal with some activity of interest to the user — the domain. A layered architecture is a tool for isolating this domain. This is because there is a world of implementation detail outside the domain. Detail like talking to the system via Intents, writing to a SQL Lite database etc. We don’t want everything crowded together — we would like to see the model as a system in a single glance.
Consider a “god object”…
In part 1 we learned the need for a model. But how do we arrive at a model?
To tackle the complexity at the heart of software, we can’t just sit in a room by ourselves and write code. “Crunching knowledge” means talking to stakeholders and domain experts to distill a model. Evans gives the following example of the following conversation in the context of printed circuit board (PCB) design:
Expert 1: It isn’t enough to say a signal arrives at a ref-des, we have to know the pin.
Developer: Ref-des?
Expert 2: Same thing as a component instance. Ref-des…
We’ve come a long way since we wrote the entire logic for a feature inside a Fragment or Activity. But sometimes it’s hard to navigate the alternative approaches with their repositories, domain objects, DTOs, and use cases. What overarching purpose do they serve? Sometimes our understanding never surpasses the cursory, since sample projects are minimal and the primary sources are written from the point of view of enterprise web developers.
I’ve always wanted to return to the canon for repositories, domain objects and their like to ensure my understanding was correct. Reading Eric Evans’ Domain-Driven Design helped me place these…
You may have noticed that many kotlin-stdlib classes like List
and Sequence
implement a map
function:
Some of the worst software engineering disasters arise from trying to achieve code reuse too soon. What if we tried to share map
? If we did this, we could then write a function that consumed either a Sequence
or a List
:
The classic way of doing this in object-oriented programming would be to extract a common interface or abstract class. But look what happens in the attempt below:
Both implementations of map
now have a return type of Mappable
. If we…
You can call it “beautiful code” when the code also makes it look like the language was made for the problem.
Ward Cunningham
If you have a sound continuous integration practice, your pull requests will be automatically evaluated for test coverage and compliance with code conventions. But it’s your teammates who will evaluate the degree to which the submitted code is high quality through being idiomatic. What does this mean?
If we have DuckDuckGo installed, we can pretend our web searches are terminal scripts:
The Trade Me ecosystem is stateful. Auctions on the site run through a lifecycle where members create, bid, win, and lose. Some of these states are quite difficult to achieve: in our squad, engineers would need to have two separate logged-in instances, the Trade Me web app running on their local machine (Alice), and the Trade Me app running on their phone (Bob). They would then click through multiple forms on the web app just to get the auction to the desired state. All of this just to test one part of the app.
Arrow is an exciting development for Kotlin developers interested in functional programming and, more broadly, pushing the limits of the Kotlin compiler. It was recently lauded in Thoughtworks Tech Radar:
Our initial positive impressions of Arrow were confirmed when using it to build applications that are now in production.
That being said, it’s not an easy framework to learn. There’s a sample Android project by Jorge Castillo, but it can be a bit intimidating. Let’s try and unpack some of the functional programming (FP) goodness in this article.
In FP, we aim for an application constructed with pure functions. …
Recently there’s been a bit of buzz around over-engineering in Android projects. Unfortunately, one person’s mere engineering is another’s over engineering. And vice versa. It’s like we’re trying to strike a median between Fizz Buzz Enterprise Edition and Big Ball of Mud.
For my own side, I want to present an argument for one particular language feature in Kotlin that some consider over-engineering, but I love to see used correctly in Android projects. Think of it as a BuzzFeed article for the enterprise-scale Android engineer: Seven Reasons To Love Interfaces.
In our small tests (unit tests), we examine the dependencies…
Let’s say we need to convert a list of numbers to letters. For 0
, I want A
. For 1
, I want B
and so on. One way to do this is the following:
But we should have been listening to Justin Bieber and the memes:
The map
combinator saves us the hassle of a for
loop and a mutable list:
So we can see that transforming one collection into another with a one-for-one correspondence should be expressed with map
. …
In part 4, we learned how to draw using the broad strokes of property-based testing. At the same time, we made all of our progress in an unusual framework, KotlinTest. Framework fatigue is a problem in the JVM community as it is the JavaScript community:
That being said, it’s a little easier if the framework is scoped as a test dependency. This is because it’s not included in your app’s binary and the dependency space for test is usually less crowded (remember we can scope a dependency to test in Gradle with testImplementation
). …
Android