Yii Framework Forum: What to do when models get too fat? - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

What to do when models get too fat?

#1 User is offline   Sarke 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 83
  • Joined: 25-October 10

Posted 23 October 2017 - 02:45 AM

What's the Yii2 way of keeping models from becoming bloated god-objects? Service components?
0

#2 User is offline   Roberto Braga 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 190
  • Joined: 18-February 13
  • Location:Roma, Italy

Posted 23 October 2017 - 03:07 AM

View PostSarke, on 23 October 2017 - 02:45 AM, said:

What's the Yii2 way of keeping models from becoming bloated god-objects? Service components?


Depends on how it became fat.... It can became fat also for bad coding, like insetting too much logic in it.

Different fat --> different diet

Some example

Lets say I have certain kind of information which, when saved (either insert or update), trigger some sort of recalculation in other table record.
At first step you will be implementing this by using afterSave() model event.

But a certain point you will see that this action start to incorporate too much code as it start to "touch" many different tables.
Then the correct way is to move everything out of the model and manage as global event decoupling the code in several components which handle the updates.

This is just an example.

Another case is when you start to have complex validator. Move them out in separate components especially when these validation rules do not apply often, like only in particular scenario.

As I was saying different fat different diet.
1

#3 User is offline   Sarke 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 83
  • Joined: 25-October 10

Posted 23 October 2017 - 10:24 PM

View PostRoberto Braga, on 23 October 2017 - 03:07 AM, said:

But a certain point you will see that this action start to incorporate too much code as it start to "touch" many different tables.
Then the correct way is to move everything out of the model and manage as global event decoupling the code in several components which handle the updates.


This is a good example, thank you. So your suggested way is to move this logic into events? This is instead of a application component singleton?
0

#4 User is offline   Roberto Braga 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 190
  • Joined: 18-February 13
  • Location:Roma, Italy

Posted 24 October 2017 - 03:46 AM

When you start to overload the afterSave model event and it gets fat you will have this code being loaded and compiled even when you just do a search and its execution is not involved, with obvious repercussion on memory usage.

In my opinion afterSave should be always empty, another example can be beforeSave but I would put code in it only if it affect the record itself.

For validation rules is much better to write an external validator rather than writing 20 line of code inside the model.

If you catch the afterSave events globally you are going to have fewer code in the model, the code involved in aftersave happen just when the event is fired, you improve the readability of the code in the model.

Keeping the code slim, make it more readable and contribute to separate the business logic and the code reusability.
Events is only a way to execute code when a certain event happen, The code to be execute can be a controller, a component, or another model update o even a function
http://www.yiiframew...-event.html#on()-detail

A simple way to manage global event is like the following

class EventsHandler extends Component
{
	public function init() {
    	Event::on(ModelFireEvent::className(), ActiveRecord::EVENT_AFTER_INSERT, ['\components\MyClass', 'methodToExecute']);
	}
}

// and then the method in the external class
	public function methodToExecute($event) {
    	// in $event->sender you have the object (in this case the AR) that fired the event
    	// the rest of my code
	}



In order to register all the events you need to insert the EventsHandler in bootstrap process.
1

#5 User is offline   Sarke 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 83
  • Joined: 25-October 10

Posted 24 October 2017 - 06:52 AM

Thanks Roberto.

I wasn't really asking how to use Events though, but more about if they are the right solution and when to use those say over application components, services, helper classes, etc. Or something. And how should they be organized?
0

#6 User is offline   Roberto Braga 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 190
  • Joined: 18-February 13
  • Location:Roma, Italy

Posted 25 October 2017 - 03:23 AM

View PostSarke, on 24 October 2017 - 06:52 AM, said:

Thanks Roberto.
I wasn't really asking how to use Events though


Sorry I misunderstood your question.

Singleton design path (in few word of poor description) is to create a piece of code accessible everywhere in the app and when you need to be sure that there is only one instance of this class, a queue manager for example.
In yii2 for example db connection, and events are singleton class.

Using event or not depends on what are you doing.

I suggested you to use events, but events is not for everything, depend on what you are decoupling.

When
In general I like to keep code clean, therefore when something became too big I prefer to split it in a separate class, it is up to you to know which is the fat limit you can tolerate.
Surely every time when this piece of code can be reused in other contest
If you make a functionality (I mean a portion of the application like and address book manager) that can be reused in other projects make it as module, you won't regret this when you start a new project.

How
In general (for both module and application) you will have widgets, validator, helpers and component (widget and validator are higer level component)
Usually what you write is in one of those category.
At application level I suggest you to create a folder for each category.
At module level usually is not necessary (most probably you are going to have just one heleper class) but I suggest you to keep the same organization as this would help a new developer to navigate your code.

Hope this answer your question
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users