i am using LINQ to SQL, 3.5 Framework and i would like to know which is the best way to design the classes. Taking a very simple example of User table.
If i have a User table with 3 different roles of Customer, Admin, Cashier.
I would say i will need to create 3 classes for each of the role. e.g. customers.cs...
Question:
1) Since Linq .dbml already has the User auto generated from my user table, all the properties are already predefined, do i still need to create a User.cs class to be inherited by 3 of the classes role above? This is because i cannot add any duplicate properties in the User.cs e.g. Public string Name {get;set;} would failed because in the .dbml already has the property call Name.
2) This question will be very basic question i think... but i find it useful if i can know the correct answer. How should i park my functionality into the correct class? e.g. PrintYearlyReport(), CheckStaffSalary(), ModifySale(), UpdateGovernmentTax().... all of these functions are under the role of Admin. It will be very readable if we have admin.PrintYearlyReport(), admin.ModifySale()... However, if we park all the admin's functionalities in the Admin.cs file, then this file would be very very huge!!! For OOP sake, we need to have classes like e.g. Sale.cs, Payment.cs, Invoice.cs. If we split all those functionalities into each different classes, then we will no longer have the elegant way of calling the admin.PrintYearlyReport() anymore..
You can create sub-classes of the User class, i.e., Customer, Admin, and Cashier, then specify the correct class based on the user's role. Sometimes we design by creating a method like User.IsInRole or User.HasAccessTo methods that you can call to verify they can access or use certain functionality.
You can split the functionality into separate files but still have them in the same class by using partial classes. If you define public partial class Admin you can define the class Admin in as many separate files as you want, and all of the properties will be added together when building the project.
Let’s keep it simple. Usually the best answer is the simplest one. Do you need to have more than one class? May be may be not. If the differences between the roles is simple one liners, than why the need to create subclasses? I usually start out with one class and as the behavior is better defined and you can clearly diferentiate the subclasses than you create them. With that said you should think about what you want your objects to look like, and by that I mean what dependencies you what to create and what functionality will be shared. Composition vs inheretance When I think of users and roles I think: user has role x, not user is role x because roles can change. Common functionality and properties should be in a base class. May be you can put your access rules in a class that lives within the user:
User{
Name
Role
Rules{ }
}
So you can say
if(user123.Rules.CanPrint())
{
Print();
}
Create the rules inside the user and pass in the role(s) so the rules class can figure out what this user can do. This is how I would do it. My point is, don't get hungup on what class should go where. Define objects and behavior and let the classes define them selves. You will learn to spot when a class is getting too big and need to breake it up.
You can add stereotype to your class diagram and get live persistence annotations in your java code. If you use Hibernate then from your code you can get your database. No need to create an object UML model and another model for your database.
This is what I do and really cool !!
It only works with Java and not with c#.
Related
I am working with an app that handles appointment scheduling.
Right now what I am doing is generating a list of people to call for confirmations in a confirmations section and a list of people to call for rescheduling in a rescheduling section.
I have two separate, but very similar (nearly identical) domain classes for the confirmation items and the rescheduling items.
I have two nearly identical methods in my scheduling service that handle list generation.
I would like to only use one method in the service that would handle the list generation for both of these. The only real difference between the two service methods is which table is being referenced.
My problem is that I can't dynamically change which domain class I am using based on what mode the user is interacting with (confirmations/rescheduling). I get a cannot implicitly convert type error.
I thought a solution would be to create a parent domain class "scheduling item" and have the confirmation item and scheduling item be children of that. However, I still can't figure out how to reference them in the service method.
I thought I could declare a var and then assign it to whichever domain I wanted based on the mode the user is in. That also gets an error because it wants the var's type to be declared in advance.
I am relatively new to C# and I could really use some advice on the best way to simplify this and not have two nearly identical sets of code.
I realize I could just use one class for both, but that would not be ideal, because I would like to keep the data separate for the two domains.
I cannot share the actual code. I figure with the information I have given though, someone might be able to tell me how to handle one service method for two related domain classes.
Thanks in advance for any help you can offer.
To clarify, our set up is like this:
There is a class ConfirmationItem and a class ReschedulingItem that are models for the Mongo database tables.
The Scheduling Service has two methods currently that are "GenerateConfirmationItemList"/"GenerateReschedulingItemList".
The way these methods access the data is like this:
var confirmationItems = GenericRepository.Table<ConfirmationItem>().Where(...).ToList();
var reschedulingItems = GenericRepository.Table<ReschedulingItem>().Where(...).ToList();
Other than these initial table references, the logic is identical.
What would be really helpful is if I could have the method choose which table to use based on what mode we are in (Confirmation or Rescheduling).
However, if I try something like:
var scheduling items;
switch(mode)
case "confirmation":
{
schedulingItems = GenericRepository.Table<ConfirmationItem>().Where(...).ToList();
}
This gets an error because implicitly typed vars have to be assigned.
The repository pattern seems to work well when working with an initial project with several large main tables.
However as the project grows it seems a little inflexible. Say you have lots of child tables that hang off the main table, do you need a repository for each table?
E.g.
CustomerAddress Record has following child tables:
-> County
-> Country
-> CustomerType
On the UI, 3 dropdown lists need to be displayed, but it gets a bit tedious writing a repository for each of the above tables which selects the data for the dropdowns.
Is there a best practice/more efficient way of doing this?
As an example say you have a main CustomerAddress repository which I guess is the 'aggregate root' which inherits the main CRUD operations from the base repo interface.
Previously I have short-cutted the aggregate root and gone straight to the context for these kinds of tables.
e.g.
public Customer GetCustomerById(int id)
{
return Get(id);
}
public IEnumerable<Country> GetCountries()
{
return _ctx.DataContext.Countries.ToList();
}
etc...
But sometimes it doesn't feel right, as countries aren't part of the customer, but I feel like I need to tack it onto something without having to create zillions of repos for each table. A repo per table definately doesn't seem right to me either.
First the code you posted is not the repository pattern. Where is the collection like interface? If it is an aggregate it should only be returning the aggregate type.
Repository pattern doesn't offer up much flexibility when it comes being able to select different types. Repository pattern follows a collection interface (insert/add/update/delete/get/etc), mirroring an in memory thing, and it generally only retrieves on type. So if you were to use the repository pattern you would need to select all CustomerAddresses and then* filter the countries out. I would suggest you move to a different pattern, that allows for more flexibility aka DAO.
If these things are always going to be maintained through CustomerAddress, then switch patterns and create a DAO class that offers some other getters for the other types of things you need.
On a more generic note, build for need.
Never just blindly create repository classes, its a maintenance nightmare. The only time I would argue for a repo per table is when you are doing CMS like things, and need to be able create everything.
Example:
So you have a CustomerAddress which ties together a Customer and a Country, but you have some other process that needs to be able to CRUD the Country. As a result you need* the repository to manipulate Country and if you are following DRY you dont want to have duplicate logic to manipulate Countries. What you would have is a Customer Respotitory that uses the Country repository.
I'm answering my own question here because while the suggestions are certainly useful, I feel I have a better solution.
While I don't have to phsyically create the underlying repository for each and every table as I have a generic repository base class with interface (Get, Add, Remove), I still have to:
1) write the interface to access any specialised methods (generally these are queries)
2) write those implementations
I don't necessarily want to do this when all I want to retrieve is a list of countries or some simple type for populating a dropdown. Think of effort required if you have 10 reference type tables.
What I decided to do was create a new class called SimpleRepo with ISimpleRepo interface which exposes 1-2 methods. While I don't normally like to expose the IQueryable interface out of the repo i/f class, I don't mind here as I want the provided flexibility. I can simply expose a 'Query()' method which provides the flexibility hook. I might need this for specialising the ordering, or filtering.
Whenever a service needs to make use of some simple data, the ISimple< T > interface is passed in, where T is the table/class.
I now avoid the need to create an interface/class for these simple pieces of data.
Thoughts anyone?
Responding to the questioner's own answer: This doesn't make sense to me; though it's possible you still had a good use case, I'm not following. Points 1 and 2 ... if you need specialized methods, then looks like they belong in their own repo. Point 2: yes, that needs an implementation.
Sharing between repos, with the smaller repo being the question (is that one needed), I do appreciate that question / problem, but guys' on this thread steered me to being okay with 1 repo per table, including the possibility of having a 'service layer', though they didn't give any examples of that, and I haven't tried this out yet (currently my practice, for good or ill, has been to have the bigger repo share or instantiate the smaller one it needs):
One repository per table or one per functional section?
Suppose we want to model a doctor's patient: a patient has a prescription history, an appointment history, a test results history... Each of these items is itself a list.
What's the best way to create the patient class?
class MyPatient{
List<Prescription> Prescriptions {get;set;}
List<Appoints> Appoints {get;set;}
...
}
class Prescription{
string PrescripName {get;set}
int Dosage {get;set}
}
class PatientAppoint{...}
This is what I have in mind; please let me know if you have some suggestions.
There are a lot of things to take into account when designing your classes:
Inheritence vs Composition -- Use "Is A" and "Has A".
For example, a Car is a Vehicle. A Car has a Engine.
Don't throw in a bunch of junk into a class to try to make it work for another class.
For example, if you want a Prescription history you'll probably need a Prescription and a Date. But, don't throw a Date into Prescription if it doesn't fit in, instead, extend it to a new PrescriptionHistoryItem class which inherits from Prescription.
Start off with an abstract representation or contractual representation and build off of that. You don't need to end up keeping any abstract classes or interfaces if they are unnecessary, but they might help you on the way there.
Basically, there are a lot of things to consider and this question is pretty open ended. There are way too many design patterns and topics to consider and that are debatable. Overall, your class hierarchy/design looks fine though.
Instead of keeping all classes in a file , i would create a separate file for each class with the same name. It will be easy for future programmer to debug or it will be very clean to understand.
Yes, that is a pretty standard way of representing those objects in OOP. Your patients have a one to many relationship with both prescriptions and appointments, so you patient class has a collection of each. You may want to keep how you are going to persist you data (database I assume) in mind as you design your class structures and layout.
This is a good example of where the model can become problematic at runtime. As you start to draw this out, you may end up with a collection of patients at somepoint. If you have data adapters building patients, and stuffing the prescription, visit, test, etc. histories into the patient classes, then a collection of Patients can end up being quite large. Now if this large collection is being transported over a network, say, between a WCF service and a client, it could become burdensome. For example, if you are just displaying a list of patients...
So in my opinion, I would look at the system from a slightly higher level, and consider some of the things I mentioned above. If you are going to be passing around collections with 500 patients in them, then I might consider a model that allows me to associate patients and "item" histories when necessary, but also be able to have them separated when desired...
This would affect the model, in my opinion, because I don't like to design a class where when the data adapter builds the instance, the population of fields is arbitrary, that is, sometimes it populates them sometimes it doesn't... But I have done that before... ;)
I'm developing a system that has different types of users. Based upong their role, the system collects different information. I'm a little unsure how best to architect this.
At the base level I have a User entity which contains just the core info for a user. Beyond this, I need somewhere to store common information (not sure whether to add this to the User entity, create something like a Profile entity, or create a Member entity that extends the User entity).
After this, I then need somewhere to store the user type specific data. My roles are "Seller", "Merchant" and "Buyer". A User / Member can be one or more of these user types. I'm not sure here whether these should be seperate entities which extend the base User / Member, or whether these are more like extended profiles, which are a property on the User entity.
Could anybody sugest the best way to architect this?
Unless there's something fundamentally user-unrelated about the common information, you can store it into the user entity. For rôles, consider having separate entities linked to the user entity. This permits adding new rôles to a user (happens when somebody who has always been buying stuff suddenly decides to sell something), which the interface-based solution may have problems with (depending on your implementation language, of course).
An common pitfall is adding all rôle fields to the user entity. It works, but it tends to progress into unmaintainability as new rôles are added to the system.
I just finished creating something very similar for a system I'm working on. The theory, in general, is to separate the definition (who they are) of an entity from its behaviour (roles; what they do). I also wanted to preserve the ability to query users based on the metadata contained in the roles that they are assigned to.
I ended up creating a Person class that looks like this:
class Person {
Guid Id;
ISet<Role> Roles;
string Name; // and any other stuff a "person" might have
}
Next, I have an abstract Role class that looks like this:
abstract class Role {
Guid Id;
abstract string Name { get; } // implemented by concrete definitions of roles
Person Person;
}
From this, I derive individual classes that "define" each role I have in my system. A User role would look something like this:
class User : Role {
override string Name { get { return "User"; } }
string LoginId;
string Password;
// etc.
}
Rinse and repeat for any other roles you might have.
At the ORM level (where I use NHibernate), I define UserRole as a joined-subclass of the Role entity.
The underlying assumptions behind this approach are:
Roles aren't dynamic.
There is no definition of roles at the data layer. A role exists simply because there's a class that derives from it.
You can't assign a role to the same
person multiple times with different
metadata
Well, in theory, I guess you could but it makes no sense for my particular system for a person to have two User roles assigned to them with different login ids and passwords.
I would start by making a separate interface for each: IUser, IMember, ISeller, IMerchant and IBuyer. Then I would create a separate Class and for each interface, which understands how to handle the CRUD for the instance (Create, Read, Update and Delete).
The nexus is the member. The IMember interface needs methods/propreties for IsSeller, IsMerchant and IsBuyer. If those return TRUE, the you know you can cast the Member object into the corresponding interfaces, or at least fetch the interface handler via a method. Note that the Member object always supports the IUser interface too.
That should get your started.
Depends if the available roles are fixed or fluid. Sounds like they're fixed, so you can:
define user.role as an int.
Define the roles as static ints to the power of two, e.g. Role.SELLER=1, Role.MERCHANT=2, Role.BUYER=4, and so on.
Add a hasRole() method to the user object that does a simple bitwise OR operation to determine if a user has a particular role.
I find it difficult to determine the responsiblity of classes: do i have to put this method in this class or should I put this method in another class? For example, imagine a simple User class with an id, forname, lastname and password. Now you have an userId and you want the forname and lastname, so you create a method like: public User GetUserById(int id){}. Next you want to show list of all the users, so you create another method: public List GetAllUsers(){}. And offcourse you want to update, delete and save a user. This gives us 5 methods:
public bool SaveUser(User user);
public bool UpdateUser(User user);
public bool DeleteUser(User user);
public User GetUserById(int id);
public List<User> GetAllUsers();
So my question is: do you put all these methods in the User class? Or do you create another data class (UserData class) which may connect to the database and contain all these methods?
What you are describing here is basically a choice between the Active Record Pattern or the Repository Pattern. I'd advise you to read up on those patterns and choose whichever one fits your application / experience / toolset.
I would not put those specific methods into the 'User' class.
There are 2 common approaches for this 'problem':
You put those method in the User
class, and then this means you 're
using the Active Record pattern
You put those methods in a
separate class (UserRepository) for
instance, and then you're using the
Repository pattern.
I prefer the repository-approach, since that keeps my 'User' class clean, and doesn't clutter it with data access code.
Barring additional complexity specific to a group of users (or really elaborate database access mechanics) I might make those methods static on the User class.
Those methods sound more like a UserManager (or something like that) to me. The user class should correspond to and represent only a single user, not many.
If we look at Enterprise Application design patterns, then the methods for fetching Users i.e. GetUserByID and GetAllUsers would be in separate class - you can name it UserData or UserDAO (DAO - Data Access Object).
Infact you should design an interface for UserDAO with appropriate methods for handling User Objects - such as CreateUser, UpdateUser, DeleterUser, GetUserXXX and so on.
There should be an implementation of UserDAO as per the data source, for example if your users are stored in database then you can implement the logic of accessing database in the implementation of UserDAO.
Following are the advantages of keeping the access methods in separate class:
1) User object should be plain object with just getter setter methods, this would facilitate passing object across tiers - from data access tier, to business tier to web tier. This would also help keep User Object serializable
2) The data access logic is loosely coupled from the User object - that means if the datasource changes, then you need not change the User object itself. This also assists in Test Driven Development where you might need to have mock objects during testing phase
3) If User object is complex object with relations with other objects such as Address or Department or Role etc. then the complexity of relationships will be encapsulated in UserDAO rather than leaking in the User Object.
4) Porting to frameworks like NHibernate or Spring.NET or .NET LINQ would become easier if the patterns are followed
Lets us see you scenario as this.
There are 'N' number of people working in assembly division of you company.
It is okay to go to a person and ask about his information BUT you cant expect him to tell you details of all persons working in assembly division. Reason why shud he remember all the details and if you do expect then his effeciency will go down(work on assembly and also remember details of others).
So ..... perhaps we can appoint a manager who can do this ppl maanagement activities
(get details, add new person, edit ,delete etc etc )
Therefore you have two entities
1) User/Person working in your assembly deivision
2) a Manager
Thus two classes. Hopes this will help you.
Thanks
If I understand your question correctly the User class deals with a single user. Hence the user class does not have a clue about how many users there are or anything about them. The structure holding this information is somewhere else and the methods you mention seem to belong to that structure / class.
With all else being equal either way is fine. Which to choose, though, usually depends on the overall architecture of the application or class library in which you find the User class. If the data access code seems tangled with the User object code, then it might make more sense to split it into two classes as you've considered. If the CRUD methods are one-line delegations to a DAL with maybe application-specific logic, then leaving them in the User class should be okay.
The complexity is more or less the same in both cases—it's a trade-off between a low-maintenace assembly with few high-maintenance classes or a high-maintenance assembly with a larger number of low-maintenance classes.
I'm also assuming that the CRUD methods should be static.
Do what's easiest to get the code written right now but consider possible refactorings in the future should you find that it'll be better that way.