You and your team developed a sophisticated App for iOS, but now you want the same on e.g. on Android and the Web. The problem: the project is so big, where should you even start with the implementation? First, implement all the model classes or rather start with the User Interface classes? Who gets assigned to which part of the code?
It requires a lot of brainstorming and planning to come up with a good plan to execute this kind of project. Additionally, this task gets more complicated with the increasing size of the project.
In this article, we present approaches to implementing software projects for a new platform when the code base on a different platform is already (partially) finished. We won’t get into the specifics of how to adapt the design or API interfaces to the new platform. Instead, we present a concept of how to approach the porting of the code in a shared team effort.
Development Approaches: Horizontal vs. Vertical
Before getting into more details, let’s discuss what a project typically consists of. A project is normally a combination of the following layer/modules.
Frontend/Presentation: presentation related problems e.g. user interface components and navigation/routing between them
Business Logic/Core: core functionalities of the project e.g. user management, product management etc.
Backend & Storage: server/local-storage related functionalities e.g. APIs, Databases etc.
In the scope of this article, we separate between three different approaches to implementing software projects: the Vertical Development Approach, the Horizontal Development Approach, and the Mixed Approach (Vertical + Horizontal):
In the following, we introduce the concepts of these approaches and their advantages and disadvantages.
Horizontal Development Approach
In this approach, the project is divided into layers (as listed above) which are implemented in parallel. Each layer is assigned to a specialized team. Development of all the layers starts at the same time.
- Tasks are assigned according to the strengths of the teams which means more efficiency and high quality of work. For example, a core developer does not need to care about the UI and vice versa.
- Team members (e.g. presentation layer team) share the same strengths. Communication becomes much easier.
- There is no presentable version of the project until it is fully complete.
- User tests or integration tests are usually only possible when all layers and therefore all features are implemented. Critical bugs might be discovered too late.
- There is a high probability of duplication of tasks which results in a waste of time. For example, the UI team would need the models for displaying data in the UI etc. but the Business Logic team didn’t implement them yet
Vertical Development Approach
In this approach, the project is divided into features (a small unit of work). Those features are developed one by one. Normally, a feature is developed and tested before moving onto the next one.
- The team can focus on the features most important to the customer.
- Each feature can be tested as soon as it’s finished. Integration tests and user tests, therefore, happen frequently throughout the project. That makes the outcome more predictable.
- Builds can be regularly sent to the customer with every newly implemented feature
- An MVP (Minimum Viable Product) can be developed quickly by implementing only the necessary features. For example, an eCommerce application with the limited ability to search and display products.
- A team member gets to wear many hats and has an opportunity to gain diverse skills.
- Features can rarely be implemented in isolation. They usually require other features to be implemented first. We are therefore forced to mock a lot of code.
- A team member has to wear many hats, this can also be a disadvantage: team members normally require more time to complete a task if they are not a specialist in that field.
Mixed (Vertical-Horizontal) Approach
The Mixed (Vertical-Horizontal) Approach combines both the Vertical and the Horizontal Development Approach. The idea is to divide the project into features (vertical). Then each feature is divided into layers (horizontal) and assigned according to expertise.
- It combines the advantages of the Vertical Development Approach and the Horizontal Development Approach.
- It’s only efficient if the size of the project and therefore the amount of developer justifies such a fine-grained separation.
- The more structural rules you introduce, the harder it will be for the developers to get the job done in a straight-forward manner
We will be using the example of an eCommerce app to explain how to approach porting that project to another platform. Our eCommerce application consists of the following main components:
All of the above modules are higher level abstractions. That means, every model includes all layers (such as presentation, core and web services). Since the backend/data persistence logic is implemented independently on a remote server, we omit it in this example.
Horizontal Development Approach in practice
We now divide the whole eCommerce application into Presentation and Core layers assigning each of the layers to a specialized team. Both of these teams now start in parallel, independent of each other.
So which module to start with first (User, Product, Purchase or Delivery)? One idea is to start with the module having the least amount of dependencies. In our example, User and Product are the modules with no dependencies on other modules. So we’ll start with these modules.
Inside the module, we differentiate between a bottom-up and a top-down class implementation approach. Bottom-up means starting by first implementing the classes which have the least amount of dependencies to other classes. For example, Util-classes usually don’t depend on any other project class. That makes it easy to implement them without mocking dependencies or jumping to other files. Model classes are also quite independent of other packages and classes.
Top-down is the opposite, you start e.g. with the User Interface classes which depend on many other classes. It forces you to mock out a lot of dependencies and your code will often not compile immediately. On the other hand, this approach feels more natural to a lot of people. It automatically forces you to implement every single class of the project.
We personally often use a bottom-up approach. The Core team starts with the Model and Util classes. This allows the Presentation Layer team to make use of these classes as soon as they are available. The Presentation Layer team starts with simple Views which can then be used to form more complex UI components.
The Horizontal Development approach is suitable when:
- there are specialist teams
- the customer does not want regular builds and just cares about the end product.
Vertical Development Approach in practice
In this approach, we first divide the whole application in a set of manageable features:
- P1: Display products
- P2: Sort products
- P3: Filter products
- U1: Login
- U2: Sign up
- PR1: Shopping Cart
- PR2: Purchase process
- D1: Delivery Process
- R1: Refund Process
Together with the customer, we assign priorities to these features. Let’s say the client wants to display some products first. We now go ahead and start implementing the model classes for this feature, following a bottom-up class implementation approach.
Since the features are chosen to be small units of work, optimally only one person works on one feature at a time. In this way, the team can develop multiple features at once without a big communication overhead.
The Vertical Development approach is suitable when:
- there are smaller teams
- the customer is expecting regular builds
- your team does Agile Development and therefore divides its work into manageable User Stories
Mixed (Vertical-Horizontal) Development
Let’s say, we want to implement the feature of displaying products. We first follow a Vertical Development approach to divide the project into features with a respective priority (see above). We then divide the selected feature into layers and assign each layer to a specialized team (member).
The Presentation Layer team now implements all of the Views for displaying products while the Core team writes the logic for filtering and sorting these products.
We’d recommend implementing the classes shared between layers first as it will reduce duplication. Model classes are a good example as they are needed by both the UI and the Core team.
The Mixed Development approach is suitable when:
- there are teams where each team member has a different domain (frontend, backend etc.) of expertise
- the customer is expecting regular builds
Each of these approaches has its Pros & Cons. We found this simplification of dividing approaches into horizontal and vertical useful for planning some of our projects. Yet, of course, this is only one way of looking at the problem. You need to decide what fits your team size and project requirements. Finally, at a certain point, it’s time to stop planning, get going and learn the important lessons for your team on the way. You cannot plan for every single problem in ahead.