Data Transfer Objects return values - vb.net

Should Data Transfer Objects always be used to transfer data? Please see the code below:
public function getPerson(ByVal id As integer) As Person
return Person
end function
public function getPersonAge(ByVal id As integer) As Integer
return age
end function
The first function returns every piece of information for the person and can probably be reused again and again, when getting information e.g. address about the person in other parts of the application. getPersonAge is slightly faster.

Please be more clear. But if your question is solely "Should DTOs only be used to transfer data" the answer is yes.
A good use of DTOs is keeping in mind that they are only a bunch of getters/setters/properties like: public int MyProperty { get; set; }.
In MVC you can see them as ViewModels but then not for views, but for the several layers in your application.

Related

What type of array should I use for a database of information about the user? vb.net

So I'm trying to make a system where a person can input data about different people and I want to store it in a textile to search and sort the data, It would contain first name, surname, location, phone number.
If I were to use a 2d array how would I go about inputting the data through a loop instead of just writing it out myself.
Or I could use one dimensional arrays and store each type of data, first name, surname etc in separate text files but I am not sure if that would work/be efficient.
If you stored the data as JSON, it would be easier to maintain.
You would create a class to represent the data, read in the file, parse the contents to a collection of your class, and then use LINQ to do your filtering.
This would be efficient enough if you aren't doing any inserts/updates, in which case I would recommend moving to a database to handle these. You could still use the same approach and just serialize the JSON collection back to the file, but you would start to see some significant slow down of the write operation pretty quickly.
Here is an example of defining the class:
Public Class Person
<JsonProperty("firstName")>
Public Property FirstName As String
<JsonProperty("surname")>
Public Property Surname As String
<JsonProperty("location")>
Public Property Location As String
<JsonProperty("phoneNumber")>
Public Property PhoneNumber As String
End Class
Here is an example of reading a text file and parsing it to a collection of your class:
Public Function GetPeople(path As String) As IEnumerable(Of Person)
Dim literal = IO.File.ReadAllText(path)
Dim people = JsonConverter.DeserializeObject(Of IEnumerable(Of Person))(literal)
Return people
End Function
Here is an example of adding people to the collection and serializing it back to the file:
Public Function AddPerson(path As String, record As Person) As IEnumerable(Of Person)
Dim people = GetPeople(path).ToList()
people.Add(record)
IO.File.WriteAllText(path, people.ToString())
Return people
End Function
Keep in mind you'd want to add exception handling and business logic to check that the state is what you would expect it to be.

Limiting Parameters

