Posted: 6/21/2011
I am not sure whether this is the right forum for this question, so I would appreciate some feedback on it . I know that it is a rather long question.
Anyway, here goes:
I am developing an ASP.Net c# application for a firm which offers their customers Accountancy, Auditing, Taxation etc. services. The idea is to give the firm a tool to track the work done for each of their clients. Since these services have deadlines (e.g. if they offer Taxation services, a submission of Corporate Tax forms to the IRS on 31/12 every year must be made), they prefer looking at these jobs as projects, assigning resources to them as they progress.
So I have designed a class Project, containing some properties, one of which is Deadlines which is List<Deadline>. Deadline is another class; I should also mention here that there are different types of deadlines (i.e. for Corporate Tax service, it is annual every 31/12, for VAT every expiration of the quarter plus one month and 10 days, etc).
My first question is how to model this; should the deadline be linked to the service? As shown above, I currently have a list deadlines for each project. They way I see it, when a project is completed, another one will start as deadlines are recurring. So when the tax books are submitted for 2010 (by 31/12/2011), a project must start for the submission of the books for 2011 (to be submitted by 31/12/2012).
My second question is what fields to include in the Deadline class so as to cope with all the different types of recurrency there may be:
Annual
Every x day of month
Quarterly
etc.
My last question is once I represent this, how to make the application create the projects automatically so that the managers start planning for them (start date, resources, budgeted amount, etc).
Thanks for reading this far!
Chris
Chris Loucas said: I am not sure whether this is the right forum for this question, so I would appreciate some feedback on it . I know that it is a rather long question.
Hi Chris,
Well, more or less, you are on the right forum... If not, don't worry, we will move it on the appropriate one, or of course, you would have got warning from me if you are not in the right place... but, nvm, lets go to your issue.
Chris Loucas said: Anyway, here goes:I am developing an ASP.Net c# application for a firm which offers their customers Accountancy, Auditing, Taxation etc. services. The idea is to give the firm a tool to track the work done for each of their clients. Since these services have deadlines (e.g. if they offer Taxation services, a submission of Corporate Tax forms to the IRS on 31/12 every year must be made), they prefer looking at these jobs as projects, assigning resources to them as they progress.So I have designed a class Project, containing some properties, one of which is Deadlines which is List<Deadline>. Deadline is another class; I should also mention here that there are different types of deadlines (i.e. for Corporate Tax service, it is annual every 31/12, for VAT every expiration of the quarter plus one month and 10 days, etc).My first question is how to model this; should the deadline be linked to the service? As shown above, I currently have a list deadlines for each project. They way I see it, when a project is completed, another one will start as deadlines are recurring. So when the tax books are submitted for 2010 (by 31/12/2011), a project must start for the submission of the books for 2011 (to be submitted by 31/12/2012).
Designing your application architecture sometimes depends of many factors, not only the requirements needed. One of the ways I see many developers prefer (and thats how ORM tools work as well) is to map your Business Objects the way your Database Tables for your application are designed (with their relations). More or less, your databse snapshoots your project model and this should give you the initial big picture of how your architecture should look like or should behave & keep relation.
Another approach is to start reading more about practical Design Patterns. But, if you are hurrying with your project, this might consume you more time to get the best out of these concepts.
Therefore, if you ask me, I would go in different ways. One of these ways would be to keep different class for each type that has different properties or behavior (but still, this may be seen by the database table relations for your project).
In your case, I think yes, the Deadline should have logical relation with Service. So, you should define your own Service class which will has its own behavior (methods, functions, properties and fields). If you are able and if you have enough time to design good structure, keep clean structure and try to make more granular way of representing object types. Try to divide the responsibilities logically to different types so that you won't mix things later. More or less, having the given information, these are the strong opinions I can give. If you provide us some more info, like if you have database and the database structure, some more details on the business itself, maybe I can even give you more details, but still, bare in mind that here we are trying to make you not only solve your issues, but also make you learn for lifetime, not for only once ;). (Feed a man with fish, you will feed him for one day. Teach a man to fish, you feed him for lifetime).
Chris Loucas said: My second question is what fields to include in the Deadline class so as to cope with all the different types of recurrency there may be:AnnualEvery x day of monthQuarterlyetc.
Well, when we are here, I might even change my mind about 'Deadline'. Maybe, if deadline has no other responsibilities than only defining the Deadline type, you can include it as Enumerator as part of the Service class. So the Enumerator may have the options of 'Annual', 'EveryXDayOfMonth', 'Quarterly' etc. So, later in the Service class behavior, functions and methods, based on the Deadline enumerator, you may have some different processing algorithms. But, it is very important to mention that this might be a case only if 'Deadline' as an logical object does not have other responsibilities than defining the deadline type, and we put all other responsibilities to the 'Service' class object. Otherwise, if there is anything else, Deadline can be still defined as different clas, but the Deadline types can be still defined as enumerator field in that class.
Chris Loucas said: My last question is once I represent this, how to make the application create the projects automatically so that the managers start planning for them (start date, resources, budgeted amount, etc).Thanks for reading this far! Chris
I would like to ask what do you mean by 'Automatically?'... Does it means, when some date reach, the application will create new Project automatically and setup other things? If that's so, well, you can create Scheduler that may operate in your application (this may cost), or maybe better would be to create Windows Service or some other functional program that will run based on Windows Task Scheduler or Windows Services system. This will give you the opportunity to create new DB entries based on some given date-time, on a daily, hourly or any defined time-interval-based system. Also, you can provide WCF or Web Services (ASMX) in your application, so that these third-party applications from within your domain will operate with the your application and all the features that you will expose tru these services. If you meant on this by saying 'Automatically', then you have my initial opinion and advice... If not, please elaborate more.
I hope this was helpful.
Best Regards,Hajan
Posted: 6/22/2011
Thanks for your response, you really helped me thinking in a more focused track; I believe that this is much more valuable than giving me code snippets and quick solutions.
After some further SRP analysis I did, it appears that the logic of creating the deadlines is really Service-specific, not deadline specific, so I am thinking that perhaps some further classes can be inherited from BaseService class such as TaxationService, VATService, etc. Each of these specific classes will carry their own method and logic of creating deadlines, so a call can be made to e.g. CreateDeadlines(startDate,endDate) which will return a List<Deadline> for the period required. This shifts the responsibility of deducing when the deadlines are to the Service itself rather than the Deadline (which it seems that it should be pretty simple, i.e. a date, type and some description along with identifiers, id and project id so as to identify which project it belongs to).
Now, in my DB I currently have a table called Services in which all the various Services are stored. There are also methods in the Service object to create, amend and delete services. There is also another table called CompanyServices linking companies to the services (once the user selects which services a company receives). So for example Company with Id=8 receiving service with id=5 will have an entry in the CompanyServices table with these two id's.
I am wondering whether this structure must change if I am to implement the strategy above; How will the application know what type of class to use for the service? It seems to me that in the BLL I may end up having Companies objects linked to Services Objects which are not of the same type (a Company may be receiving TaxationService, VATService, etc); so by calling GetServicesForCompany I will get back what? Also if in the Services table, Taxation Service has id=5, and the user enables this service for the client some hard-coded conditional logic must exist in the application that will check the Service Id, and if it is 5, it will instantiate a TaxationService and call its methods to create the deadlines. I am wondering if there is a better way to deal with this.
Also, as far as maintainability goes clearly by adding a new service in the database (perhaps they decide to offer an additional service in the future) will not be enough to implement a new service as a new Service class (e.g. FutureService) must also be implemented, containing the logic of the service in building deadlines (whatever that will be). I guess this is normal?
Sorry for dragging this too long, I just wanted to articulate my confusion and concerns as clearly as I could.
Posted: 6/25/2011
Chris Loucas said: Thanks for your response, you really helped me thinking in a more focused track; I believe that this is much more valuable than giving me code snippets and quick solutions.
Chris Loucas said: After some further SRP analysis I did, it appears that the logic of creating the deadlines is really Service-specific, not deadline specific, so I am thinking that perhaps some further classes can be inherited from BaseService class such as TaxationService, VATService, etc. Each of these specific classes will carry their own method and logic of creating deadlines, so a call can be made to e.g. CreateDeadlines(startDate,endDate) which will return a List<Deadline> for the period required. This shifts the responsibility of deducing when the deadlines are to the Service itself rather than the Deadline (which it seems that it should be pretty simple, i.e. a date, type and some description along with identifiers, id and project id so as to identify which project it belongs to).Now, in my DB I currently have a table called Services in which all the various Services are stored. There are also methods in the Service object to create, amend and delete services. There is also another table called CompanyServices linking companies to the services (once the user selects which services a company receives). So for example Company with Id=8 receiving service with id=5 will have an entry in the CompanyServices table with these two id's.
This seems pretty good to me. For your DB relation between Services and Company, it means these are in MANY-TO-MANY relation since you have put CompanyService table that will carry that relation on the right way. So, thus far, everything seems ok and logical to me, with the data I have to evaluate this.
Chris Loucas said: I am wondering whether this structure must change if I am to implement the strategy above; How will the application know what type of class to use for the service? It seems to me that in the BLL I may end up having Companies objects linked to Services Objects which are not of the same type (a Company may be receiving TaxationService, VATService, etc); so by calling GetServicesForCompany I will get back what? Also if in the Services table, Taxation Service has id=5, and the user enables this service for the client some hard-coded conditional logic must exist in the application that will check the Service Id, and if it is 5, it will instantiate a TaxationService and call its methods to create the deadlines. I am wondering if there is a better way to deal with this.Also, as far as maintainability goes clearly by adding a new service in the database (perhaps they decide to offer an additional service in the future) will not be enough to implement a new service as a new Service class (e.g. FutureService) must also be implemented, containing the logic of the service in building deadlines (whatever that will be). I guess this is normal?
Well, since you have BaseService class (which may be probably abstract class?), and all other ServiceType specific will inherit from that class, the 'GetServicesFromCompany' method may be defined in the base class, if all other classes that derive from that class implement that method. Therefore, which implementation will be called will depend on which instance is created.
By far I have seen and I have got picture of what design should be needed here, you can implement something like this class structure schema (bare in mind this is not definitive and may need changes for some additional requirements in your project)
public abstract class BaseService<T> { public virtual List<T> GetServicesForCompany(int companyId) { //any base implementation here return new List<T>(); } } public class TaxationService : BaseService<TaxationService> { public override List<TaxationService> GetServicesForCompany(int companyId) { //any TaxationService specific implementation here return base.GetServicesForCompany(companyId); } } public class VATService : BaseService<VATService> { public override List<VATService> GetServicesForCompany(int companyId) { //any VAT Service specific implementation here return base.GetServicesForCompany(companyId); } }
One more thing I would like to knwo is what Data Access approach you plan to use? If you are using some ORM-based approach, like Entity Framework, NHibernate or LINQ2SQL, you will already get the business objects created by the ORM itself from Database tables in code classes. So, more or less you can add another layer of business logic that may have your custom implementation for logical scenarios within your application higher layer, but you may need to make additional mappings for some cases to handle the db operations well.
Chris Loucas said: Sorry for dragging this too long, I just wanted to articulate my confusion and concerns as clearly as I could.
Don't worry, I hope my answer was helpful for you.