Since there have been some posts about best practices, I thought I'd mention some of my own thinking on this topic. The coding standards are great for some aspects, but they kind of bypass a lot of things.
So, a short brain dump of my own thought processes:
1) Don't repeat code from parent classes, call it directly. For example, look at how most controllers are written - 75%+ of the function needed in a controller is in the JController display method. Rather than copying that code over, most Joomla CMS controller methods consist of the 5-25% of code specific to that method, followed by a call to parent::display(). In most cases, you can either call the parent method before or after your own custom code[depending on what you need to do] rather than cut and pasting code from it and then having to update it whenever the parent code changes!
2) For getting lists of items, build on SmartSearch/finder as a model for your code. Using that means less code repetition as you can use the same listQuery for smartsearch(FinderIndexerAdapter) and for your own code.
In that vein, let's take a look at these methods and how their used for content:
When getting a list of items, it is a limited subset of fields. I for one have a great temptation to keep sticking more fields in the list as I need them - DO NOT DO THIS. Stick to the minimal list:
id, title, alias, summary, body, state, catid, start_date, created_by, created_by_alias, modified, modified_by, params, metakey, metadesc, metadata, language, access, version, ordering, publish_start_date, publish_end_date, type, category, cat_state, and cat_access
Note that this entire query can and is reused for other purposes. For example, in order to get a count of all items, finder will make a copy of this query, then wipe the select statement and replace it with a select count(*). This is a very smart way of doing things because it means you don't have to duplicate your selection criteria in 2 methods and update it in 2 places - you can do it all in one.
Note 2, when you need data outside of this, you can get it in a foreach loop through the query just like finder does. Take a look at the index method for finder, first it gets the list of all items, then it loops through them and adds some additional field data[calling getItem when needed], then it indexes all the items in the list. This sounds wasteful since you could have done it all in one step with the list query, until you start thinking about caching. If you are caching each of these objects, then your lookups only have to run queries for the uncached individual objects - while the database query itself doesn't grow to an uncacheable amount of data.
3) Use libraries but work with Joomla! Joomla components are MVC components - heavy emphasis on the view and model. Models contain all the business logic of getting/saving data - so it makes sense to place models in libraries so that other modules and components can use them. However, Joomla component logic expects to find models in the component directory so now you seem to be stuck with the choice of sticking the models in the component, or doing extra work from other components/modules to reuse code. Not so. You can stick your model with 90% of it's logic in the library folder. In your component folder, you create a CHILD class of your model for the component to use. This allows you to work WITH Joomla! by loading models directly from the expected file structure, yet also allows you to centralize your code.
This is just an ugly mind dump of items, I'll add more as I think of them...or as I realize one of my thoughts is wrongheaded and change it. :-)