It depend what you mean by “extend”.
If you want to change core EE functionality, then you have only two options - to hack the core code (bad idea) or to use the available extension hooks.
However, if you want to create some new functionality, then you can do anything you like by creating a module. These are essentially CI packages including libraries, views and models. The controller concept is not really present as EE is the controller, but you can use your own techniques to route code once it reaches your module.
You can use modules to create complex interfaces in the CMS and any kind of web app imaginable in the front end. For the latter the entry point would be a custom tag inside an EE template.