Beans, methods, access and change? What is the recommened practice for handling them (i.e. in ColdFusion)? - oop

I am new to programming (6 weeks now). i am reading a lot of books, sites and blogs right now and i learn something new every day.
Right now i am using coldfusion (job). I have read many of the oop and cf related articles on the web and i am planning to get into mxunit next and after that to look at some frameworks.
One thing bothers me and i am not able to find a satisfactory answer. Beans are sometimes described as DataTransferObjects, they hold Data from one or many sources.
What is the recommended practice to handle this data?
Should i use a separate Object that reads the data, mutates it and than writes it back to the bean, so that the bean is just a storage for data (accessible through getters) or should i implement the methods to manipulate the data in the bean.
I see two options.
1. The bean is only storage, other objects have to do something with its data.
2. The bean is storage and logic, other objects tell it to do something with its data.
The second option seems to me to adhere more to encapsulation while the first seems to be the way that beans are used.
I am sure both options fit someones need and are recommended in a specific context but what is recommended in general, especially when someone does not know enough about the greater application picture and is a beginner?
Example:
I have created a bean that holds an Item from a database with the item id, a name, and an 1d-array. Every array element is a struct that holds a user with its id, its name and its amount of the item. Through a getter i output the data in a table in which i can also change the amount for each user or check a user for deletion from this item.
Where do i put the logic to handle the application users input?
Do i tell the bean to change its array according to the user input?
Or do i create an object that changes the array and writes that new array into the bean?
(All database access (CreateReadUpdateDelete) is handled through a DataAccessObject that gets the bean as an argument. The DAO also contains a gateway method to read more than one record from the database. I use this method to get a table of items, which i can click to create the bean and its data.)

You're observing something known as "anemic domain model". Yes, it's very common, and no, it's not good OO design. Generally, logic should be with the data it operates on.
However, there's also the matter of separation of concerns - you don't want to stuff everything into the domain model. For example, database access is often considered a technically separate layer and not something the domain models themselves should be doing - it seems you already have that separated. What exactly should and should not be part of the domain model depends on the concrete case - good design can't really be expressed in absolute rules.
Another concern is models that get transferred over the network, e.g. between an app server and a web frontend. You want these to contain only the data itself to reduce badnwidth usage and latency. But that doesn't mean they can't contain logic, since methods are not part of the serialized objects. Derived fields and caches are - but they can usually be marked as transient in some way so that they are not transferred.

Your bean should contain both your data and logic.
Data Transfer Objects are used to transfer objects over the network, such as from ColdFusion to a Flex application in the browser. DTOs only contain relevant fields of an object's data.
Where possible you should try to minimise exposing the internal implementation of your bean, (such as the array of user structs) to other objects. To change the array you should just call mutator functions directly on your bean, such as yourBean.addUser(user) which appends the user struct to the internal array.
No need to create a separate DAO with a composed Gateway object for your data access. Just put all of your database access methods (CRUD plus table queries) into a single Gateway object.

Related

What is naming convention for DTOs in a webservice

I'm designing a restful web service and I was wondering what should I name my DTOs. Can I use suffixes like Request and Response for them? for example for addUser service, there will be 2 DTOs named: AddUserRequest and AddUserResponse.
Does your organization already have a schema that describes a canonical user that you pass in? If that's what you're using, of course you would use the name from that schema. Otherwise, describe them just as you would any class or schema element.
Note that since a DTO doesn't contain its own methods, you probably would not give it a name with an action verb.
However, consider calling them AddUserRequest and AddUserResponse, especially if the method requires more info than just your regular user DTO. This fits with the Interface Segregation Principle in that your interface parameters should be specifically tailored to the request itself (it shouldn't require elements that are unrelated to the request; and you shouldn't have function-type parameters that change the request, those should be extracted into their own calls.) The AddUserRequest might then contain an element called User that holds the user-specific data, and another element holding the set of other associated data on the request, perhaps groups or access permissions, that sort of thing.
DTOs (Data Transfer Object) are like POJOs(Plain Old Java Objects). It should only have getters and setters and not any business logic.
From Wikepedia:
A data transfer object is an object that carries data between
processes. The motivation for its use is that communication between
processes is usually done resorting to remote interfaces (e.g., web
services), where each call is an expensive operation. Because the
majority of the cost of each call is related to the round-trip time
between the client and the server, one way of reducing the number of
calls is to use an object (the DTO) that aggregates the data that
would have been transferred by the several calls, but that is served
by one call only.
The difference between data transfer objects and business objects or
data access objects is that a DTO does not have any behavior except
for storage and retrieval of its own data (mutators and accessors).
DTOs are simple objects that should not contain any business logic
that would require testing.
This pattern is often incorrectly used outside of remote interfaces.
This has triggered a response from its author[3] where he reiterates
that the whole purpose of DTOs is to shift data in expensive remote
calls.
So ideally for those actions you should create some helpers or you can add those as controllers.
Since it is a RESTful service, ideally the user addition/creation request should send back 201 created HTTP status code , with userId in location header and no response body. For the request, you could name it like UserDetails or UserData or simply User. Refer https://pontus.ullgren.com/view/Return_Location_header_after_resource_creation

