We're looking for a way to document Core Data entities. So far the only real options I've come up with are:
Document externally using UML or some other standard
Create NSManagedObject subclasses for every entity and use code comments
Use the User Info dictionary to create a key value pair that holds a string comment
Option 1 feels like too much extra work and something that will almost certainly be out of date 99% of the time.
Option 2 feels natural and more correct than option 1. The biggest con here is that those comments could potentially be lost if this model class is regenerated using Xcode.
Option 3 feels a little less correct than option 2, but has the added advantage of adding automation possibilities with regards to meta data extraction. For instance, in one of our apps we need to keep a real close eye on what we're storing locally on the device as well as syncing to iCloud. Using the user info dictionary it's pretty easy to automate the creation of some form of artefact which can be checked both internally and externally (by the client) for compliance
So my question is whether it would be inappropriate to use the user info dictionary for this purpose? And are there any other options I'm missing?
Option 2 is what I use every time. If you look at your core data model (something.xcdatamodeld or something.xcdatamodel) you will see something like the picture below.
You can tie your entity to whatever class you want and then put the comments in there. It helps if you keep your entity name the same as your class name to make it obvious what you've done.
Additionally this also gives you the ability to add automation. You can do this by creating custom getters and setters (accessor methods) and a custom description method.
I use option 2 and categories. I'll let XCode generate the NSManagedObject subclasses and use a categorie on each of these subclasses. With the categories I do not loose my changes made in the categories, can document, make custom getter and setters and I am still able to use generated subclasses.
If we speak only about documenting (i.e. writing more or less large amounts of text which is intended to be read by humans) your classes, I'd use the option 2.
If you are concerned with the possibility of Xcode overwriting your classes in the option 2, you may consider creating two classes for each entity: one which is generated by Xcode and always could be replaced (you generally do not touch this file) and one other which inherits from the generated one and in which you put all your customizations and comments.
This two-class approach is proposed by the mogenerator.
Although if you need to store some metadata with the entities which will be processed programmatically, the userInfo is perfectly suitable for this.
Related
I have developed a system where various classes have attributes consisting of a custom formula. The formula can contain special tokens which refer to different types of object. For example an object of class FruitSalad may have the following attribute;
$contents = "[A12] + [B76]";
In somewhat abstract terms, this means "add apple 12 to banana 76". It can also get significantly more complex than that with as many as 15 or 20 references to other objects involved in one formula.
I have a trait which passes formulae such as this and each time it finds a reference to a model (i.e. "[A12]") it gets it from the database with A::find(12) and adds it to an array of component objects which can be used for other processes later on in the request.
So, in essence, it's a relationship. But instead of a pivot table to describe the relationship, there is a formula on the parent model which can include references to child models.
This is all working. Yay! But it's really inefficient because there are so many tiny queries to get single models as formulae are parsed. One request may quite easily result in hundreds of queries. Oops.
I see two potential options;
1. Get all my apples and bananas from the database at the start of the request and get them from an in-memory store instead of from the database when parsing a formula (is this the repository pattern??).
2. Create a custom relation type (something like hasManyFromFormula) which makes eager loading work so that the parsing becomes much simpler because the relevant apples and bananas would already be loaded into the parent model.
Is there a precedent for this? As for why I am doing it like this, it would a bit tough to explain in brief but suffice to say it is to support a highly configurable data retrieval system which supports as-yet unknown input data configurations.
Help!
Thanks,
Geoff
Am not completely sure if it is the best solution, but in the end I created a new directory class for basic components and then set it up in the app service provider as a singleton. The constructor for the directory class loaded all models of several relevant classes and made them available as collections throughout the app.
I have an App using a sql base. I created this base with 1 Entity, 10 Attributes at the begining.
So, now I have to add new attributes. (4 more), so I did the versioning, model ... update.
Then, I changed my App in order to access to my new fields values. But, what I don't understand, is how my App can access to my new field in the updated sqlite data base.
Certainly doing something wrong but honestly don't know.
Whether you're using SQLite or not makes absolutely no difference here. Similarly, if lightweight migration is working (i.e. the store is being opened successfully) then there's really little more to say about that.
Assuming you're using NSManagedObject subclasses then what you've probably not realised is that merely updating your model doesn't update the classes you generated for it. So you need to do that again. It'll add the new properties to the relevant classes.
You could write a quick test using key-value coding to demonstrate that the fields are there — e.g.
NSLog(#"%#", [object valueForKey:#"newProperty"]);
... but you should probably stick to generating new class definitions and using the runtime-synthesised getters and setters that flow from there, as it'll allow the compiler better to verify what you're typing and will lead to more efficient code at runtime.
I think this should be an easy one, but haven't found any clear answer, on what would the best practice be.
In an application, we keep current status of an order (open, canceled, shipped, closed ...).
This variables cannot change without code change, but application should meet the following criteria:
status names should be easily displayed in different languages,
application can search via freetext status names (like googling for "open")
status_id should be available to developer via enum
zero headache when adding new statuses
Possible ways we have tackled this so far:
having DB table status with PK(id, language_id) and a separate enum which represents this statuses in an application.
PROS: 1.,2.,3. work out of the box, CONS: 4. needs to run update script on every client installation, SQL selects can become large and cumbersome, when dealing with a lot of code tables
having just enum:
PROS: 3.,4. CONS: 1.,2. is a total nightmare
having enums, which populate database tables on each start of an application:
PROS: 1.,2.,3.,4. work CONS: some overhead on application start, SQL select can become large and cumbersome, when dealing a lot code tables.
What is the most common way of tackling this problem?
Sounds like you summarized it pretty good yourself, and comparing the pros/cons points towards #3. Just one comment when you implement #3 though:
Use a caching mechanism (even a simple HashMap!) plus adding the option to refresh the cache - will ease your work when you'll want to change values (without the need to restart every time!).
I would, and do, use method 3 because it is the best of the lot. You can use resource files to store the translations in and map the enum values to keys in the resource files. Your database can contain the id of the enum for the status.
1.status names should be easily displayed in different languages,
2.application can search via freetext status names (like googling for "open")
These are interfaces layer's concern, you'd better not mix them in you domain model.
I would setup a mapping between status enum and i18n codes. the mapping could be stored in a file (cached in memory) or hardcoded.
for example: if you use dto or view adatper to render your ui.
public class OrderDetailViewAdapter {
private Order order;
public String getStatus() {
return i18nMapper.to(order.getStatus());//use hardcoded switch case or file impl
}
}
Or you could done this before you populating you dtos.
You could use a similar solution for goal2. When user types text, find corresponding enum from mapping and use enum for search.
Anyway, use db tables the less the better.
Personally, I always use dedicated enum class inside domain. Only responsibility of this class is holding status name (OPEN, CANCELED, SHIPPED, ...). Status name is not visible outside codebase. Also, status could be also stored inside database field as string (varchar or similar).
For the purpose of rendering, depending of number of use cases, sometimes I implement formatting inside formatter (e.g. OrderFormatter::formatStatusName(), OrderFormatter::formatAbbreviatedStatusName(), ...). If formatting is needed often I create dedicated class with all formatting styles needed (OrderStatusFormatter::short(), OrderStatusFormatter::abbriviated()...). Of course, internal mapping is needed to map status name to status title, and this is tricky part. But if you want layering you can't avoid mapping.
Translation is not dealt so far. I translate strings inside templates so formatters are clean of that responsibility. To summarize:
enum inside domain model
formatter inside presentation layer
translation inside template
There is no need to create special table for order status translations. Better choice would be to implement generic translation mechanism, seperated from your business code.
I have this idea of generating an array of user-links that will depend on user-roles.
The user can be a student or an admin.
What I have in mind is use a foreach loop to generate a list of links that is only available for certain users.
My problem is, I created a helper class called Navigation, but I am so certain that I MUST NOT hard-code the links in there, instead I want that helper class to just read an object sent from somewhere, and then will return the desired navigation array to a page.
Follow up questions, where do you think should i keep the links that will only be available for students, for admins. Should i just keep them in a text-file?
or if it is possible to create a controller that passes an array of links, for example
a method in nav_controller class -> studentLinks(){} that will send an array of links to the helper class, the the helper class will then send it to the view..
Sorry if I'm quite crazy at explaining. Do you have any related resources?
From your description it seems that you are building some education-related system. It would make sense to create implementation in such way, that you can later expand the project. Seems reasonable to expect addition of "lectors" as a role later.
Then again .. I am not sure how extensive your knowledge about MVC design pattern is.
That said, in this situation I would consider two ways to solve this:
View requests current user's status from model layer and, based on the response, requests additional data. Then view uses either admin or user templates and creates the response.
You can either hardcode the specific navigation items in the templates, from which you build the response, or the lit of available navigation items can be a part of the additional information that you requested from model layer.
The downside for this method is, that every time you need, when you need to add another group, you will have to rewrite some (if not all) view classes.
Wrap the structures from model layer in a containment object (the basis of implementation available in this post), which would let you restrict, what data is returned.
When using this approach, the views aways request all the available information from model layer, but some of it will return null, in which case the template would not be applied. To implement this, the list of available navigation items would have to be provided by model layer.
P.S. As you might have noticed from this description, view is not a template and model is not a class.
It really depends on what you're already using and the scale of your project. If you're using a db - stick it there. If you're using xml/json/yaml/whatever - store it in a file with corresponding format. If you have neither - hardcode it. What I mean - avoid using multiple technologies to store data. Also, if the links won't be updated frequently and the users won't be able to customize them I'd hardcode them. There's no point in creating something very complex for the sake of dynamics if the app will be mostly static.
Note that this question doesn't quite fit in stackoverflow. programmers.stackexchange.com would probably be a better fit
After writing a few lesser programs when learning Java the way I've designed the programs is with Model-View-Control. With using MVC I have a plethora of getter methods in the model for the view to use.
It feels that while I gain on using MVC, for every new value added I have to add two new methods in the model which quickly get all cluttered with getter & setters.
So I was thinking, maybe I should use the notifyObserver method that takes an argument. But wouldn't feel very smart to send every value by itself either so I figured, maybe if I send a kind of container with all the values, preferably only those that actually changed.
What this would accomplish would be that instead of having a whole lot of getter methods I could just have one method in the model which put all relevant values in the container.
Then in the view I would have a method called from the update which extracted the values from the container and assigning them to the correct fields.
I have two questions concerning this.
First: is this actually a viable way to do this. Would you recommend me doing something along these lines?
Secondly: if I do use this plan and I don't want to keep sending fields that didn't actually change. How would I handle that without having to have if statements to check if the value is not null for every single value?
I've more familiar with the MVP paradigm, but hopefully they're similar enough to comment. While getters (and setters) in and of themselves are not necessarily evil, they are sometimes a sign that your subsystems are too strongly coupled. One really great way to decouple this is to use an event bus: see Best practices for architecting GWT apps. This allows the view to just shoot off events for the controller to listen for whenever something important happens, and the view can listen for events whenever something changes in the model that corresponds to updating the view. Ideally you wouldn't even need to ever pass the model to the view, if you can break up any changes into incremental pieces and just tell the view to change this part and then this other part.
If you feel you have too many getters (and setters) in your model class, maybe you have too many fields altogether. Is it possible that there are several distinct classes hiding within your model? If you extract these into separate classes, it may make your model more manageable.
OTOH the associated container you are thinking about could also be viable - but then why duplicate all data? You could instead use the associated container directly in the model to store all properties you can think of. And you can also pass this around for observers to get updates (preferably wrapped into an unmodifiable container, of course) - although in this setup you wouldn't need to.
In general, Java is a verbose language which expects you to put all those getters and setters (and a lot more) in place. However, any decent IDE can generate those for you with a few keypresses. Note also that you need to write them only once, and you will read and call them many many more times. Verbose also means easily readable.
If you have too many getter it's ok. But you shouldn't need the setter. The view is supposed to only read/query the model.
The MVC pattern should promote something that is asymmetric: the control update the model by calling methods in the model that embed the logic and update the sate accordingly; this respects encapsulation. The view reads/queries the model via the getters. This goes a bit against information hiding, but that's how MVC works.
I wouldn't personally pass all information in the events. It sounds complicated to me: either you end up with something that is not statically typed (e.g. you pass hashmaps), or with a plethora of typed events. I would stick with something simple, and have (possibly many) getter in the model.