The PyQGIS Cookbook explains what files are common in QGIS plugins. As you can see there, you would only need three files to run a minimal plugin:
__init__.py file lets QGIS know the Plugin folder is a Python module. It must contain a
classFactory(iface) function that QGIS uses to initialize your plugin, making use of your main Plugin class, which is in the
metadata.txt is where you specify the metadata of your plugin, i.e., plugin's name, author, license, version, homepage, bugtracker, repository, among others.
mainPlugin.py might be named in other ways. This is the file referenced in
__init__.py and contains the functions you enumerated in your question. I'd say this file is the core of your plugin.
Regarding the QGIS Plugin Builder, I suggest you to read the official documentation to get an idea of how it is structured. I actually prefer not to use such plugin, because it creates lots of stuff you wouldn't like to be aware while you are learning the basics of plugin development.
I recommend you starting from plugins you completely understand. That is, start with a very basic (even the minimal) plugin structure and add complexity only when necessary, and when you master the basics.
On the other hand, I'll tell you what the functions you enumerated are for:
__init__( self, iface )
This is the constructor of your plugin. When QGIS recognizes a folder as a Python plugin, the
__init__() method is executed, and the interface object,
iface, is passed to your plugin, so that it can access QGIS afterwards.
You should use this method to save a reference to
iface (as it will be your entry point to QGIS components) as well as to initialize other variables you will use in other functions of your plugin.
tr( self, message )
This is a Python function to get translations from strings. Of course you'll need to provide translations, but you do that in other Qt files (namely, in .ts files).
In general, you wouldn't need this function unless you're going to support languages other than English. It is definitely not a priority for new PyQGIS developers.
add_action( self )
This is a function I've only seen in plugins generated via QGIS Plugin Builder. It helps you set up your plugin GUI. I personally do not use it in my plugins.
initGui( self )
This is a method to set up your Plugin's GUI within QGIS. Here you specify whether you want a button in the QGIS Plugin's toolbar, a custom toolbar, a button inside an existing QGIS menu, and/or (not recommended) a new custom menu.
This is also a good place to establish SIGNAL/SLOT connections betweeen your plugin buttons (or other controls) and your functions.
unload( self )
This is a method to remove your plugin widgets (buttons, menus, and the like) from QGIS GUI.
This is also a good place to disconnect SIGNALS and SLOTS that you have connected in
initGui( self ).
run( self )
This is the main method of your plugin. Here you put the code that will run when the user clicks on your plugin's button. By and large, you start by getting some data from the current QGIS project and then do some editing, processing, or reporting. It's totally up to you.
If your plugin has a dialog, this is the method where you should open it, so that the user can start interacting with the dialog. The dialog logic is normally handled in other Python files, in order to distribute your code and favor maintenance and encapsulation.
run() is not a good place to set SIGNAL/SLOT connections, because doing so, they will be set every time you open your plugin's dialog, triggering your (SLOT) functions multiple times like in Odd behavior in a QGIS plugin: my function is triggered twice.
Finally, the best way to learn to program QGIS plugins is to read other plugins' source code. Start with simple ones and when you master them, go ahead to more complex ones.
I've created a (very simple) demo plugin to help you understand how QGIS plugins work. You can access it from here. There are installation instructions in the README file. The plugin lets you know, through message boxes, when each function you asked for is executed.