Since I have been a speaker and a teacher, I have always stressed the importance of practicing proper object-oriented programming (OOP) techniques. If you don’t practice OOP, no matter what language you are using, I guarantee you will end up with a “house of cards” and they all eventually fall.
The first “pillar” of OOP is encapsulation which means the practice of data hiding. No code gets to the data in the type unless it uses properties or methods. As I always say, “bad data in, bad data out”. If that bad data gets saved to a database it could get corrupted, it could upset customers and will cause more work and money to fix it. Is this a good example of OOP coding?
- public class OrderData
- {
- public string ORDER;
- private string wherehouseID = "";
- public string OrderNumber = "";
- public string openClosed = "";
- public string transType = "";
- public string dateOpened = "";
- public string dateClosed = "";
- public string dateShop = "";
- public OrderData(string _ORDER)
- {
- this.ORDER = _ORDER;
- }
- //Code removed for brevity
- }
NO, it is not! This type, currently in production, does not practice good encapsulation since the actual code contains over 198 public string fields! I would say over 90 percent of code I see as a consultant does not even get this first pillar right. The first line of all your properties and methods should be validating the data before proceeding.
To make this easier, always use proper data types since they will help you with validation. If the type needs a date, then use DateTime. If the type needs a URL, then use the Uri type etc. If I had the codebase to the type above, I would have changed it to something like this.
- public class Order
- {
- private ReplacementType _replacementType;
- private OrderType _orderType;
- private DateTime? _closedOn;
- private DateTime? _customerPickupOn;
- private TransactionType _transactionType;
- private DateTime _openedOn;
- private string _orderNumber;
- public string OrderNumber
- {
- get
- {
- return _orderNumber;
- }
- set
- {
- if (string.IsNullOrEmpty(value))
- {
- throw new ArgumentNullException();
- }
- _orderNumber = value;
- }
- }
- public bool IsClosed { get; private set; }
- public TransactionType TransactionType
- {
- get
- {
- return _transactionType;
- }
- set
- {
- if (!System.Enum.IsDefined(typeof(TransactionType), value))
- {
- throw new ArgumentOutOfRangeException();
- }
- _transactionType = value;
- }
- }
- public int EmployeeId { get; set; }
- public DateTime OpenedOn
- {
- get
- {
- return _openedOn;
- }
- set
- {
- if (value <= DateTime.MinValue)
- {
- throw new ArgumentOutOfRangeException();
- }
- _openedOn = value;
- }
- }
- public DateTime? CustomerPickupOn
- {
- get
- {
- return _customerPickupOn;
- }
- set
- {
- if (this.OpenedOn <= DateTime.MinValue)
- {
- throw new ArgumentOutOfRangeException(nameof(OpenedOn));
- }
- if (value < this.OpenedOn)
- {
- throw new ArgumentOutOfRangeException(nameof(CustomerPickupOn), "Value must be the same or later than OpenedOn");
- }
- _customerPickupOn = value;
- }
- }
- public DateTime? ClosedOn
- {
- get
- {
- return _closedOn;
- }
- set
- {
- if (this.OpenedOn <= DateTime.MinValue)
- {
- throw new ArgumentOutOfRangeException(nameof(OpenedOn));
- }
- if (value < this.OpenedOn)
- {
- throw new ArgumentOutOfRangeException(nameof(ClosedOn), "Value must be the same or later than OpenedOn");
- }
- _closedOn = value;
- this.IsClosed = true;
- }
- }
- public OrderType OrderType
- {
- get
- {
- return _orderType;
- }
- set
- {
- if (!System.Enum.IsDefined(typeof(OrderType), value))
- {
- throw new ArgumentOutOfRangeException();
- }
- _orderType = value;
- }
- }
- public ReplacementType ReplacementType
- {
- get
- {
- return _replacementType;
- }
- set
- {
- if (!System.Enum.IsDefined(typeof(ReplacementType), value))
- {
- throw new ArgumentOutOfRangeException();
- }
- _replacementType = value;
- }
- }
- // Code removed for brevity
- }
As you can see in the code above, I’m using the proper data types and even created a few enums. I am also validating all the data coming into the type and if it fails, I throw the proper exception.
If you use proper data types, then I guarantee this will help your team. If you are a Microsoft .NET developer, please be sure to pick up a copy of my coding standards book. Please share comments you might have below.

Mangesh GPosted Apr 16, 2018, 11:40 AM
I will Follow this approach Dave dealing hence forth in our application but with the MVC it will be a good idea to combine with the Data Annotation like Required ?
Don KrausePosted Apr 14, 2018, 5:49 PM
Hi Dave, Would you recommend doing something like this in MVC for properties in a model?
Jefferson S. MottaPosted Apr 10, 2018, 11:29 AM
I desing a system that read the database and create classes: to read/write - with IDE data validation - updates only changed fields, auto regulate the field size (string fields); a pro-active dictionary system (never more I needed remember the exact name of a field); encryptation (xml); static classes to manage data and dictionary; type of field data like zipCode, Address, City, etc.; recycle bin and recycle bin relational; cross-plataform (web/desktop) or .NET Standard; classes to read all relational data in separeted fields (classes); full auditoring (who changed any field, Ip and datetime); using interfaces; and many other things. All this working 10.000x faster than Linq. Nothing goes wrong with data type validation because it validate on compilation time. Sinze y2k I do not have wrong data type mistakes or any field validation troubles in production. Ops, and can be configured to work with Sqlserver, MSAccess, Oracle or MySql, just changing a master class.
Satish Kumar VadlavalliPosted Apr 9, 2018, 6:15 AM
Thanks for sharing :)
Former memberPosted Apr 6, 2018, 8:28 AM
Thank You so much. This information very important for us
imran osmanzaiPosted Mar 19, 2018, 1:34 AM
Thank you Sir that is very interesting for me