Typically I will use views where possible to encapsulate low-level logic and conforming. If a parameterized view (i.e. an inline table-valued function) will allow you to enforce certain parameters being supplied, I would use that. If a multi-statement action needs to be performed, at that point I would use a stored procedure.
The benefits of views and inline table valued functions is that the optimizer can manipulate them a lot more easily (views can be combined in building the execution plan), and views and ITVFs can be used just like tables and joined to other tables, views or ITVFs with effectively little or no overhead compared to repeating the code inline.
For instance, the code in ChaosPandion's answer can be encapsulated in an ITVF taking a parameter (a great way to ensure that certain parameters are ALWAYS supplied - there is no way in a view to ensure that filter criteria are going to be supplied in the outer SELECT) or in a view (and the parameter will need to be supplied outside the view). The execution plan in both cases will actually be equivalent, because the optimizer can handle cases like this very well.
Stored procedure result sets cannot be joined without putting the data into a temporary table first.
CREATE VIEW TableWithDefault
AS
Select Table.Id, Coalesce(OtherTable.Field, 'Default Value') As Value
From Table
Left Join OtherTable On Table.OtherTableId = OtherTable.Id
-- Usage: SELECT * FROM TableWithDefault WHERE Id = @Id
CREATE FUNCTION TableWithDefault(@Id int)
RETURNS TABLE
RETURN (
Select Coalesce(OtherTable.Field, 'Default Value') As Value
From Table
Left Join OtherTable On Table.OtherTableId = OtherTable.Id
Where Table.Id = @Id
)
-- Usage: SELECT * FROM TableWithDefault(@Id)
Now the benefits of this is that this logic can be called from various stored procedures, views (OUTER APPLY, CROSS APPLY) etc. and the logic is always in one place.