Skip to content

hadilq/Mastan

Repository files navigation

Mastan

This is a passive aggressive refactor of Firefly/Ebony. Notice, the refactoring never has a straight path, rather it's a zigzag path that you need to keep the functionality of the app, therefore, each commit in this path must be compilable and the app must works as expected. In this sense, this is a sample for refactoring itself too. In fact, refactoring an already existing project is chosen for this project to show how it should be done, instead of starting a new project, and copy stuff here! Notice for any refactoring you need to understand the old implementation and the new one completely, to be able to make a bridge between them. In this way we can add more value, by building upon previous projects.

Naming

Mastan in Farsi's poems literally means cool crowd, which we take it here, however, it also means drunk people, so who knows! By the way, it's reflected in the icon! Also the rainbow in the icon is referring to diversity of all kind.

  • Gender, including men, women, and the spectrum between.
  • Races, including all spectrum.
  • Believe systems, including all spectrum.
  • You get it, including all kind of spectrum, even it's ends!

Roadmap

  • Modularize.
  • Enforcing flat dependency graph by using DIP. All modules must have Input, Output contracts.
  • Apply Logic Tree Architecture(LTA).
  • It's laggy! Consider using @Stable on the data classess.
  • Handle the errors properly.
  • Complete the features set.
  • Make it multiplatform.

Logic Tree Architect(LTA)

The LTA is already explained in The Molecule Sample to fix the scoping problem of the legacy architect. The idea that the scopes in any app make a tree, where the children of any node has smaller scopes than their parents. Hence, the parent of the parents, which is the root of the tree, is a singleton, which is the longest scope. Notice, by logic we mean Business logic.

On the other hand, Compose is a very awesome tool to build such a tree with scopes. Indeed, those scopes will turn into the already implemented Coroutines' scopes of Composable. We put all the logics into a separated tree from the UI tree, because the UI tree has smaller scopes due to the configuration changes, eg. rotation, where are not suitable for handling the logic behind the screen. Therefore, having an independent tree only to handle the logic is what LTA seeks.

Notice, even that there are other Compose-Driven Architectures, eg. Circuit, getting mature in this time, and the author is the turtle of the Android community, but LTA is still superior, simply because it's not relying on Android components, such as its specific dependency injection frameworks, or even extensive use of Android Activity retain, or rememberSaveable in Circuit. Instead of relying on Android's old and crappy architecture, LTA is saving and loading the state tree, which is generated by the logic tree itself, automatically, in any platform. However, currently the only platform in this repository is Android, mainly because of the legacy code, but if you check the code it's easy to extend it to other platforms.

Here the code after refactoring is not depending on the Dagger, and Anvil, because the no-framework that is used here to handle dependency injection has less boilerplate code and it's much more clear, and also, don't let me start on the build time. Notice here the no-framework dependency injection is working on all platforms, where Dagger and Anvil are restricted to Android. Additionally, be aware that the no-framework is a real dependency injection, not a service locator!

Each module, as an independent part of the code, has two Gradle modules, io, and impl module, as you may expect from the implementation of Dependency Inversion Principle. io stands for the definition of input/output of that independent part of the code, and impl stands for the implementations.

As a side note, in the Curry–Howard correspondence context the impl is the mathematical prove of what's claimed in the io. How cool it's.

The io is where we put the states, events, and also, interfaces, where the impl includes the implementations of those intefaces. In this way, the part of the dependency graph that connects the implementations is a flat tree graph, which will help a lot to reduce the incremental build time, while working on the implementations, where we do most of our developments there. It's the advantage of coding cool!

By the way, if you noticed there are a lot of different kind of tree graphs are mentioned here. My reasoning is that something is comprehensive for human brain, if it has a tree structure. Hope you enjoy having tree graphs around like me.

Contribution

I know you think it's awesome, but what if ...

Create that what if as an issue or a PR for us. Let's build a community around it.

About

A Mastodon Client

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published