Builtin objects with NHibernate

Does anyone know of a way to mix static object instances with those managed by NHibernate. I have an application where I use the repository pattern to manage db object instances, and those instances have some complex many-many, one-many, and many-one relationships. There are some scenarios where I'd like to have a guaranteed object (like a "User" type instance of "sys_user", for example). The instance must be able to participate in relationships, and I'm willing to have a hardcoded primary key for the few objects I want.
Basically I'm looking for a way to make my repository intermingle statically defined objects into the output, so if I ask for a list of "User"s i get the static "sys_user" plus those defined in the database. Furthermore, I'd like to be able to have that "sys_user" participate in a relationship with DB objects, i.e. - MyClass("db instance").UserProperty == "sys_user" instance, as defined by a fk on the MY_CLASS db table with a special value (say -1)
In essence, this is just a way to avoid an installation time requirement of pre-loading predefined objects that the app expects into the DB, as well as preventing them from being modified after installation. I want to code some logic that relies on special instances being present, and not allow users of the app to inadvertantly break that contract.
this should be exactly the case you describe, no need for repository though, just NHibernate http://fabiomaulo.blogspot.com/2009/08/from-db-to-ram-wellknowinstancetype.html

Entity Framework Code First DTO or Model to the UI?

I am creating a brand new application, including the database, and I'm going to use Entity Framework Code First. This will also use WCF for services which also opens it up for multiple UI's for different devices, as well as making the services API usable from other unknown apps.
I have seen this batted around in several posts here on SO but I don't see direct questions or answers pertaining to Code First, although there are a few mentioning POCOs. I am going to ask the question again so here it goes - do I really need DTOs with Entity Framework Code First or can I use the model as a set of common entities for all boundaries? I am really trying to follow the YAGNI train of thought so while I have a clean sheet of paper I figured that I would get this out of the way first.
Thanks,
Paul Speranza
There is no definite answer to this problem and it is also the reason why you didn't find any.
Are you going to build services providing CRUD operations? It generally means that your services will be able to return, insert, update and delete entities as they are = you will always expose whole entity or single exactly defined serializable part of the entity to all clients. But once you do this it probably worth to check WCF Data Services.
Are you going to expose business facade working with entities? The facade will provide real business methods instead of just CRUD operations. These buisness methods will get some data object and decompose it to multiple entities in wrapped business logic. Here it makes sense to use specific DTO for every operation. DTO will transfer only data needed for the operation and return only date allowed to the client.
Very simple example. Suppose that your entities keep information like LastModifiedBy. This is probably information you want to pass back to the client. In the first scenario you have single serializable set so you will pass it back to the client and client pass it modified back to the service. Now you must verify that client didn't change the field because he probably didn't have permissions to do that. You must do it with every single field which client didn't have permission to change. In the second scenario your DTO with updated data will simply not include this property (= specialized DTO for your operation) so client will not be able to send you a new value at all.
It can be somehow related to the way how you want to work with data and where your real logic will be applied. Will it be on the service or on the client? How will you ensure that client will not post invalid data? Do you want to restrict passing invalid data by logic or by specific transferred objects?
I strongly recommend a dedicated view model.
Doing this means:
You can design the UI (and iterate on it) without having to wait to design the data model first.
There is less friction when you want to change the UI.
You can avoid security problems with auto-mapping/model binding "accidentally" updating fields which shouldn't be editable by the user -- just don't put them in the view model.
However, with a WCF Data Service, it's hard to ignore the advantage of being able to write the service in essentially one line when you expose entities directly. So that might make the most sense for the WCF/server side.
But when it comes to UI, you're "gonna need it."
do I really need DTOs with Entity Framework Code First or can I use the model as a set of common entities for all boundaries?
Yes, the same set of POCOs / entities can be used for all boundaries.
But a set of mappers / converters / configurators will be needed to adapt entities to some generic structures of each layer.
For example, when entities are configured with DataContract and DataMember attributes, WCF is able to transfer domain objects' state without creating any special classes.
Similarly, when entities are mapped using Entity Framework fluent mapping api, EF is able to persist domain objects' state in database without creating any special classes.
The same way, entities can be configured to be used in any layer by means of the layer infrastructure without creating any special classes.

