I have two entities - A and B. A includes a set of Bs. Every time I create a B, I want to make sure I add it to a special instance of A.
Looking at the NSManagedObjectClass reference, it is very clear that I should NOT be overriding the init method. So where is the best place to "catch" the creation of B? The only way I can see is to use validateForInsert, but I'm concerned that that's not really what it's meant for, and thus may cause headaches down the road. Is there a better option?
From the NSManagedObject documentation:
awakeFromInsert
Invoked automatically by the Core Data framework when the receiver is first inserted into a managed object context.
Subclass this method on your entity's class.
Related
I'm trying to follow DDD principles for my current project. Unfortunately I have to use RFCs due to technical constraints, so no OData and no REST. It's quite a long question I hope it's OK to ask this in Stackoverflow.
In any case, I have an entity class WorkOrder with a list of Operation objects.
I have a WorkOrderRepository class with a SAVE method that only receives a WorkOrder object and is able to save everything (header data, address, etc) in one go. No matter if it's creation, update or deleted. The repository hides the BAPI calls from the rest.
Now I want to implement the logic to add/update/remove Operations to the work order object and I'm not sure even if the names I give to the methods are correct. Maybe they should be insert/edit/delete... I'm quite confused with this since in every place I look they use different names.
But the most important are my 2 specific doubts:
Should I have only 1 RFC that receives all the updates to a WorkOrder entity including header, operations? Or should I create 1 RFC per operation that only handles one operation at a time? Bear in mind that the UI mockup expects that the user can add/delete multiple operations before clicking a SAVE button and RFC has implicit commit, and that to my knowledge a DDD entity should be updated always in one call.
Option 1:
FUNCTION ZWORKORDER_HDR_UPD
IMPORTING
VALUE(I_WORKORDER_ID) TYPE AUFNR
VALUE(I_WORKORDER_HDR_CHG) TYPE ZWORKORDER_HDR_CHG
VALUE(I_WORKORDER_HDR_UPD) TYPE ZWORKORDER_HDR_UPD "X structure for the BAPI
VALUE(I_OPERATIONS_CHG) TYPE ZOPERATIONS_CHG
VALUE(I_OPERATIONS_UPD) TYPE ZOPERATIONS_UPD
VALUE(I_OPERATIONS_DEL) TYPE ZOPERATIONS_DEL
EXPORTING
VALUE(E_ERRORS) TYPE BAPIRET2_T.
Option 2
FUNCTION ZWORKORDER_OPERATION_CRT
IMPORTING
VALUE(I_WORKORDER_ID) TYPE AUFNR
VALUE(I_OPERATION) TYPE ZOPERATION_CHG
EXPORTING
VALUE(E_ERRORS) TYPE BAPIRET2_T.
FUNCTION ZWORKORDER_OPERATION_UPD
IMPORTING
VALUE(I_WORKORDER_ID) TYPE AUFNR
VALUE(I_OPERATION_CHG) TYPE ZOPERATION_CHG
VALUE(I_OPERATION_UPD) TYPE ZOPERATION_UPD
EXPORTING
VALUE(E_ERRORS) TYPE BAPIRET2_T.
FUNCTION ZWORKORDER_OPERATION_DEL
IMPORTING
VALUE(I_WORKORDER_ID) TYPE AUFNR
VALUE(I_OPERATION_ID) TYPE ZOPERATION_ID
EXPORTING
VALUE(E_ERRORS) TYPE BAPIRET2_T.
How should my Workorder methods look to handle this? I'm specially confused with the update method, since I'm not sure if I should first get the existing operation and then update it or let the parent class do it. But maybe my approaches are completely wrong from the root.
Option 1:
workorder->add_operation( i_operation ). "Pass flat structure from RFC? Or first create object?
workorder->update_operation( i_operation_chg
i_operation_upd ).
workorder->delete_operation( i_operation_id ).
Option 2:
workorder->add_operation( ).
operation = workorder->get_operation(i_operation_chg->get_id())
operation->update( i_operation_chg
i_operation_upd ).
operation->delete_operation( i_operation_id ).
The simplest solution is always the best (KISS and YAGNI principles). It doesn't really matter if you create 1 or 3 RFC-enabled function module, so if you can achieve your goal with one function module, then do it with one.
I think you need to have two RFC-enabled function modules. One to validate the maintained operations (do the validations as far as possible), but that should not save anything to the database, and another one called after the user clicks the SAVE button, to save the whole "WorkOrder", including the maintained operations (at this time, there will be the complete validation also).
If you don't need to define an "operation" class for something else, right now, then keep it simple, no need to instantiate an object. Note that you may create an "operation" class with private static methods, and being a friend of the "workorder" class (only this class can use the operation class), just to organize better your code.
PS: although I don't know what is "Domain-Driven Design", I don't see how your question is related to it, because it just looks like simple program design.
We also work with DDD, although luckily not with RFCs but instead Gateway/OData. Since REST by defintion is stateless we always commit in our application service layer.
What we do is have three "DDD" entities
app_Service, domain_service, repository (and also some data containers like aggregates), where the app_service in your case would expose the methods create, update and delete, and possibly also validate.
Then I would write four thin RFCs (crud + validate) that basically passes the data to the app service.
As for being able to handle multiple updates in each save, we always model our OData (your RFC) after the UI requirements, then it's the app_service task to make sense of the data from a system point of view.
We make heavy use of Abap Clean Code (it's even part of our ATC check), and they clearly state that you should have seperate methods, which is also OO best practices.
https://github.com/SAP/styleguides/blob/master/clean-abap/CleanABAP.md#split-methods-instead-of-adding-optional-parameters
I've created an NSManagedObject class that matches the corresponding Core Data entity. The class has an initializer so I can pass in property values and assign them.
Once the NSManagedObject class is initialized and ready to be saved to Core Data, how exactly do you save it?
The examples I've seen all start by creating a new class through NSManagedObjectContext. I don't want to go that route since I'm creating the class like any other class.
Is there some way to pass this object to NSManagedObjectContext and call its save() method.
It sounds like you're probably not properly initializing your managed objects. It's not enough to assign property values in an initializer-- you have to use the designated initializer. The examples you've seen all use an NSManagedObjectContext because the designated initializer for a managed object requires one. If you don't provide one, you're not using the designated initializer, and you won't be able to save your objects in Core Data.
This is one of the base requirements of Core Data. You must use managed objects, which must be initialized properly, and doing this requires a context.
You don't save a managed object-- you tell a context to save any changes it knows about, which includes changes to any of its managed objects. You can make that more fine-grained by creating a new context that only knows about one new object. But saving an object on one context doesn't automatically let other contexts know, so you end up adding some complexity to keep changes synced.
Apple's Core Data Programming Guide covers this in detail with sample code.
My question here is if I should place a RowVersion [TimeStamp] property in every
entity in my domain model.
For Example: I have an Order class and an OrderDetails "navigation, reference" property,
should I use a RowVersion property for both entities, or is it enough to the parent object?
These classes are pocos meant to be used with Entity Framework Code First approach.
Thank you.
The answer, as often, is "it depends".
Since it will almost always be possible to have an Order without any OrderDetails, you're right that the parent object should have a RowVersion property.
Is it possible to modify an OrderDetail without also modifying the Order? Should it be?
If it isn't possible and shouldn't be, a RowVersion property at the detail level doesn't add anything. You already catch all possible modifications by checking the Order's RowVersion. In that case, only add the property at the top level, and stop reading here.
Otherwise, if two independent contexts load the same order and details, both modify a different OrderDetail, and both try to save, do you want to treat this as a conflict? In some cases, this makes sense. In other cases, it doesn't. To treat it as a conflict, the simplest solution is to actually mark the Order as modified too if it is unchanged (using ObjectStateEntry.SetModified, not ObjectStateEntry.ChangeState). EF will check and cause an update to the Order's RowVersion property, and complain if anyone else made any modifications.
If you do want to allow two independent contexts to modify two different OrderDetails of the same Order, yes, you need a RowVersion attribute at the detail level.
That said: if you load an Order and its OrderDetails into the same context, modify an OrderDetail, and save your changes, Entity Framework may also check and update the Order's RowVersion, even if you don't actually change the Order, causing bogus concurrency exceptions. This has been labelled a bug, and a hotfix is available, or you can install .NET Framework 4.5 (currently available in release candidate form), which fixes it even if your application uses .NET 4.0.
Well this time the question I have in mind is what should be the necessary level of abstraction required to construct an Aggregate.
e.g.
Order is composed on OrderWorkflowHistory, Comments
Do I go with
Order <>- OrderWorkflowHistory <>- WorkflowActivity
Order <>- CommentHistory <>- Comment
OR
Order <>- WorkflowActivity
Order <>- Comment
Where OrderWorkflowHistory is just an object which will encapsulate all the workflow activities that took place. It maintains a list. Order simply delegates the job of maintaining th list of activities to this object.
CommentHistory is similarly a wrapper around (list) comments appended by users.
When it comes to database, ultimately the Order gets written to ORDER table and the list of workflow activities gets written to WORKFLOW_ACTIVITY table. The OrderWorkflowHistory has no importance when it comes to persistence.
From DDD perspective which would be most optimal. Please share your experiences !!
As you describe it, the containers (OrderWorkflowHistory, CommentHistory) don't seem to encapsulate much behaviour. On that basis I'd vote to omit them and manage the lists directly in Order.
One caveat. You may find increasing amounts of behaviour required of the list (e.g. sophisticated searches). If that occurs it may make sense to introduce one/both containers to encapulate that logic and stop Order becoming bloated.
I'd likely start with the simple solution (no containers) and only introduce them if justified as above. As long as external clients make all calls through Order's interface you can refactor Order internally without impacting the clients.
hth.
This is a good question, how to model and enrich your domain. But sooo hard to answer since it vary so much for different domain.
My experince has been that when I started with DDD I ended up with a lots of repositories and a few Value Objects. I reread some books and looked into several DDD code examples with an open mind (there are so many different ways you can implement DDD. Not all of them suits your current project scenario).
I started to try to have in mind that "more value objects, more value objects, more value objects". Why?
Well Value objects brings less tight dependencies, and more behaviour.
In your example above with one to many (1-n) relationship I have solved 1-n rel. in different ways depending on my use cases uses the domain.
(1)Sometimes I create a wrapper class (like your OrderWorkflowHistory) that is a value object. The whole list of child objects is set when object is created. This scenario is good when you have a set of child objects that must be set during one request. For example a Qeustion Weights on a Questionaire form. Then all questions should get their question weight through a method Questionaire.ApplyTuning(QuestionaireTuning) where QuestionaireTuning is like your OrderWorkflowHistory, a wrapper around a List. This add a lot to the domain:
a) The Questionaire will never get in a invalid state. Once we apply tuning we do it against all questions in questionaire.
b) The QuestionaireTuning can provide good access/search methods to retrieve a weight for a specific question or to calculate average weight score... etc.
(2)Another approach has been to have the 1-n wrapper class not being a Value object. This approach suits more if you want to add a child object now and then. The parent cannot be in a invalid state because of x numbers of child objects. This typical wrapper class has Add(Child...) method and several search/contains/exists/check methods.
(3)The third approach is just having the IList exposed as a readonly collection. You can add some search functionality with Extension methods (new in .Net 3.0) but I think it's a design smell. Better to incapsulate the provided list access methods through a list-wrapper class.
Look at http://dddsamplenet.codeplex.com/ for some example of approach one.
I believe the entire discussion with modeling Value objects, entities and who is responsible for what behaviour is the most centric in DDD. Please share your thoughts around this topic...
This may be a basic question but I am pretty new to DDD.
I have an domain object that we'll call Adjustment which can be processed in bulk from the UI. Before we process the Adjustments, we need to validate the date those adjustments will be applied. My problem is with the location of that IsValidDate() method in my domain object.
Should it be a static method in the Adjustment class?
Should it be part of an AdjustmentService class?
Should I create a AdjustmentsGroup domain object to contain a collection of adjustments and which would also implement IsValidDate?
I would tend to think that the 3rd option is the best one but I have a hard time thinking of a domain term for the group of Adjustment objects. Is it ok to "force" a container type domain object for this type of scenario? Is there a common practice to handle this?
Thank you
Edit: IsValidDate actually contains business logic. This is not just a simple date validation method
I would vote for 2) Make it a DomainService. The code to implement it could be in either a DomainServices class, an AdjustmentServices class, or a ValidateAdjustmentService class, depending on what other services are in the domain model, and what makes the most sense from an organizational perspective.
Another option, (if the rules implemented by this service are business rules) is to implement this as a SPECIFICATION. (Check out pages 224 - 240 in DDD)
If you're doing simple is-this-actually-a-date string validation, the correct place for that method, in my opinion, is inside a Service class, as Charles suggested.
However, if data within the Adjustment or AdjustmentCollection objects can change the date validation logic, e.g. disallowing certain date ranges, the method belongs in that object.
I would favor the 3rd option, but create make a more generic function on Adjustment, like Validate(), which would return a collection of errors/validation faults on itself. That way you can add validation rules at a later time without changing your interface. The Validate() function of AdjustmentsGroup would simply call Validate() on each member in the collection. An equally valid (no pun intended) way would also be to have a separate validator class for the object that contains all validation logic.
Your AdjustmentService would then call Validate() on AdjustmentsGroup before processing the adjustments.