3

I have an app that collects data points throughout the day.

Each data point is stored in a DataPoint object (that is persisted in the DATA_POINTS) table.

I also have a DataPointRepository with basic CRUD operations, but also methods to get average, min & max datapoints.

At the end of each day I want to compress the data in DATA_POINTS to a DataPointsDay entity that only contains the average, max and min values, and then persist it to the DATA_POINTS_DAYS table. (But for the current day I also want to be able to retrieve the DataPointsDay object at any time without persisting it yet)

What is a good way to do this? I initially wanted to pass the DataPointsRepository to the DataPointsDay constructor, but I assume it violates clean architecture since the entity should not know about the repository? Would it make sense to create a DataPointsDayFactory so that I can get the object at any time, and also a CreateDataPointsDayInteractor that creates the DataPointsDay object and then persists it to the database?

5

Your mistake here is that you are incorrectly thinking of DataPoint and DataPointsDay as your business entity, when in fact, they are nothing more than persistence details. I do not know what these points represent, but lets pretend they are temperature of the CPU (I know this is not the case, but you can change out what ever you are representing for this)

class CPUTemp
{
     int Min;
     int Max;
     int Average;
     string Unit;
}

The CPU Temp is your entity, not the datapoints. Therefore you would have a CPUTempRepostory

Your CPUTempRepo would be responsible for adding new records and the compression (you could argue that compression goes in a separate class, but let's keep things simple)

CPUTempRepository.GetData(DateTime day)

If it was today, the repo would go to the current day and calc the averages, if it was a past day it would go to compressed table and look it up. The rest of your app would not care at all which table it came from.

I hope this will solve your issues without having to pass any repositories to entities, which you should avoid.

DataPoint and DataPointsDay are NOT two seperate entities, or even entities at all, they are just two separate ways of STORING a single entity.

Your code should look something like this:

class CPUTempRepository
{
     public CPUTemp getCPUTemp(Date d)
     {
         myBusinessModels.CPUTemp output = new CPUTemp();
         if (d == today)
         {
             ORM.myMyDb.DataPoint data = ORM.Get(d);
             //do summation/average
             output.setThing(data.getThing());
             //ect
         }
         else
         {
            ORM.myMyDb.DataPointsDay datum = ORM.Get(d);
            output.setThing(datum.getThing());
            //ect
         }
         return output;
     }
}
  • Thank you! This makes sense. I guess where I went wrong was in thinking that each table maps to an entity - I know I required a separate table for the compression of the data into days, and I assumed I required a "Day" entity... – HPage Apr 24 '17 at 18:11
  • Very common mistake, I've made it myself many many times. Avoid the temptation to make your DB schema first. Make you domain layer first, your UI second, and your Repositorys/Schema last, this can be helpful in avoiding this issue. – TheCatWhisperer Apr 24 '17 at 18:50
  • My challenge is that I am working with an ORM in Android, and it does not seem to support multiple tables for a single entity: stackoverflow.com/questions/14273419/… – HPage Apr 24 '17 at 19:00
  • I am going to assume that I need to make a split between what the ORM considers to be an entity, and entities according to my clean architecture implementation. So while I will have two tables, (each represented by a ORM entity), CPUTEMP_SAMPLES and CPUTEMP_DAYS, I will still only have a single CPUTempRepository? – HPage Apr 24 '17 at 19:15
  • 1
    Exactly. This is one reason I hate ORMs, doubly so, those with Entity in the name, it gets you thinking in the wrong way because the naming is confusing. ORMs do not generate entities, they generate data-models. If you must use a ORM, do not use it outside of your repository. You need to have a seperate class you define your self in the business model module instead of trying to mess around w the orm. I will put an edit in the answer – TheCatWhisperer Apr 24 '17 at 20:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.