I have a data structure which has an add function. When the user instantiates a new data structure object, she can specify an algorithm which will be executed each time the add function is called and alters the newly inserted value based on the previous values in the data structure. The algorithm needs to have access to all the data in the data structure.  Thus the data structure needs to store an algorithm object (since this is called each time the add is executed). On the other hand the algorithm needs access the data structure, and thus needs to store the data structure object. I think situations where class A has an instance of class B and class B has an instance of class A are usually undesirable.Does anybody have an idea how to solve this recurrence here?
OODesign: Data Structure which calls algorithm on insert
design patterns;object oriented;object oriented design
One way to approach this problem without extending the tiers of your system is to implement the Command and Strategy patterns together in your design.  Encapsulate the actionable method (in your case, add) as a Command and decorate it with a Strategy that encapsulates your algorithm. Inside the Execute of your AbstractCommand, execute a virtual OnAfterExecute() method, which is where you state that you want your Algorithm to process. To tie the patterns together, conceptualize the responsibilities of your Context and of your Invoker as being the same.  Untested code. Typed by hand from memory.public interface ICommand{    void OnBeforeExecute();    void OnExecute();    void OnAfterExecute();    void Execute();}public abstract class Command : ICommand{    protected IStrategy Algorithm{ get;set; }    public Command(IStrategy algorithm)    {      this.Algorithm = algorithm;    }    public virtual void OnBeforeExecute(){};    public virtual void OnExecute(){};    public virtual void OnAfterExecute(){};    public virtual void Execute()    {       OnBeforeExecute();       OnExecute();       OnAfterExecute();        };}public class AddCommand : Command{    private IPersistenceService PersistenceService {get;set;}    public AddCommand(IStrategy algorithm, IPersistenceService persistenceService) :base(algorithm)    {       this.PersistenceService = persistenceService;    }    public virtual override OnExecute()    {       this.PersistenceService.ExecuteAddStuffs();    }    public virtual override OnAfterExecute()    {       this.Algorithm.Process();    }}public interface IStrategy{    void Process();}public class HighPassFilterStrategy : IStrategy{    private IPersistenceService PersistenceService { get;set; }    public void Process()    {       //Execute your HighPassFilter logic.    }}//DomainProcess is your InvokerContext//As an alternative design consideration, you could move the virtual 'On' methods//up into DomainProcess and decouple the strategy from the command.public class DomainProcess{    public ICommand Command{ get; protected set;}    public DomainProcess(IStrategy strategy, ICommand command)    {       command.Algorithm = strategy;       this.Command = command;    }    public void Run()    {       Command.Execute();    }}public class YourDataStructure{   public string Foo {get;set;}   public string Bar {get;set;}   //List of DomainProcess. Won't accept angle brackets.   //Listleft angle bracketDomainProcessright angle bracket    private List DomainProcesses { get;set; }    public DataStructure(List workflows)    {       this.DomainProcesses = workflows;       //alternative, but indicative of poor design. **Objects should not       //construct their own dependencies.**       //---------------------------------------------------------        //I'm including this so that I don't have to design all the way up to       //Composition Root for this illustration.       //---------------------------------------------------------       if(!this.DomainProcesses.Any(process => process.Name.Equals(Add))       {          var algorithm = new HighPassFilterStrategy();          var command = new AddCommand();          var add = new DomainProcess(algorithm, command);          this.DomainProcesses.Add(add);       }    }    public void AddRuntimeOperation(string name, ICommand command, IStrategy algorithm)    {       DomainProcess process = new DomainProcess(algorithm, command);       process.Name = name;       DomainProcesses.Add(process);    }    public void Add()    {       var add = this.DomainProcesses.Where(operation => operation.Name.Equals(Add')).SingleOrDefault();       add.Run();    }}Your structure that currently has an Add method on it could instead encapsulate a DomainProcess called Add    public void Add()  {    DomainProcess.Run();  }The OnBeforeExecute, OnExecute and OnAfterExecute methods are colloquially known as aspects.  If you are going to use an object hierarchy in your design, aspects should serve as your primary extension points of that hierarchy.By creating the default implementation of Execute as an aggregation of these 3 aspects, you can very easily specify inside your Algorithms that you want them to be processed Before or After your main operation is executed.  More specific information about your requirements might change the recommendation.