The scope of the project I’m working on is being expanded. The application is fairly simple but currently targets a very specific niche. For the immediate future I’ve been asked to fork the project to target a new market and continue developing the two projects in tandem.
Both projects will be functionally similar so there is a very strong incentive to generalize a lot of the guts of the original project. Also I’m certain I’ll be targeting more markets in the near future (the markets are geographic).
The problem is a previous maintainers of the project made a lot of assumptions that tie it to its original market. It’s going to take quite a bit of refactoring to separate the generic from the market specific code.
To make things more complex several suggestions have been tossed around on how to organize the projects for the growing number of markets:
- Each market is a separate project, commonalities between projects are moved to a shared library, projects are deployed independently.
- Expand the existing project to target multiple markets, limiting functionality based on purchased license.
- Create a parent application and redesign projects as plugins, purchased separately
All three suggestions have merit and ideally I would like to structure the codeto be flexible enough that any of these is possible with minor adjustments. Suggestion 3 appears to be the most daunting as it would require building a plugin architecture. The first two suggestions are a bit more plausible.
Are there any good resources available on the pros and cons of these different architectures?
What are the pros and cons on sharing code between projects verses copying and forking?
Forking is usually going to get you a quicker result initially, but almost always going to come around and bite you in maintenance — bug fixes and feature enhancements from one fork get lost in the other forks, and eventually you find yourself throwing out whole forks and having to re-add their features to the “best” fork. Avoid it if you can.
Moving on: all three of your options can work, but they have trade-offs in terms of build complexity, cost of maintenance, deployment, communication overhead and the amount of refactoring you need to do.
1. Each market is a separate project
A good solution if you’re going to be developing simultaneously for multiple markets.
Pros:
Cons:
2. Expand the existing project to target multiple markets
Can be made to work okay for quite a while. If you’re going to be working on releases for one market at a time, with a small team, it might be your best bet.
Pros:
Cons:
3. Create a parent application and redesign projects as plugins
Feels technically sweet, and may allow you to share more code.
Pros:
Cons:
I would guess that (2) is sort of where you find yourself now, apart from the licensing. I think it’s okay to stay there for a little while, but put some effort into moving toward (1) — moving the shared code into a separate project even if it’s all built together, for instance, trying to make sure the dependencies from market code to shared code are all one-way.
Whether you end up at (1) or (3) kind of depends. Mostly it comes down to who’s “in charge” — the shared code, or the market-specific code? The line between a plugin, and a controller class that configures some shared component, can be pretty blurry. My advice would be, let the code tell you what it needs.