C# (OOP) Nested Business Objects - c#

I received the following email today from a co-worker. My question is this accurate. Nesting Business Objects is bad practice? Can anyone shine in on this?
Nested Objects
When any variable is created within C# it takes up a piece of memory on the Web Server. Since we will have many tools running on the same server, it is even more important to ensure we are not creating objects if we don't plan on using them.
Using the second employee object above as an example… If we also needed to know the employees Supervisor ID.. (and that was all the tool was populating and using) we would want to ensure the Employee class contains the appropriate information, along with taking into consideration Memory and Processes in the tool.
We would add the 'supervisorId' string variable to the Employee class, and add the appropriate Getters and Setters.
On the flip side, we would want to shy away from nesting another object within the employee object. Such as:
public class Employee {
private string firstName;
private string lastName;
private string empId;
private Employee supervisor;
public string FirstName {
get { return firstName; }
set { firstName = value; }
}
public string LastName {
get { return lastName; }
set { lastName = value; }
}
public string EmpId {
get { return empId; }
set { empId = value; }
}
public Employee Supervisor{
get { return supervisor; }
set { supervisor = value; }
}
}
In this case we may not always use the values within the 'Supervisor' instance of the Employee object, but the variables are created in memory. This can have a potentially catastrophic effect on performance.
There are 'some' cases where nesting of objects is necessary:
Example: (Category :: Question) Where each category could have an array list of questions assigned to it.

The short answer to your general question of
Is it bad to nest business objects?
is no.
The long answer is that is sounds like your team is suffering from premature optimization. You need to design your business objects to mirror your business domain. All the behaviors in your business domain should be exemplified in your business layer. Once you've achieved that goal, you can then do performance testing. Actually measure what parts of your system is too slow, and then optimize those parts. Don't get caught up in preoptimizing your business logic before you've even had a chance to get it laid out.
Design and implement, then performance test and then optimize when you find unacceptable slowness.

My opinion is that you should nest only when you'll be routinely calling a method on the nested object.
If all you will do with the nested object is to get some properties of it, then you shouldn't have it nested and should store the properties directly.

It appears from your code sample that you're setting the supervisor Employee object externally (i.e. through the property setter), so I think this design is OK. If you were automatically instantiating the supervisor object (by, say, hitting the database) every time you created the "outer" Employee object, you would have a potential problem.

