2
votes

Suppose someone says that you must have these modules in you app,

  1. user can sign in provided if user already sign up
  2. user can send messages
  3. user can sign out

what they mean by module they could say that your application must have these functionality, I understand that A module is a component of your app that you can build, test, or debug independently. Modules contain the source code and resources for your app.

My question is that if they say like this then how can I organize my code in professional way? do I have to make separate package for each of these functionalities? or I have to make separate module for each functionalities, I'm confuse about organization of code

3
Only split your project into modules if you absolutely need to. It might make sense for a giant application like Facebook but for 95% of apps, a single module is just fine and you don't suffer the overhead that multiple modules brings. As for organizing the rest of your code, this is a great article for inspiration -- generally, packaging by feature rather than layer (i.e. login would have a package, messaging would have a package) will make navigating your codebase a lot easier.Eric Bachhuber
So just classes in single package will do this? Or separate packages? The functionality i described in question is just example, where will we going to need packageblackHawk
And what about unit test, how can we orginize our code so it could be unit test easily?blackHawk
I assume that in the requirement must have these modules in you app the term modul just means menu item or user story or feature but not modul as implementation- and code organisation- detail in which lib/jar/dll/android-studi-modul the code has to be compiled into.k3b

3 Answers

1
votes

You need to do three rather simple things. Each of them will need one view, there are two entities (user and message) and there will be some helper class or more of them. This sounds like below 10 classes.

It's like having 10 pieces of paperwork. How many organizers would you buy for 10 sheets of paper? In how many cabinets would you put the organizers?

That's it. KISS. Having everything in a single package is most practical as long as the project is tiny. Writing unit tests helps you to limit the dependencies so that you can split you code into packages or even modules when it grows. Having everything in a single place does not prevent you from testing nor from anything else. It's fine, it just becomes bad when the project grows as there's no visible structure. When this happens, you'll know much better how to do the split.

0
votes

Modularisation describes splitting an application into discrete parts and defining APIs that govern communication between these parts. If all comms between the modules go via these APIs then the modules are termed loosely coupled. This brings benefits such as (briefly) …

  • Ease of change within a module since changes which are internal to one module will not effect any other modules
  • The ability to develop, build and test each module separately
  • … loads more here

Modularisation may involve some or all of the following:

  • Logical separation
  • Physical separation
  • Some kind of modularisation system such as OSGI or whatever Project Jigsaw produces in Java 9

So, that’s the background. In the context of an Android App (which your question tagged) I’d suggest that one module is sufficient and that you should use packaging to define logical separation within that module. You’ll find plenty of descriptions of package by feature and package by layer elsewhere and while it certainly makes sense to read up on these common approaches they are both underpinned by two basic principles:

  • The Common-Reuse Principle: the classes in a package are reused together. If you reuse one of the classes in a package, you reuse them all.
  • The Common-Closure Principle: the classes in a package should be closed together against the same kinds of changes. A change that affects a package affects all the classes in that package and no other packages.

The organisation of your test tree should mirror the organisation of your main tree. If the main packages are well factored then the test packages will be too. Or to put this another way, if you find writing test cases is made more difficult by hacing to depend on classes and packages which seem to be in the wrong place then this is a clear hint that you should reconsider your packaging approach.

As a starting point, you could have a look at existing open source Android apps to see whether there are common patterns emerges. You could also have a look at this answer to a related SO question. But ultimately, you'll understand the specifics of your app best so whilst a well known / widely used structure is a good starting point you may have to change it as your own app evolves and at that stage refactoring tools and test coverage will be be very useful.

0
votes

Module can mean a couple of things, depending on the context. Usually, terminology like this is very fuzzy. In Java/Kotlin, it can be either class or package. In terms of Android, it can be one conceptually (or funcionally) independent component of your application. Moreover, those component typically will reside in separate files (classes) and packages, so there is semantic overlap.

Let's take your example:

  1. Sign in.
  2. Send a message.
  3. Sign out.

On Android, you could model it like so:

app
 ˪ ui
    ˪ SplashActivity
          ˪ SignInFragment
          ˪ SignUpFragment
 ˪ data
    ˪ db
       ˪ DatabaseManager
       ˪ models
           [model classes]
    ˪ api
       [classes responsible for network communication]

Here you have:

  • ui - module/component (and at the same time package) responsible for UI logic.

  • SplashActivity - responsible for managing logic concerning login/signup. Conceptually, we could refer to it as a module too. Physically a class/file.

  • data - big module/component responsible for data manipulation only. Again, at the same time, physically, a package.

  • db - submodule exclusively responsible for Database logic.

And so on. The point I'm trying to drive is: module will serve as an abstraction more often than not.

Regarding unit-tests. Modular design will always make application more testable. In the example above all UI logic is separated from data logic so all data can be very easily mocked. Activity does not care from where data is pulled as long all details are hidden behind suitable interface. This is a bit broad question, so I recommend you Android's guide to application architecture, which is exactly about modular design: https://developer.android.com/topic/libraries/architecture/guide.html

Update

What about MVC?

Android uses derivation of MVC, called Model-View-Presenter. In MVP the presenter assumes the functionality of the "middle-man" (details here). Let's use an example: https://github.com/googlesamples/android-architecture/tree/todo-mvp. This Google's simple to-do app is illustrating MVP design. It's organized as follows:

todoapp
 ˪ data
     ˪ source
     ˪ Task.java (model)
 [...]
 ˪ tasks
    ˪ TasksActivity.java
    ˪ TasksFragment.java
    ˪ TasksPresenter.java
    [...]

As you can see, this layout is very similar to what I presented earlier. Data (Model) logic is kept in separate package and UI logic together (View, Presenter). You could, of course, separate Presenter from View futher, however, this is a very simple application and class separation is enough.

If you have clean separation between components, like in MVP, it's easy to instrument tests for each of them independently - just mock the other components. Again, I recommend reading: https://developer.android.com/topic/libraries/architecture/guide.html, there is a whole section on how to test each component.