Epoxy: Clone EpoxyModel with @EpoxyClass annotation

Created on 9 May 2017  路  10Comments  路  Source: airbnb/epoxy

Is there a way to clone an EpoxyModel with generated attributes.

Something like this in PhotoModel.java:

    @Override public Object clone() {
        return new PhotoModel_()
              .id(this.id())
              .title(this.title)
              .imageUrl(this.imageUrl);
    }

Because generated class in PhotoModel_.java calls this, instead of the super.clone() method.

  @Override
  public PhotoModel_ clone() {
    super.clone();
    return this;
  }

Is there a way to not generate overriden function?

help wanted

Most helpful comment

I can look into it after the #198 :)

All 10 comments

The generated model looks at every method in the super class that returns itself and overrides it so that the generated model is returned instead of the super class - this is helpful for chaining methods.

It definitely breaks your use case though, sorry about that. It would actually be pretty to implement clone automatically in the generated model. If that is something you're interested in I could build it. I'm curious what your use case is?

If you want to prevent a generated override method from being created I believe you can just mark your clone method with final

I see now.My use case with the EpoxyController and immutability, sometimes I only need just one or two property to change on the model, so I use clone and set them. The final is totally working solution, and yes an automatic generated clone would be handy. Thanks!

Great. We can add a clone method in the generated model at some point.

Anyone interested in putting up a PR? if not I'll get to it probably within a month.

I can look into it after the #198 :)

Fantastic :)

So I've started to look into it and now I have some doubts. The clone implementation example by @laszlo-galosi is a shallow copy. Could we potentially run into any issues because of it?
Another question is about ids. Should we copy them as well? Might be a big problem if a user forgets to change it.

Great points @geralt-encore , I hadn't thought about that.

I think a deep copy would actually be ok. EpoxyController enforces that models cannot be changed once they are added to the controller. This is based on equals, so all objects in the attribute must not change either.

People could run into problems with the deep copy if they use EpoxyAdapter, or if they turn off the model validation warnings, or if they clone a model before adding it to the controller and then modify an attribute object. I don't think we should worry about those cases. If we wanted to we could either generate two methods (cloneShallow, cloneDeep), or use parameter options in the EpoxyModelClass annotation, to control if the clone is shallow or deep, but I don't think that is worth the effort.

Cloning the id's is interesting. I think you're right that it is dangerous to since a user may forget to change it. I vote for not copying the id to force the user to set the id and avoid accidents. Again, if we wanted to later we could have methods like cloneWithId to be explicit that id is included.

Since there are these subtleties to cloning, maybe we shouldn't include the method by default? Maybe we can only generate it if they mark their abstract base model asimplements Cloneable? And then on the generated method we can include javadoc explaining the deep/shallow details and the id details.

With all the restrictions it looks pretty complex. So many potential problems and edge cases.
Maybe we can just add an option to not override a specific method from the original model if a user doesn't want to do it.

good points, I'm fine not supporting clone then since everybody will have different expectations for what it does.

I mentioned above that the solution to not have the generated model override a method is to simply mark it final, so we can leave things as is.

Oh, I missed it somehow. Making method final is a really nice solution.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

atonamy picture atonamy  路  4Comments

ailuoyi picture ailuoyi  路  5Comments

Sergiyss picture Sergiyss  路  6Comments

jQrgen picture jQrgen  路  5Comments

AdamMc331 picture AdamMc331  路  6Comments