JHM is right about the reason. John Fultz shows nice versioning and coding style I'm encouraging to use. Yet there is no answer to how to avoid this problem in general and flexible way.

Here is my attempt, I will skip JF enhancement to not complicate things but it can be used with this method too. 

The problem is that whatever symbol name we use it may happen that the collision will occur as soon as our name will already be somewhere on `$ContexPath` (at a time of parsing those two controllers). It would be nice to don't have to come up with unique symbols which are not readable and handy, for every piece of code we write. 

The solution is to ensure that the context in which `update` is parsed will be unique.

We can achieve this sticking to two rules:

- each "modular" gui element should be defined in own "subcontext"

  So e.g. between ``Begin["`inner`"]/End[]``

- `DynamicModule` variables should be typed with a backtick `` `update`` so that we are sure that even when `update` is somewhere in `$ContexPath` "our" `update` will be `` `inner`update``.

Here is a minimal example of such package:


    ClearAll["GUI`*"];
    BeginPackage["GUI`"];
    
      inner; outer;
      update (*it isn't part of the solution, it is here to simulate \
               "update" being on context path*)
    
    Begin["`Private`"];
    
    Begin["`inner`"];
    
      inner[Dynamic[x_, args___]] := 
        DynamicModule[{`update}, Print@{"inner:", SymbolName@`update};
          `update[] := (Print@"inner"; args@1);
          Slider[Dynamic[x, (`update[]; x = #) &]]];
    
    End[];

    Begin["`outer`"];
    
      outer[Dynamic[x_, args___]] := 
        DynamicModule[{`update}, Print@{"outer:", SymbolName@`update};
         `update[] := (Print@"outer"; args@1);
         {inner[Dynamic[x, (`update[]; x = #) &]], Dynamic@x}];
    
    End[];
    
    End[];
    
    EndPackage[];

Now, since we have ``GUI`Private`inner`update`` and ``GUI`Private`outer`update`` there is no collision. Which was achieved with minimal effort and works even when ``GUI`update`` is on `$Path` during parsing.


    x = 1;
    outer[Dynamic@x]

Prints `inner/outer`