Bloch's Builder Pattern / Updater I'm creating many builders where I use inheritance.

My resources have many properties and are stored in a Repository.
In rare case I need to update them.
When I update, I need to keep the same objectId (I track update on the repository).

I use the same Builder/Updater as it's easier for my users (there are more than 10 concrete builders).

The code with only one builder (and properties removed): 

     public interface IBuilder&lt;T, P&gt;
        {
            P Build();
            P Update();
        }


    public abstract class BuilderBase&lt;T, P&gt;: IBuilder&lt;T, P&gt; 
        where T : BuilderBase&lt;T, P&gt;
        where P : class, new()
        {
            protected P Result;
            protected P Source;
            protected T This;

            protected BuilderBase()
            {
                Result = new P();
                This = (T) this;
            }

            protected BuilderBase(P source):this()
            {
                Source = source;
            }

            public P Build()
            {
                var result = Result;
                Result = null;
                return result;
            }

            public abstract P Update();
    }


   public abstract class ResourceBuilder&lt;T, P&gt; : BuilderBase&lt;T, P&gt;
        where T : ResourceBuilder&lt;T, P&gt;
        where P : ResourceBase, new()
        {

            protected ResourceBuilder():base(){}

            protected ResourceBuilder(P resource):base(resource)
            {
                Result.Name = Source.Name;
            }

            public new P Build()
            {
                var result = Result;
                return base.Build();
            }

            public override P Update()
            {
                if (Source != null)
                    Result.ResourceId = Source.ResourceId; 
                return Build();
            }

            public T Name(string name)
            {
                Result.Name = name;
                return This;
            }

        }


    public abstract class ColorResourceBuilder&lt;T, P&gt; : ResourceBuilder&lt;T, P&gt;
           where T : ColorResourceBuilder&lt;T, P&gt;
           where P : ColorResource, new()
    {

        public T Color(Color color)
        {
            Result.Color = color;
            return This;
        }

        protected ColorResourceBuilder(P colorResource) : base(colorResource)
        {
            Result.Color = Source.Color;
        }

        protected ColorResourceBuilder() : base()
        {
        }
    }


       public class ColorResourceBuilder : ColorResourceBuilder&lt;ColorResourceBuilder, ColorResource&gt; {
        public ColorResourceBuilder(ColorResource colorResource) : base(colorResource)
        {
        }

        public ColorResourceBuilder()
        {
        }
    }


The main problem with this approach is for the Update():

var colorResource2 = new ColorResourceBuilder(colorResource1).Name("Blue").Update();


colorResource2 != colorResource1  => two different object have the same Id...

hypothetical improvement:

var colorResource2 = new ColorResourceBuilder(ref colorResource1).Name("Blue").Update();
var colorResource2 = new ColorResourceBuilder(ref colorResource1).Name("Blue").Build();


It could be OK for the Update(). But weird with Build() as ref suggest update.

Another hypothetical improvement:

var colorResource2 = new ColorResourceBuilder().Name("Blue").Update(ref colorResource1);
var colorResource2 = new ColorResourceBuilder(colorResource1).Name("Blue").Build();


Will incur another usage inconsistency problem.

I'm looking for any advice to make it more clean and natural. Or any other pattern which could do the job.
Comment on the builder pattern

I don't think that Joshua Bloch discovered any new version of the builder pattern. I suggest to follow the standard way and purposes from the GoF.

The purposes of the builder pattern are:


avoid having a lot of constructor parameters
provide a default and preserve consistency to be able to ALWAYS build an object
make the code fluently readable


I think here the pattern is not appropriate and not implemented in the way it should be. The Update()-method for example has nothing to do with any builder pattern.

A guess on the intention

As you mentioned a "repository" you are dealing with some kind of persistence context. In your implementation the build()-method will create a new object in the repository and the update()-method wil update an existing object in the repository so far I understand.

Proposal, creation and result

The design I would follow is a natural approach. 

If you want to create a new resource then you create a proposal object that contains data that may be considered during a creation process. The proposal object itself may have been constructed by a builder pattern. That depends on the purposes mentioned in the first place.

After that the proposal object is passed into the creation process. It will be validated and checked against internal system consistency. The creator object is well defined as the responsible for the creation of the wished object (SRP).

If no validation errors occured and it is not violating the systems consistency the object ist created AND persisted. The object may be internally (in the responsible object) constructed through the builder pattern. But that has nothing to do with persistence.

Proposal, update and result

The same with the update. The only difference is that you have an update proposal, an existing object to update and a responsible object that will to the update process.

Now it's getting interesting. The result of the update can be a versioned new object xor a cached old object. This depends on if you want to work with immutability or not. As you have an "id" I suggest to have the objects cached and mutable.

Nevertheless you have to override equals and hashcode in both scenarios. But be careful: two objects of any version are equal if their id is equal.

Conclusion


Do not make the builder pattern return mutable objects, always return new objects. The "builder" pattern is meant to "build" something not to update something
Only build transient, never involve persistence in the builder pattern
Have a proper design for CRUD-Operations for your persistent objects (business objects??) and well defined responsibilities
Distinguish between proposal, creator/updater/deleter and result


I am sorry, this is more a design issue of your problem domain than a pattern issue.