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".
Related
I have an object, let's call it a Request, that has associations to several other objects like:
Employee submitter;
Employee subjectsManager;
Employee pointOfContact;
And several value properties like strings, dates, and enums.
Now, I also need to keep track of another object, the subject, but this can be one of 3 different types of people. For simplicity let's just talk about 2 types: Employee and Consultant. Their data comes from different repositories and they have different sets of fields, some overlapping. So say an employee has a
String employeeName;
String employeeId;
String socialSecurityNumber;
Whereas a consultant has
String consultantName;
String socialSecurityNumber;
String phoneNumber;
One terrible idea is that the Request has both a Consultant and an Employee, and setSubject(Consultant) assigns one, setSubject(Employee) assigns the other. This sounds awful. One of my primary goals is to avoid "if the subject is this type then do this..." logic.
My thought is that perhaps an EmployeeRequest and a ConsultantRequest should extend Request, but I'm not sure how, say, setSubject would work. I would want it to be an abstract method in the base class but I don't know what the signature would be since I don't know what type the parameter would be.
So then it makes sense to go at it from an interface perspective. One important interface is that these Request objects will be passed to a single webservice that I don't own. I will have to map the object's fields in a somewhat complex manner that partially makes sense. For fields like name and SSN the mapping is straightforward, but many of the fields that don't line up across all types of people are dumped into a concatenated string AdditionalInfo field (wump wump). So they'll all have a getAdditionalInfo method, a getName, etc, and if there's any fields that don't line up they can do something special with that one.
So that makes me feel like the Request itself should not necessarily be subclassed but could contain a reference to an ISubjectable (or whatever) that implements the interface needed to get the values to send across the webservice. This sounds pretty decent and prevents a lot of "if the subject is an employee then do this..."
However, I would still at times need to access the additional fields that only a certain type of subject has, for example on a display or edit page, so that brings me right back to "if subject is instance of an employee then go to the edit employee page..." This may be unavoidable though and if so I'm ok with that.
Just for completeness I'll mention the "union of all possible fields" approach -- don't think I'd care to do that one either.
Is the interface approach the most sensible or am I going about it wrong? Thanks.
A generic solution comes to mind; that is, if the language you're using supports it:
class Request<T extends Subject> {
private T subject;
public void setSubject(T subject) {
this.subject = subject;
}
public T getSubject() {
return subject;
}
}
class EmployeeRequest extends Request<Employee> {
// ...
}
class ConsultantRequest extends Request<Consultant> {
// ...
}
You could similarly make the setSubject method abstract as you've described in your post, and then have separate implementations of it in your subclasses. Or you may not even need to subclass the Request class:
Request<Employee> employeeRequest = new Request<>();
employeeRequest.setSubject(/* ... */);
// ...
int employeeId = employeeRequest.getSubject().getEmployeeId();
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.
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.
I am implementing a Data Access Layer (DAL), which is basically a set of classes with (VB.NET) Shared functions to actually execute the database (CRUD) calls. I am trying to figure out the best place to place the calls to the DAL within the class hierarchy. Let me give an example.
Suppose I have a class Customer, with only standard ID, Name, Address1, etc. properties and maybe an overridden ToString function or so. I also have a DAL class with Shared methods, such as:
(pseudocode)
Namespace Dal
Public Class Customer
Public Shared Function Read(id As Integer) As Customer
Public Shared Function ReadList() As List(Of Customer)
Public Shared Sub Create(c As Customer)
'etc.
Now, I could call the Dal from the presentation layer like so:
Me.DataGridView1.Datasource = Dal.Customer.ReadList
However, is it not a good practice to have the presentation layer aware of the Dal at all? Should I instead put methods in the Customer object and call the Dal, like this?
Public Function ReadList() As List(Of Customer)
Return Dal.Customer.ReadList()
End Sub
Public Sub Create()
Dal.Customer.Create(Me)
End Sub
Would this be "cleaner" OOP? Or is it acceptable practice to let the presentation call the Dal, passing the business objects like my previous example:
Me.DataGridView1.Datasource = Dal.Customer.ReadList
Dim c As New Customer
c.Name = "Alpha Corporation"
c.Address1 = "123 Main Street"
Dal.Customer.Create(c)
Thanks for your feedback.
The less your application knows about your DAL the better. There are several ways to do this and I think you are on the right track. I think you might want to look into the factory pattern for this implementation as you will be able to hide the DAL implementation behind the factory and return entities and collections of entities from the factory.
I agree that data calls do not belong in a UI layer. Those are for presentation only.
I think they properly belong in a service layer. The service implementation uses model objects and the persistence layer to accomplish its goals. Whether that's an XML-based web service or local interface, the service is the object that maps to use cases and knows about units of work.
Either put the database calls into a separate persistence layer or embed them in the model objects for extra object-oriented purity.
The reason why'd you want to pull the CRUD operations into a separate layer is in case you ever want to change database systems. Well, that's why I did it. I wouldn't recommend doing this just to be good OOD. But here ya go...
Several sets of classes/interfaces
BusinessObject - Represents business type entities such as a Customer, has DataManager as a property.
DataManager - Maybe you can come up with a better name, but this thing provides Load() and Save() functions for the BusinessObjects
SearchList - Returns lists of things, your SQL queries go here. Also this should probably behave like a RecordSet with Next(), Eof(), and CurrentRecord type members
Constructor/Factory - See FactoryPattern. You've de-coupled your database operations from your business objects this thing re-couples them in a necessary way. Assigns an appropriate datamanager implementation to BusinessObject
Come up with whatever actual names you want, but let's talk about Customer again. Suppose you have an Oracle database. You might end up with these classes:
boCustomer that inherits from BusinessObject
oracleDMCustomer that inherits or implements DataManager
searchlistCustomer that inherits from searchlist that has exposed either through abstract methods or as an interface something like:
SearchAll() - which should return all customer
SearchByZip(String zip) which should return all customers with the given zipcode
oracleSearchlistCustomer - implements searchlistCustomer, would actually implement the SearchAll() and SearchByZip()
boFactory - static class that has a method that looks something like CreateObject(Type type)
searchlistFactory - static class that has a method that looks something like CreateSearchList(Type type);
I'll let you fill in some of the blanks, but I think the important stuff is there. Others may have different ideas that require less abstraction. I'd mock up several strategies before going with one.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Which class design is better and why?
public class User
{
public String UserName;
public String Password;
public String FirstName;
public String LastName;
}
public class Employee : User
{
public String EmployeeId;
public String EmployeeCode;
public String DepartmentId;
}
public class Member : User
{
public String MemberId;
public String JoinDate;
public String ExpiryDate;
}
OR
public class User
{
public String UserId;
public String UserName;
public String Password;
public String FirstName;
public String LastName;
}
public class Employee
{
public User UserInfo;
public String EmployeeId;
public String EmployeeCode;
public String DepartmentId;
}
public class Member
{
public User UserInfo;
public String MemberId;
public String JoinDate;
public String ExpiryDate;
}
The question is simply answered by recognising that inheritance models an "IS-A" relationship, while membership models a "HAS-A" relationship.
An employee IS A user
An employee HAS A userinfo
Which one is correct? This is your answer.
I don't like either one. What happens when someone is both a member and an employee?
Ask yourself the following:
Do you want to model an Employee IS a User? If so, chose inheritance.
Do you want to model an Employee HAS a User information? If so, use composition.
Are virtual functions involved between the User (info) and the Employee? If so, use inheritance.
Can an Employee have multiple instances of User (info)? If so, use composition.
Does it make sense to assign an Employee object to a User (info) object? If so, use inheritance.
In general, strive to model the reality your program simulates, under the constraints of code complexity and required efficiency.
Nice question although to avoid distractions about right and wrong I'd consider asking for the pros and cons of each approach -- I think that's what you meant by which is better or worse and why. Anyway ....
The First Approach aka Inheritance
Pros:
Allows polymorphic behavior.
Is initially simple and convenient.
Cons:
May become complex or clumsy over time if more behavior and relations are added.
The Second Approach aka Composition
Pros:
Maps well to non-oop scenarios like relational tables, structured programing, etc
Is straightforward (if not necessarily convenient) to incrementally extend relations and behavior.
Cons:
No polymorphism therefore it's less convenient to use related information and behavior
Lists like these + the questions Jon Limjap mentioned will help you make decisions and get started -- then you can find what the right answers should have been ;-)
I don't think composition is always better than inheritance (just usually). If Employee and Member really are Users, and they are mutually exclusive, then the first design is better. Consider the scenario where you need to access the UserName of an Employee. Using the second design you would have:
myEmployee.UserInfo.UserName
which is bad (law of Demeter), so you would refactor to:
myEmployee.UserName
which requires a small method on Employee to delegate to the User object. All of which is avoided by the first design.
You can also think of Employee as a role of the User (Person). The role of a User can change in time (user can become unemployed) or User can have multiple roles at the same time.
Inheritance is much better when there is real "is a" relation, for example Apple - Fruit. But be very careful: Circle - Ellipse is not real "is a" relation, because cirlce has less "freedom" than ellipse (circle is a state of ellipse) - see: Circle Ellipse problem.
The real questions are:
What are the business rules and user stories behind a user?
What are the business rules and user stories behind an employee?
What are the business rules and user stories behind a member?
These can be three completely unrelated entities or not, and that will determine whether your first or second design will work, or if another completely different design is in order.
Neither one is good. Too much mutable state. You should not be able to construct an instance of a class that is in an invalid or partially initialized state.
That said, the second one is better because it favours composition over inheritance.
Stating your requirement/spec might help arrive at the 'best design'.
Your question is too 'subject-to-reader-interpretation' at the moment.
Here's a scenario you should think about:
Composition (the 2nd example) is preferable if the same User can be both an Employee and a Member. Why? Because for two instances (Employee and Member) that represent the same User, if User data changes, you don't have to update it in two places. Only the User instance contains all the User information, and only it has to be updated. Since both Employee and Member classes contain the same User instance, they will automatically both contain the updated information.
Three more options:
Have the User class contain the supplemental information for both employees and members, with unused fields blank (the ID of a particular User would indicate whether the user was an employee, member, both, or whatever).
Have an User class which contains a reference to an ISupplementalInfo, where ISupplementalInfo is inherited by ISupplementalEmployeeInfo, ISupplementalMemberInfo, etc. Code which is applicable to all users could work with User class objects, and code which had a User reference could get access to a user's supplemental information, but this approach would avoid having to change User if different combinations of supplemental information are required in future.
As above, but have the User class contain some kind of collection of ISupplementalInfo. This approach would have the advantage of facilitating the run-time addition of properties to a user (e.g. because a Member got hired). When using the previous approach, one would have to define different classes for different combinations of properties; turning a "member" into a "member+customer" would require different code from turning an "employee" into an "employee+customer". The disadvantage of the latter approach is that it would make it harder to guard against redundant or inconsistent attributes (using something like a Dictionary<Type, ISupplementalInfo> to hold supplemental information could work, but would seem a little "bulky").
I would tend to favor the second approach, in that it allows for future expansion better than would direct inheritance. Working with a collection of objects rather than a single object might be slightly burdensome, but that approach may be better able than the others to handle changing requirements.