Where do character-object interactions live?

I am working on adding selection and interaction to my game. The Selection part (for my player) is not too difficult - I'm using the raycast-from-camera method to click-select. Selectable objects have a Selectable script attached to them so I can tell whether they can be interacted with.

My question is about how people structure their code to manage this interactivity. Different objects have different actions (e.g. pick up, open, press). Different characters may be able to perform different actions. Some actions may have other constraints (e.g. need a specific key or other item).

The selection code will need to combine all of these data to determine the available actions and offer options to the player. When an action is executed, it may need to affect the object (e.g. the door opens), the character, or both (e.g. the character's inventory gets the item, the item's game object is destroyed).

I am wondering if anyone has pointers, suggestions, tutorials, etc. that help keep this manageable since it can easily become a complicated mess... Do you have some kind of separate data structure that defines all possible actions and assigns them to specific items and characters? Subclassed behavior classes that define each possible action? How do you match up the "actions item offers" with the "actions character can perform" and then execute the correct code on each end?

I don't want to keep all of this code in my player-character, because I'd like to use the core functionality for NPCs as well (just add the GUI interface for the player)...

Different characters may be able to perform different actions. Some actions may have other constraints

There are a number of approaches:

One method is double-dispatch http://en.wikipedia.org/wiki/Double_dispatch Using a visitor you can determine the correct set of actions based on the types of the classes.

Another method would be some kind of conditional action, which contains a delegate which evaulates to true if that action is possible. Both objects could add all of the possible actions and then you can draw the actions based on which are possible.

pseudocode:

possibleActions.add(new ConditionalAction( "Look for potion", delegate { return (player.hasPotion == false); } );

I set up my items as prefabs (doors, triggers, health etc) with scripts attached to them so it leaves my main character free from these scripts. The scripts on the prefabs just have colliders on them to check if they are interacted with by anything with the "player" tag and execute and script associated with them if the "player" conditions are met. Ideally, I'd like to set it up with a more sophisticated design pattern, but as it is now, it works just fine like this with minimal clutter.