Property definitions reflect the Blender data structures, which are independent from Python. Most importantly, you need properties if you want to get something displayed in the UI. UI elements like sliders etc. are displayed by calling something like:
layout.prop(object,“property_name”)
That’s it - your property now shows up as some widget in the UI, depending on what it is. For this reason, property definitions also let you define a description, value ranges, etc. You don’t deal with instantiating UI widgets and adding event listeners or anything like that. You can generate UI procedurally just from looking at property definitions on types.
Also, data stored in properties is saved in the blend file without any effort on your part. If you want to integrate with animation drivers, you also need to define properties.