Probably going to get shot down for this, but I have an issue with my parameters.
Say I need to store a race (Which I do)
During planning, I realized I needed to store things like:
Terrain of the race
location of the race
time the race starts
time admission ends.
Name of the Race
Types of member permitted to join
etc
In short, it's a ton of underivable data that can't really come from elsewere
and all in all, I have like, 22 parrameters for my JuniorRace object, and like 26 Parameters for my SeniorRace object, I've already coded it but it's messy and I don't like my work.
This wouldn't be a massive problem, and it actually won't be a problem AT ALL for the users since they won't see the business model, just the view model, but it is for me having to constantly comment these same parameters multiple times.
What is the best way I can stop using so many parameters every time I make a constructor, and every time I create a new object instance?
do I just try to use less and store data elsewhere, if so, where?
use more classes like Person would have Address and Details?
I'm really stumped here, will post my code, but yeah, it's a ton of parameters pretty much everywhere -- I'm not a very experienced OO programmer.
You could store all the parameters as a map and just pass in the map, something like:
Map myParams = new HashMap<String,Object>();
myParams.add("Terrain","terrible");
myParams.add("Location","Bobs back yard");
myParams.add("Length (yards)", 100);
myParams.add("Hazards", new String[] {"Bob's cat","The old tire","the fence"});
Then you could calll your routine like this:
SaveRaceCourse(myParams);
Maps and suchlike are great for passing around data.
As I can't see all 22 parameters this is a guess but most probably a correct one.
Are some of those 22 parameter related. If so group the related ones in another class and make SeniorRace a composition of all these classes.
For example: location and terrain seem related, admission period and allowed member types seems related to admission (maybe a fee is part of it too).
This way you will end up with a limited set of objects to pass, all related info lives together and evolve together.
Break it down by encapsulating similar properties in objects. It's called decomposition.
For example, your Race can accept a TimeCard encapsulating all the timing details, a Location which has the terrain and what not (maybe directions), an object encapsulating the requirements, ect...
class RaceTimeCard {
private final Timestamp admissionStart;
private final Timestamp admissionEnd;
private final Timestamp raceStart;
private Timestamp raceEnd;
public RaceTimeCard(Timestamp admissionStart, Timestamp admissionEnd, Timestamp raceStart) {
//init final fields
}
public void endRace() {
//clock the time that the race ended
}
}
class RaceLocation {
private final Terrain terrain;
private final Directions directions;
private final GPSCoordinates coordinates;
public RaceLocation(Terrain terrain, Directions directions, GPSCoordinates coordinates) {
//init final fields
}
}
class Race {
private RaceTimeCard timeCard;
private RaceLocation location;
public Race(RaceTimeCard timeCard, RaceLocation) {
//init fields
}
}
If you'd like, you could subclass Location and TimeCard to create specific instances:
final class Mountains extends RaceLocation {
public Mountains() {
super(Terrain.ROCKY, new Directions(...), new GPSCoordinates(...));
}
}
final class EarlyBirdTimeCard extends RaceTimeCard {
public EarlyBirdTimeCard() {
//specify super constructor with params
}
}
Now instantiating your Race object is as simple as:
RaceTimeCard timeCard = new EarlyBirdTimeCard();
RaceLocation location = new Mountains();
...
Race race = new Race(timeCard, location, ...);
If it's still too long, you can probably decompose more. The way I see it, you could have a RaceDetails object containing all the (already decomposed) details, then pass that to Race. Make sure to profile your application, make sure the overhead from object creation doesn't get too bad.

Should an object know how to add itself to a data source?

I have a set of objects that will be read from data source one and written into data source two.
It's tempting to create something like a IAddableToDataSourceTwo interface:
public interface IAddableToDataSourceTwo
function addToDataSourceTwo(connection As DataSource2Connection) as Boolean
public class customer implements IAddableToDataSourceTwo
public function addToDataSourceTwo(connection as DataSourceConnection) as Boolean
insertSQL = "insert into customers values....."
return connection.nonQuery(insertSQL)
However, it seems like that could be a slippery slope. Should an object know how to add itself to a data source?
An alternative option is to do something like this....
public class DataSource2Writer()
public function writeCustomer(connection, customer as Customer)
insertSQL = "insert customer into customers values....."
return connection.nonQuery(insertSQL)
public function writeInvoice(connection, invoice as Invoice)
insertSQL = "insert into Invoices values....."
return connection.nonQuery(insertSQL)
This seems a lot less OO but decouples the customer object from the data source more safely.
Suggestions?
In my opinion, no as it violates the Single Responsibility Principle. However, what you're suggesting is similar to the Active Record pattern. I guess it depends on your stance re: SRP.
I often ask myself "Should a letter (or email) know how to send itself?". Invariably, the answer is no. You typically end up with a "LetterSender" class to do this. Or, in your case, a "CustomerDataMapper".

Objects with two properties only