I believe the following Business Object (Data Transfer Objects) sparked the email:
/// <summary>
/// Manufacturer Data Transfer Object
/// </summary>
public class MfgBO {
public int Id { get; set; }
public string Name { get; set; }
public bool Active { get; set; }
}
}
public class TypeBO {
public int Id { get; set; }
public string Name { get; set; }
public bool Active { get; set; }
}
public class ModelBO {
#region Private Variables
private int mmtId = -1;
private int id = -1;
private string name = String.Empty;
private bool active = false;
private MfgBO mfg = new MfgBO();
private TypeBO type = new TypeBO();
#endregion
// Getter and setters below
Looking at this the ModelBO holds the MfgBO and a TypeBO because a model cannot be complete without the info. What he is recommending is in the ModelBO instead of having MfgBO or TypeBO, we should have a variable of int MakeID, string MakeName, int DeviceTypeId, string DeviceTypeName, etc, basically retyping fields that already exist in MfgBO and TypeBO objects.
To my limited OOP knowledge it makes more sense to use the MfgBO and TypeBO. Which is better way for my own personal knowledge? Is having the MfgBO and TypeBO in MakeBO will actually use more memory and "potentially crash the server"?

You could create the object only if you explicitly access it.
public BusinessObject Item
{
get
{
if (_Item == null)
_Item = new BusinessObject();
return _Item;
}
}
private BusinessObject _Item;

Related

C# data model, are there any differences between using these form?

I'm going to build my MVC Web Application and I created my data models.
I found online many ways to compile a data model code. This is easiest one, using only public properties:
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
But I also found a version using a private variable and a public properies, like this:
public class Person
{
private int id;
private string firstName;
private string lastName;
public int Id { get { return id; } set { id = value; } }
public string FirstName { get { return firstName; } set { firstName = value; } }
public string LastName { get { return lastName; } set { lastName = value; } }
}
What is the difference between these two data models?
When is more advisable using the first one or the second one?
This is the same like asking: what is a difference bwteen auto properties and normal properties.
Auto properties:
easy creation (less to type)
internal field is generated for you automatically by compiler
Not possible to debug (set a break point inside the property)
Normal properties
Sligtly more code to type
Easy to debug
More code can be injected inside get and set
If first example compiler will create private field for every automatic property itself, but they behave exactly the same. More info on MSDN
I would suggest second approach as you have more control how property works, but there is nothing wrong in using first one.
The fiest block you have are auto-properties, and under the hood the c# will be compiled similar to the second block, so in this case there is no difference. Take a look at these posts here:
C# 3.0 auto-properties - useful or not?
What are Automatic Properties in C# and what is their purpose?
Any reason to use auto-implemented properties over manual implemented properties?
If you were implementing the INotifyPropertyChanged interface, then you would need to use the traditional way as you would be interacting with the property in the setter, see example...
http://msdn.microsoft.com/en-us/library/ms743695.aspx

how to configure class for mongo de/serialization

I have a class:
class Product
{
public String Name { get; private set; }
private List<Release> releases;
private List<Area> areas;
public List<Release> Releases
{
get
{
return new List<Release>(releases);
}
private set
{
releases = value
}
}
public List<Area> Area
{
get
{
return new List<Area>(areas);
}
private set
{
areas = value
}
}
public Product(String Name)
{
this.Name = Name;
this.Releases = new List<Release>();
this.Areas = new List<Area>();
}
public Product(String Name, List<Release> Releases, List<Area> Areas)
{
this.Name = Name;
this.Releases = Releases;
this.Areas = Areas;
}
}
My understanding is that Mongodb bson serializer will not be able to automatically de/serialize Product objects because all the properties/fields don't have public read and write access and I do not supply a no argument constructor. How could I go about configuring this to be fully de/serializable ? I have looked into the serialization tutorial on the mongodb.org but it didn't cover this scenario. I also found this https://jira.mongodb.org/browse/CSHARP-476 enhancement but it doesn't look to be implemented yet.
Currently I have another class ProductDoc which has the same field/properties but they have full public read and write access and I supply a no argument constructor so mongodb driver can automapp this type without any problems, and I just convert Product objects to ProductDoc objects and vice versa when I need to read write to the DB. But this seems very hacky even though it is very simple.
UPDATE:
It seems that it does not matter one jot that the set accessors on my public properties are private only that the property itself is public and the lack of a no-argument constructor doesn't seem to affect the de/serialization process either. Can anyone confirm how this works? and whether the info here is correct.
The quickstart tutorial is correct. You can use private getters and setters for those. But, if you are ever concerned, whipping up a test program to try stuff out is always the best answer. The "public" read/write indicates that one of the getters or setters needs to be public.

Conditionally Limit Property Access

Is there a better way to limit access to the Occupation and Employer properties?
This class is simply designed to collect a person's (potential customer's) employment information. EmploymentStatus can be Employed, SelfEmployed, Unemployed, Retired, etc...
I only want users of this class to be able to set Employer and Occupation if the person is indeed employed.
public class EmploymentInformation
{
private const string _EmploymentStatusNotEmployedMessage = "Employment status is not set to employed";
private string _occupation;
private Company _employer;
/// <summary>The person's employment status<example>Employed</example></summary>
public EmploymentStatus EmploymentStatus { get; set; }
/// <summary>The person's occupation<example>Web Developer</example></summary>
public string Occupation
{
get
{
if (IsEmployed)
{
return _occupation;
}
throw new ApplicationException(_EmploymentStatusNotEmployedMessage);
}
set
{
if (IsEmployed)
{
_occupation = value;
}
throw new ApplicationException(_EmploymentStatusNotEmployedMessage);
}
}
/// <summary>The person's employer</summary>
public Company Employer
{
get
{
if (IsEmployed)
{
return _employer;
}
throw new ApplicationException(_EmploymentStatusNotEmployedMessage);
}
set
{
if (IsEmployed)
{
_employer = value;
}
throw new ApplicationException(_EmploymentStatusNotEmployedMessage);
}
}
private bool IsEmployed
{
get
{
return EmploymentStatus == EmploymentStatus.Employed
|| EmploymentStatus == EmploymentStatus.SelfEmployed;
}
}
/// <summary>
/// Constructor for EmploymentInformation
/// </summary>
/// <param name="employmentStatus">The person's employment status</param>
public EmploymentInformation(EmploymentStatus employmentStatus)
{
EmploymentStatus = employmentStatus;
}
}
Anything wrong with simply returning null if the value is not set? That's fairly common practice. If Employer does not exist it's value is null. Why it's null may not be relevant. In addition force the employment status to be set within the ctor of the class itself.
Forcing developers to set properties in a particular order is a dangerous design: it makes the interface misleading and encourages mistakes.
Instead, consider making EmploymentInformation objects immutable:
// Constructor for retired / unemployed people
public class EmploymentInformation(EmploymentStatus status) {}
// Constructor for self-employed people - we know their status
public class EmploymentInformation(string occupation) {}
// Constructor for people employed by others - we know their status
public class EmploymentInformation(string occupation, Company employer) {}
public bool IsEmployed { get; }
public string Occupation { get; }
public Company Employer { get; }
Firstly, why is it possible to construct an object of EmploymentInformation if there is no Employer?
As far as possible, you should not allow an object to be constructed in an invalid state. You can express these constraints in the constructor of your object either using Guard Clauses or Code Contracts.
public class EmploymentInformation
{
public EmoloymentInformation(Employer employerInstance)
{
if(employerInstance == null)
throw new ArgumentNullException();
}
Secondly, you can use the Null Object pattern so that you don't have to throw exceptions. Just create appropriate class for EmptyEmployer and return them as shown below.
public Company Employer
{
get
{
return IsEmployed ? _employer : Employer.Empty;
// Employer.Empty is static property which return an instance of EmptyEmployer just like string.Empty.
}
A new answer:
Given that the object is strictly to hold data regarding the users CURRENT employement status, it's still wrong.
As #Jeff Sternal said you shouldn't force dev's to assign parameters based on a particular order. In the event the object needs to be serialized/deserialized you could end up with a lot of errors.
Instead you should provide a validation function. Something like bool IsValid(); When that method is called perform the business logic validation to ensure that the object is in an acceptable state. You could have it simply return a false if not, throw an exception (please don't), or have it send a status code back as to why the object is not currently valid.
Typically you throw data into an object THEN you validate the object is good prior to persistence. The above is just one way of doing this. Others include having a Business Logic library which separates the logic completely from the data classes (personally, I never understood why you'd do this, but a lot of people swear by it.).
I've not had any experience in this, but somewhere I would consider looking is in Code Contracts.
Have a look at these links:
http://social.msdn.microsoft.com/Forums/en/codecontracts/thread/1ca2d371-4b85-479d-9e00-64c84e372f02
http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx
You can decorate your properties with "requirements" suitable to your application. Looks cool to use, and it appears to be half integrated into the IDE.
This looks wrong from a logic perspective.
The object is called "EmploymentInformation" and has a property called "EmploymentStatus"
This seems to either allow for situations where the employmentinformation deals with active or term'd employees; or, to allow for employment history.
If either of those are true, then it seems to me that you can have an Occupation but have an EmploymentStatus of something like "NotEmployed" for whatever reason.
After all, let's see the record is initially created where the EmploymentStatus is employed. Then later the status is changed to "NotEmployed" The next time you go to load the object you are going to lose data.
If you were being strict you might argue that an unemployed person does not have an occupation or employer, so a person object should not have these properties. That leads to something like this.
class Person
{
public EmploymentStatus EmploymentStatus { get; set; }
}
class EmployedPerson : Person
{
public string Occupation { get; set; }
public Company Employer { get; set; }
}
However in practice this unforgiving object model will be cumbersome to work with as you will need to know whether or not a person is employed before you can instantiate an object. It will also be difficult to change between being employed and unemployed as you will have to create a new object and copy everything across.
The clinical distinction isn't worth it. I think it's just as correct and in fact more logical to ask an unemployed person who their employer is and for them to reply with "I haven't got one" rather than be unable to ask the question in the first place.
For me, this would be a more flexible person class.
class Person
{
public Person()
{
this.EmploymentStatus = EmploymentStatus.Unemployed;
}
public void Hire(Company employer, string occupation)
{
this.Occupation = occupation;
this.Employer = employer;
this.EmploymentStatus = EmploymentStatus.Employed;
}
public void Fire()
{
this.Occupation = null;
this.Employer = null;
this.EmploymentStatus = EmploymentStatus.Unemployed;
}
public EmploymentStatus EmploymentStatus { get; private set; }
public string Occupation { get; private set; }
public Company Employer { get; private set; }
}

DDD: Enum like entities

I have the following DB model:
**Person table**
ID | Name | StateId
------------------------------
1 Joe 1
2 Peter 1
3 John 2
**State table**
ID | Desc
------------------------------
1 Working
2 Vacation
and domain model would be (simplified):
public class Person
{
public int Id { get; }
public string Name { get; set; }
public State State { get; set; }
}
public class State
{
private int id;
public string Name { get; set; }
}
The state might be used in the domain logic e.g.:
if(person.State == State.Working)
// some logic
So from my understanding, the State acts like a value object which is used for domain logic checks. But it also needs to be present in the DB model to represent a clean ERM.
So state might be extended to:
public class State
{
private int id;
public string Name { get; set; }
public static State New {get {return new State([hardCodedIdHere?], [hardCodeNameHere?]);}}
}
But using this approach the name of the state would be hardcoded into the domain.
Do you know what I mean? Is there a standard approach for such a thing? From my point of view what I am trying to do is using an object (which is persisted from the ERM design perspective) as a sort of value object within my domain. What do you think?
Question update:
Probably my question wasn't clear enough.
What I need to know is, how I would use an entity (like the State example) that is stored in a database within my domain logic. To avoid things like:
if(person.State.Id == State.Working.Id)
// some logic
or
if(person.State.Id == WORKING_ID)
// some logic
Your proposed structure seems fine. (Terminology digression: since State has an ID, it's not a Value Object, but rather an Entity.)
Enums are a code smell, so don't attempt to go that route. It's much more object-oriented to move the behavior into the State object using the State pattern.
Instead of having to write
if (person.State == State.Working)
// do something...
all over your code, this would allow you to write
person.State.DoSomething();
That's much cleaner, and will allow you to add new States if need be.
A previous question of mine unearthed some useful links that I suspect are pertinent to your question, in particular Jimmy Bogard's discussions of Enumeration Classes.
It's a common practice to include an 'Unknown' element with value 0 in an enum. You can do this and use it for the New state if you really want to.
But what you are describing is business logic... setting a state after creating a new object should then happen in the business logic layer, not inside the class itself.
You want to create a factory method that will instantiate the appropriate state class needed, based on the value stored.
something like
public static State GetStateByID( StateEnum value)
{
if(value.Invalid)
throw new Exception();
switch(value)
case State.Working
return new WorkingState();
case State.somethingelse
return new somethingelseState();
case State.something
return new somethingState();
case State.whatever
return new whateverState();
}
When using enums always try to use 0 as Invalid. Under the hood an enum is a value type, and an unassigned int is always 0.
It is common to use a factory, such as this, in conjunction with the state pattern.
So when you read your stored integer value from the database you can cast the int to the enum and call the factory with it to get the appropriate State object.
I personally think it's a mistake to program against IDs. Instead, I would amend your table to the following:
**State table**
ID | Desc | IsWorking | IsVacation
-----------------------------------------------------------
1 Working True False
2 Vacation False True
I would then use these attributes to make business decisions on such as:
public void MakeDecisionOnState(State state)
{
if (state.IsVacation)
DoSomething();
if (state.IsWorking)
DoSomethingElse();
}
Or by being even more clever, use the factory pattern to create the correct instance based on these attributes:
public abstract class State
{
public Guid Id { get; set; }
public string Description { get; set; }
public abstract void DoSomething();
}
public class WorkingState : State
{
public override void DoSomething()
{
//Do something specific for the working state
}
}
public class VacationState : State
{
public override void DoSomething()
{
//Do something specific for the vacation state
}
}
public class StateFactory
{
public static State CreateState(IDataRecord record)
{
if (record.GetBoolean(2))
return new WorkingState { Id = record.GetGuid(0), Description = record.GetString(1) };
if (record.GetBoolean(3))
return new VacationState { Id = record.GetGuid(0), Description = record.GetString(1) };
throw new Exception("Data is screwed");
}
}
Now you've eliminated the if/switch statement, and your code could simply be:
state.DoSomething();
The reason why I do this is that often these types of entities can be configured by the customer, i.e. they may not want to have some of the states active in the system, or they may wish to term them something else. By programming against the attributes the customer can delete / edit the records as they please and even if that process generates new ID's it doesn't affect the system, they just need to set the attributes.
In my opion the domain layer has to be seperated from the DB model / ERM design. I had trouble understanding your final suggestion for the State class. IMHO this is not a good thing for establishing a common language which is one of the main purposes of DDD.
I would go for a simpler design. The state belongs to the Person class. I would include it in the class.
public class Person
{
public int Id { get; }
public string Name { get; set; }
public PersonState State { get; set; }
}
The state itself seems to have defined values (I assume a person is an employee in your context) which don't change very often. So I would model it as enum and treat it as a data type.
enum Days {Working, Vacation};
This is a simple to understand design in my opinion. The mapping to the ERM design belongs IMHO in the persistence layer. There the enum has to be mapped to the key of the state table. This could be done using an aspect to keep the original domain model clean.

"const correctness" in C#

The point of const-correctness is to be able to provide a view of an instance that can't be altered or deleted by the user. The compiler supports this by pointing out when you break constness from within a const function, or try to use a non-const function of a const object. So without copying the const approach, is there a methodology I can use in C# that has the same ends?
I'm aware of immutability, but that doesn't really carry over to container objects to name but one example.
I've come across this issue a lot of times too and ended up using interfaces.
I think it's important to drop the idea that C# is any form, or even an evolution of C++. They're two different languages that share almost the same syntax.
I usually express 'const correctness' in C# by defining a read-only view of a class:
public interface IReadOnlyCustomer
{
String Name { get; }
int Age { get; }
}
public class Customer : IReadOnlyCustomer
{
private string m_name;
private int m_age;
public string Name
{
get { return m_name; }
set { m_name = value; }
}
public int Age
{
get { return m_age; }
set { m_age = value; }
}
}
To get the benefit of const-craziness (or pureness in functional programming terms), you will need to design your classes in a way so they are immutable, just like the String class of c# is.
This approach is way better than just marking an object as readonly, since with immutable classes you can pass data around easily in multi-tasking environments.
I just wanted to note for you that many of the System.Collections.Generics containers have an AsReadOnly method which will give you back an immutable collection.
C# doesn't have such feature. You can pass argument by value or by reference. Reference itself is immutable unless you specify ref modifier. But referenced data isn't immutable. So you need to be careful if you want to avoid side effects.
MSDN:
Passing Parameters
Interfaces are the answer, and are actually more powerful than "const" in C++. const is a one-size-fits-all solution to the problem where "const" is defined as "doesn't set members or call something that sets members". That's a good shorthand for const-ness in many scenarios, but not all of them. For example, consider a function that calculates a value based on some members but also caches the results. In C++, that's considered non-const, although from the user's perspective it is essentially const.
Interfaces give you more flexibility in defining the specific subset of capabilities you want to provide from your class. Want const-ness? Just provide an interface with no mutating methods. Want to allow setting some things but not others? Provide an interface with just those methods.
Agree with some of the others look at using readonly fields that you initialize in the constructor, to create immutable objects.
public class Customer
{
private readonly string m_name;
private readonly int m_age;
public Customer(string name, int age)
{
m_name = name;
m_age = age;
}
public string Name
{
get { return m_name; }
}
public int Age
{
get { return m_age; }
}
}
Alternatively you could also add access scope on the properties, i.e. public get and protected set?
public class Customer
{
private string m_name;
private int m_age;
protected Customer()
{}
public Customer(string name, int age)
{
m_name = name;
m_age = age;
}
public string Name
{
get { return m_name; }
protected set { m_name = value; }
}
public int Age
{
get { return m_age; }
protected set { m_age = value; }
}
}
The const keyword can be used for compile time constants such as primitive types and strings
The readonly keyword can be used for run-time constants such as reference types
The problem with readonly is that it only allows the reference (pointer) to be constant. The thing referenced (pointed to) can still be modified. This is the tricky part but there is no way around it. To implement constant objects means making them not expose any mutable methods or properties but this is awkward.
See also Effective C#: 50 Specific Ways to Improve Your C# (Item 2 - Prefer readonly to const.)

Categories