What is the best approach to deal with object graphs across tiers/layers?

We have a typical multi-tier/layer architecture. Application + WCF Service + Repository/EF4/Database.
We are using a customized version of the EF POCO T4 template to generate our entities, that we use across the tiers/layers. We have decided not to use DTO, because of the additional time/work involved.
An example object would be a forest which could have navigation properties of trees which could have navigation properties of leaves.
What is the best approach to add leaves and deal with the object graph? The data is being imported from the client side, so we don't necessarily know if the parent forest/tree already exists in the database.
Query service and retrieve any existing related objects. Attach graph for related objects or create new objects and attach graph on the client side.
example: public Forest GetForest(string forestid)
then --- public void AddLeaf(Leaf leaf)
Create the forest, tree, and leaf objects on the client side and attach the graphs. Send the leaf object across and then on the server side perform logic to compare objects to existing objects in the database. Strip graphs if required, add items that do not exist and/or attach to existing objects.
example: public void AddLeaf(Leaf leaf)
Create the forest, tree and leaf objects on the client side, but don't attach the graphs. Send the objects across and then on the service side perform the logic to compare objects to existing objects in the database. Add items that do not exist and/or attach to existing objects.
example: public void AddLeaf(Leaf leaf, Tree tree, Forest forest)
The question boils down to where should the logic take place to attach the graphs of these related objects.
On a side note I am a little concerned about the "fixup" logic for the navigation properties when dealing with graphs being serialized and deserialized. It seems like that could become an expensive opearation.
Note: The client application is a windows service that is importing data...so it is not necessarily a light weight client. (We are not necessarily afraid of adding logic to it.)
I had similar question few months ago. After playing a lot with this problem my final decission is to use your third solution (my client is always web application). This solution requires writting a lot of code and it includes some additional database queries because each time you want to update your objects you have to load whole object graph first. Reason for this is that when working with detached objects you have to deal with change tracking manually.
When you use third solution you can also involve DTO and transfers only really needed data between client and server.
In case of statefull client (windows app written in .NET or maybe Silverlight) you can also use self tracking entities and your first approach. Self tracking entities are implementation of Changeset pattern. They can track all changes after detaching from context but you have to load your entities first from DB. Self tracking entities are not a good choice in case of web application client or service consumed by non .NET client.

web service data type (contract)

i have a general design question.
we have a fairly big data model that represents an clinical object, the object itself has 200+ child attributes in the hierarchy.
and we have a SetObject operation, and a GetObject operation. my question is, best practice wise, would it make sense to use that single data model in both operations or different data model for each? Because the Get operation will return much more details than what's needed for Set.
an example of what i mean: the data model has say ProviderId, and ProviderName attributes, in the Get operation, both the ProviderId, and ProviderName would need to be returned. However, in the Set operation, only the ProviderId is needed, and ProviderName is ignored by the service since system has that information already. In this case, if the Get and Set operations use the same data model, the ProviderName is exposed even for Set operation, does that confuse the consuming developer?
It would say: it depends :-)
No seriously. How do you edit / work on the object? I assume your software is calling the WCF service to retrieve an object, using an ID or a search term or something.
So you get back the object with 200+ attributes. How do you work on it, how much of it do you typically change?
If you typically only change a handful of attributes - then maybe having a generic SetProperty method on the service that would take the object ID, a property name, and a new value, might make sense. But think about how this is going to work:
the server side code will get the ID for the object
it will load the object from the database
it will then set a single property to a new value
it will save the object back to the database
What if you update four properties? You'd go through 4 of those cycles. Or: you could extend the SetProperty method to include a dictionary of (property name, value) pairs.
So I guess it depends on how many of those 200 properties are you changing at any given time? If you change 10%, 20% of those properties - wouldn't it be easier to just pass back the whole, modified object?
This looks like a good candidate for using your clinical object as canonical model and providing a restful style service interface. You can then provide different views, or representations of your your data object with only the fields required based on the usage model. Your verbs (get, set) will become the http standard Get, Put.
There are a number of open source Rest frameworks that you can use to make this easier to get started. Restlet is one that I have used successfully.