Please critique the (fictious and incomplete) code below. I would like advice on how to make the code into more of a standard architecture or pattern. The example is a registration system where a person is registering for an event.
I've been programming for a couple of years now and I've been learning about different techniques for creating an n-layer architecture. I'm finding some of the concepts difficult without having concrete examples (most of the examples that I have seen on the 'net aren't nearly complete or don't provide answers to problems) so I would like to use the example below as a starting point.
(Sorry for such a long post. I'm unable to add an attachment due to permissions.)
Domain Model Base (Entities)
1 namespace domainModelExample
2 {
3 /// <summary>
4 /// The domain object for a Person
5 /// </summary>
6 public class Person : domainModelExample.Data.DomainObjectBase
7 {
8 private string _firstName;
9 private string _lastName;
10
11 public Person() : base() { }
12 public Person(string firstName, string lastName)
13 {
14 this.FirstName = firstName;
15 this.LastName = lastName;
16 }
17
18 public string FirstName
19 {
20 get
21 {
22 return this._firstName;
23 }
24 set
25 {
26 this._firstName = value;
27 }
28 }
29
30 public string LastName
31 {
32 get
33 {
34 return this._lastName;
35 }
36 set
37 {
38 this._lastName = value;
39 }
40 }
41 }
42
43 /// <summary>
44 /// Represents a registration for an event
45 /// </summary>
46 public class Registration : domainModelExample.Data.DomainObjectBase
47 {
48 private Person _person;
49 private Event _event;
50 private RegistrationType _type;
51
52 public Registration(Event eventInfo, Person person)
53 {
54 //TODO: Check to make sure the event and person are not null
55
56 this.Event = eventInfo;
57 this.Person = person;
58
59 //Adds this registration to event, if not already there
60 eventInfo.Registrations.Add(this);
61 }
62
63 public Person Person
64 {
65 get
66 {
67 return this._person;
68 }
69 private set
70 {
71 this._person = value;
72 }
73 }
74
75 public Event Event
76 {
77 get
78 {
79 return this._event;
80 }
81 private set
82 {
83 this._event = value;
84 }
85 }
86
87 /// <summary>
88 /// Gets or sets the type of registration
89 /// </summary>
90 public RegistrationType Type
91 {
92 get
93 {
94 return this._type;
95 }
96 set
97 {
98 this._type = value;
99 }
100 }
101 }
102
103 public enum RegistrationType
104 {
105 Attending,
106 NotAttending
107 }
108
109 /// <summary>
110 /// The domain object for an Event
111 /// </summary>
112 public class Event : domainModelExample.Data.DomainObjectBase
113 {
114 private string _title;
115 private RegistrationCollection _registrations;
116
117 /// <summary>
118 /// Gets or sets the title for this event
119 /// </summary>
120 public string Title
121 {
122 get
123 {
124 return this._title;
125 }
126 set
127 {
128 this._title = value;
129 }
130 }
131
132 /// <summary>
133 /// Gets the registrations for this event
134 /// </summary>
135 public RegistrationCollection Registrations
136 {
137 get
138 {
139 if (this._registrations == null)
140 this._registrations = new RegistrationCollection();
141
142 return this._registrations;
143 }
144 }
145 }
146
147 /// <summary>
148 /// A collection of registration
149 /// </summary>
150 public class RegistrationCollection : System.Collections.Generic.List
151 {
152
153 }
154 }
Business Layer (Middle Layer)
1 namespace domainModelExample.Business
2 {
3 public class PersonManager
4 {
5 /// <summary>
6 /// Saves a person's information
7 /// </summary>
8 /// <param name="person">The newly created person</param>
9 public void SavePerson(Person person)
10 {
11 //TODO: Check that the person is not null
12 //TODO: Check that the person is validated correctly
13
14 //Get the service provider for the registration domain object
15 domainModelExample.Data.IService personService = (domainModelExample.Data.IService)domainModelExample.Data.ServiceFactory.GetService(typeof(Person));
16
17 //If new, add the person; otherwise update
18 if (person.IsNew)
19 personService.Add(person);
20 else
21 personService.Update(person);
22 }
23 }
24
25 public class RegistrationManager
26 {
27 public void SaveRegistration(Registration registration)
28 {
29 //TODO: Check that the registration is not null
30 //TODO: Check that the registration is validated correctly
31
32 //save the person
33 (new PersonManager()).SavePerson(registration.Person);
34
35 //TODO: save the event
36
37 //Get the service provider for the registration domain object
38 domainModelExample.Data.IService registrationService = (domainModelExample.Data.IService)domainModelExample.Data.ServiceFactory.GetService(typeof(Registration));
39
40 //If the object is new, add it; otherwise update it
41 if (registration.IsNew)
42 registrationService.Add(registration);
43 else
44 registrationService.Update(registration);
45 }
46 }
47 }
Data Access Layer
1 namespace domainModelExample.Data
2 {
3 public abstract class DomainObjectBase
4 {
5 private int _id = DomainObjectBase.EmptyId;
6 private bool _isNew = true;
7
8 /// <summary>
9 /// Creates a new domain object
10 /// </summary>
11 public DomainObjectBase() { }
12
13 /// <summary>
14 /// Creates a domain object that is existing
15 /// </summary>
16 /// <param name="id">The unique ID of the existing domain object</param>
17 public DomainObjectBase(int id)
18 {
19 //TODO: Make sure the id is of valid value
20
21 this.Id = id;
22 this.IsNew = false;
23 }
24
25 /// <summary>
26 /// Gets the unique ID for this object
27 /// </summary>
28 public int Id
29 {
30 get
31 {
32 return this._id;
33 }
34 private set
35 {
36 this._id = value;
37 }
38 }
39
40 /// <summary>
41 /// Gets the value for an empty ID
42 /// </summary>
43 public static int EmptyId
44 {
45 get
46 {
47 return -1;
48 }
49 }
50
51 /// <summary>
52 /// Gets or sets whether this object is new
53 /// </summary>
54 internal bool IsNew
55 {
56 get
57 {
58 return this._isNew;
59 }
60 set
61 {
62 this._isNew = value;
63 }
64 }
65 }
66
67 /// <summary>
68 /// Service interface for a domain object (business entity)
69 /// </summary>
70 /// <typeparam name="TDObject">The domain object type</typeparam>
71 public interface IService
72 where TDObject : DomainObjectBase
73 {
74 void Add(TDObject dobject);
75 void Update(TDObject dobject);
76 void Delete(TDObject dobject);
77 }
78
79 /// <summary>
80 /// Service interface specifically for the person domain object
81 /// </summary>
82 public interface IPersonService : IService
83 {
84
85 }
86
87 /// <summary>
88 /// Person domain object service provider for the database
89 /// </summary>
90 internal class PersonServiceDb : IPersonService
91 {
92 /// <summary>
93 /// Adds a person to the database
94 /// </summary>
95 /// <param name="person">The person to be added to the database</param>
96 public void Add(Person person)
97 {
98 //Check person domain object isn't null
99 //Execute "Insert" stored procedure with person values
100 //Get output parameter for the new person's unique ID and save it in the domain object
101 }
102
103 /// <summary>
104 /// Updates the person object in the database
105 /// </summary>
106 /// <param name="person"></param>
107 public void Update(Person person)
108 {
109 //Check person domain object isn't null
110 //Execute "Update" stored procedure with person values
111 }
112
113 /// <summary>
114 /// Deletes the person object in the database
115 /// </summary>
116 /// <param name="person"></param>
117 public void Delete(Person person)
118 {
119 //Check to make sure the person isn't null
120 //Execute the "Delete" stored procedure
121 }
122 }
123
124 /// <summary>
125 /// Main interface for other layers to access the services for a domain object
126 /// </summary>
127 public static class ServiceFactory
128 {
129 /// <summary>
130 /// Gets the service object for the specified domain object type
131 /// </summary>
132 /// <param name="domainObjectType">The type of domain object to get a service for</param>
133 /// <returns></returns>
134 public static object GetService(Type domainObjectType)
135 {
136 if (domainObjectType == typeof(Person))
137 return new PersonServiceDb();
138
139 //Throw a more specific exception - omitted in example
140 throw new Exception();
141 }
142 }
143 }
Conclusion
The example above is a fictious example written in under 30 minutes, so its far from complete.