I've been involved in startups since last year and are developing with the Python framework Django. There was a development blank for nearly five years, so I decided opportunistically, "Is this the development of today?" But it was full of anti-patterns and ramblings.
The former former person in charge and the previous person in charge have stopped, and the attachment has been turned around. Looking at the remaining code, I can't help but think about it.
Under such circumstances, I would like to summarize the story of refactoring and the story of refactoring from now on.
It seems like it won't stop when I start talking, but there were two disappointing things from the architectural point of view.
It seems that it was a simple app that the view only fetches the data originally created by batch processing. However, with the addition of functions, various calculations are now performed in the view.
It seems that the previous person tried to do something, but there was logic left in the view or logic in the model. You can create circular references in two different packages. I haven't confirmed the operation. It's been terrible.
I put aside the fact that I didn't have enough time, ~~ the person in charge was stupid ~~, and it depends on the situation and people.
In the first place, Django expects a simple configuration with a 1: 1 table and model. It's a bit off the original meaning, but it's probably the Active Record pattern.
This configuration becomes problematic as the app becomes more complex.
As the functionality becomes more complex, the table changes. It may not match the model you originally expected.
I think Django tends to call the model directly from the view.
When you combine information from multiple tables, you tend to write logic in the view. If you do complicated calculations, it will be difficult to understand where the responsibility lies, asking "What? Is this model in charge?"
Model-View-Controller is a presentation layer pattern in the first place. It seems that the model is mixed with the architectural pattern of the data source, which is confusing. (I think I simply don't understand)
I went back to the basics and started by layering. At that time, I referred to Domain Driven Design and the enterprise architecture pattern (although it has a bad reputation).
Personally, I was sick of the content of the enterprise architecture pattern.
http://www.amazon.co.jp/dp/4798121967 http://www.amazon.co.jp/dp/4798105538
There are some patterns, but it was easy to understand how to divide them into 4 layers.
Again, what made Django personally confusing was that it seemed like the presentation layer model, domain layer, and data layer were all in one. It became a key to divide this area.
Changed to provide one service for one view. I don't like the complexity of the method parameters, so I let them handle the Data Transfer Object-like parameters.
The service is also divided into two types.
One is to handle basic CRUD. The naming convention is also XxxService.
The other is to combine multiple objects to perform complicated calculations and processing. The naming convention is also XxxEngine.
I didn't understand well even if I read various explanations, so I referred to the following code. http://www.infoq.com/jp/news/2015/04/ddd-trading-example https://github.com/archfirst/bullsfirst-server-java
Since it is inefficient to create an instance of the service each time, I made it a Singleton.
http://code.activestate.com/recipes/579090-yet-another-singleton-pattern-in-python-using-clas/
This is an issue for the future.
There were some similar things in XxxEngine. This is a haze that gives you a better view if you separate it with the Strategy pattern.
I decided to think of Django's model as a data layer.
In the future, I am thinking of introducing a domain layer. Implement domain logic in a class that inherits from Django's model.
In the old days, when converting a table to an object, it was mapped to a POJO (Plain Old Java Object). To implement logic as a domain model, a class that inherited POJO was used. With that as a reference, I am thinking of inheriting POMO (my coined word w: Plain Old Model Object) and making it a domain model.
It's still subtle, but the current situation is like this.
When I saw the story of introducing the service layer in Rails, I thought "There are people who think the same thing", so I summarized what I thought / responded to in Django.
However, what I was worried about this time was the problem that was being talked about in the enterprise application pattern. Nowadays, there are many things that the framework hides and is not aware of. But when I was trying to push the boundaries of the framework, I thought it was important to know the basics.