I am trying to decide on the best approach to the following problem:
I have a class called Desk. A desk has lots of properties. A Desk may have some objects on it. The current application specifies that it can have Pencils, Computers, or Cups on the desk. A few more objects may be added in the future. It can have one or none of each object. The Pencils have a property of Color, all of the objects have an ID and name. All of this information must be persistent so is stored in a database in some form.
Do I:
public class Desk {
public int property1;
public int property2;
...
public ISet<DeskObject> deskObjects;
}
public DeskObject {
public int deskObjectID;
public String name;
public DeskObject(name) {
this.name = name;
}
}
public Computer extends DeskObject {
DeskObject("Computer");
}
public Pencil extends DeskObject {
DeskObject("Pencil);
public Color color;
}
I also need to easily tell which objects a Desk contains in O(1) time. This means I will have to override hashcode and equals (probably by just returning the ID) for the DeskObjects so I can do set.contains(object). It seems like overkill and a misuse of objects. Surely there is a better solution?
If your domain is about desks and the objects they contain, then an object model like this is entirely warranted. The only question you need to ask yourself is this: Is this my domain model, or is it a computation model?
From the phrasing of your question, I would infer its rather the latter. Your objects do not contain any behavior (such as Desk.CleanNonRecentlyUsed()).
A domain model contains data and behavior (a true object model, I call this domain model), a computation model is data and separated behavior (procedural code).
If all your model needs to do is provide efficient lookups, you can chose any abstract representation that suits you. A lightweight object that captures just data is ok, but you could also use tuples (or to be .net specific since you mentioned GetHashCode: Annonymous classes) or just a Hashtable for the desk. Your computation model can be anything from an Index in your database (sounds reasonable in your example), a special object model, or dedicated algorithms over plain arrays.
Most of the time, it is not warranted to create a computation model when you already have a domain model. But sometimes it is.

WCF Data Contract and Reference Entity Data?

Soliciting feedback/options/comments regarding a "best" pattern to use for reference data in my services.
What do I mean by reference data?
Let's use Northwind as an example. An Order is related to a Customer in the database. When I implement my Orders Service, in some cases I'll want the reference a "full" Customer from an Order and other cases when I just want a reference to the Customer (for example a Key/Value pair).
For example, if I were doing a GetAllOrders(), I wouldn't want to return a fully filled out Order, I'd want to return a lightweight version of an Order with only reference data for each order's Customer. If I did a GetOrder() method, though, I'd probably want to fill in the Customer details because chances are a consumer of this method might need it. There might be other situations where I might want to ask that the Customer details be filled in during certain method calls, but left out for others.
Here is what I've come up with:
[DataContract]
public OrderDTO
{
[DataMember(Required)]
public CustomerDTO;
//etc..
}
[DataContract]
public CustomerDTO
{
[DataMember(Required)]
public ReferenceInfo ReferenceInfo;
[DataMember(Optional)]
public CustomerInfo CustomerInfo;
}
[DataContract]
public ReferenceInfo
{
[DataMember(Required)]
public string Key;
[DataMember(Required)]
public string Value;
}
[DataContract]
public CustomerInfo
{
[DataMember(Required)]
public string CustomerID;
[DataMember(Required)]
public string Name;
//etc....
}
The thinking here is that since ReferenceInfo (which is a generic Key/Value pair) is always required in CustomerDTO, I'll always have ReferenceInfo. It gives me enough information to obtain the Customer details later if needed. The downside to having CustomerDTO require ReferenceInfo is that it might be overkill when I am getting the full CustomerDTO (i.e. with CustomerInfo filled in), but at least I am guaranteed the reference info.
Is there some other pattern or framework piece I can use to make this scenario/implementation "cleaner"?
The reason I ask is that although we could simply say in Northwind to ALWAYS return a full CustomerDTO, that might work fine in the simplistic Northwind situation. In my case, I have an object that has 25-50 fields that are reference/lookup type data. Some are more important to load than others in different situations, but i'd like to have as few definitions of these reference types as possible (so that I don't get into "DTO maintenance hell").
Opinions? Feedback? Comments?
Thanks!
We're at the same decision point on our project. As of right now, we've decided to create three levels of DTOs to handle a Thing: SimpleThing, ComplexThing, and FullThing. We don't know how it'll work out for us, though, so this is not yet an answer grounded in reality.
One thing I'm wondering is if we might learn that our services are designed at the "wrong" level. For example, is there ever an instance where we should bust a FullThing apart and only pass a SimpleThing? If we do, does that imply we've inappropriately put some business logic at too high of a level?
Amazon Product Advertising API Web service is a good example of the same problem that you are experiencing.
They use different DTOs to provide callers with more or less detail depending on their circumstances. For example there is the small response group, the large response group and in the middle medium response group.
Having different DTOs is a good technique if as you say you don't want a chatty interface.
It seems like a complicated solution to me. Why not just have a customer id field in the OrderDTO class and then let the application decide at runtime whether it needs the customer data. Since it has the customer id it can pull the data down when it so decides.
I've decided against the approach I was going to take. I think much of my initial concerns were a result of a lack of requirements. I sort of expected this to be the case, but was curious to see how others might have tackled this issue of determining when to load up certain data and when not to.
I am flattening my Data Contract to contain the most used fields of reference data elements. This should work for a majority of consumers. If the supplied data is not enough for a given consumer, they'll have the option to query a separate service to pull back the full details for a particular reference entity (for example a Currency, State, etc). For simple lookups that really are basically Key/Value pairs, we'll be handling them with a generic Key/Value pair Data Contract. I might even use the KnownType attribute for my more specialized Key/Value pairs.
[DataContract]
public OrderDTO
{
[DataMember(Required)]
public CustomerDTO Customer;
//in this case, I think consumers will need currency data,
//so I pass back a full currency item
[DataMember(Required)]
public Currency Currency;
//in this case, I think consumers are not likely to need full StateRegion data,
//so I pass back a "reference" to it
//User's can call a separate service method to get full details if needed, or
[DataMember(Required)]
public KeyValuePair ShipToStateRegion;
//etc..
}
[DataContract]
[KnownType(Currency)]
public KeyValuePair
{
[DataMember(Required)]
public string Key;
[DataMember(Required)]
public string Value;
//enum consisting of all possible reference types,
//such as "Currency", "StateRegion", "Country", etc.
[DataMember(Required)]
public ReferenceType ReferenceType;
}
[DataContract]
public Currency : KeyValuePair
{
[DataMember(Required)]
public decimal ExchangeRate;
[DataMember(Required)]
public DateTime ExchangeRateAsOfDate;
}
[DataContract]
public CustomerDTO
{
[DataMember(Required)]
public string CustomerID;
[DataMember(Required)]
public string Name;
//etc....
}
Thoughts? Opinions? Comments?
We've faced this problem in object-relational mapping as well. There are situations where we want the full object and others where we want a reference to it.
The difficulty is that by baking the serialization into the classes themselves, the datacontract pattern enforces the idea that there's only one right way to serialize an object. But there are lots of scenarios where you might want to partially serialize a class and/or its child objects.
This usually means that you have to have multiple DTOs for each class. For example, a FullCustomerDTO and a CustomerReferenceDTO. Then you have to create ways to map the different DTOs back to the Customer domain object.
As you can imagine, it's a ton of work, most of it very tedious.
One other possibility is to treat the objects as property bags. Specify the properties you want when querying, and get back exactly the properties you need.
Changing the properties to show in the "short" version then won't require multiple round trips, you can get all of the properties for a set at one time (avoiding chatty interfaces), and you don't have to modify your data or operation contracts if you decide you need different properties for the "short" version.
I typically build in lazy loading to my complex web services (ie web services that send/receive entities). If a Person has a Father property (also a Person), I send just an identifier for the Father instead of the nested object, then I just make sure my web service has an operation that can accept an identifier and respond with the corresponding Person entity. The client can then call the web service back if it wants to use the Father property.
I've also expanded on this so that batching can occur. If an operation sends back 5 Persons, then if the Father property is accessed on any one of those Persons, then a request is made for all 5 Fathers with their identifiers. This helps reduce the chattiness of the web service.