Take the 2-minute tour ×

What advice/suggestions/guidance would you provide for designing a class that has upwards of 100 properties?


  • The class describes an invoice. An invoice can have upwards of 100 attributes describing it, i.e. date, amount, code, etc...
  • The system we are submitting the invoice to uses each of the 100 attributes and is submitted as a single entity (as opposed to various parts being submitted at different times).
  • The attributes describing the invoice are required as part of the business process. The business process can not be changed.


  • What have others done when faced with designing a class that has 100 attributes? i.e., create the class with each of the 100 properties?
  • Somehow break it up (if so, how)?
  • Or is this a fairly normal occurrence in your experience?

EDIT After reading through some great responses and thinking about this further, I don't think there really is any single answer for this question. However, since we ended up modeling our design along the lines of LBrushkin's Answer I have given him credit. Albeit not the most popular answer, LBrushkin's answer helped push us into defining several interfaces which we aggregate and reuse throughout the application as well as a nudged us into investigating some patterns that may be helpful down the road.

share|improve this question
How are you serializing/deserializing the objects - do you store them in a database? Are you using WCF? –  Philip Wallace Oct 27 '09 at 19:48
@Philip - the data is stored in a combination of SharePoint and SQL Server. No WCF. All submission of data is done between internal systems where the end point takes an Excel spreadsheet of the data (no other options with the system). –  Metro Smurf Oct 27 '09 at 19:55
Are you actually dealing with all (or most) of those properties in your code? Or is it just a data structure that "passes through" it - read from some input in a generic fashion, just to be output to some other existing software that implements your business process? –  Pavel Minaev Oct 27 '09 at 19:57
@Pavel - we are directly editing around 90% of the attributes. –  Metro Smurf Oct 27 '09 at 20:03
It's pretty common to have a denormalized table like an invoice_header that actually has the address and all the customer info from the time it was created. –  dotjoe Oct 27 '09 at 21:51
add comment

17 Answers

up vote 9 down vote accepted

I would imagine that some of these properties are probably related to each other. I would imagine that there are probably groups of properties that define independent facets of an Invoice that make sense as a group.

You may want to consider creating individual interfaces that model the different facets of an invoice. This may help define the methods and properties that operate on these facets in a more coherent, and easy to understand manner.

You can also choose to combine properties that having a particular meaning (addresses, locations, ranges, etc) into objects that you aggregate, rather than as individual properties of a single large class.

Keep in mind, that the abstraction you choose to model a problem and the abstraction you need in order to communicate with some other system (or business process) don't have to be the same. In fact, it's often productive to apply the bridge pattern to allow the separate abstractions to evolve independently.

share|improve this answer
@LBushkin - thank you, re: Bridge Pattern. This is the type of answers I was looking for and will spend some time reading up on it. –  Metro Smurf Oct 27 '09 at 20:11
add comment

You could try to 'normalize' it like you would a database table. Maybe put all the address related properties in an Address class for example - then have a BillingAddress and MailingAddress property of type Address in your Invoice class. These classes could be reused later on also.

share|improve this answer
@Philip - sadly the data doesn't really subclass into tidy segments. Although there is the possibility of breaking some parts down... hmmm... will take another look. Thanks. –  Metro Smurf Oct 27 '09 at 19:58
I agree. Try to break up the data into smaller parts. 100 properties on a class is out of control. –  Chuck Conway Oct 27 '09 at 21:32
Also, what about having a generic List<Property> to hold all the properties? –  RCIX Nov 2 '09 at 11:49
add comment

The bad design is obviously in the system you are submitting to - no invoice has 100+ properties that cannot be grouped into a substructure. For example an invoice will have a customer and a customer will have an id and an address. The address in turn will have a street, a postal code, and what else. But all this properties should not belong directly to the invoice - an invoice has no customer id or postal code.

If you have to build an invoice class with all these properties directly attached to the invoice, I suggest to make a clean design with multiple classes for a customer, an address, and all the other required stuff and then just wrap this well designed object graph with a fat invoice class having no storage and logic itself just passing all operations to the object graph behind.

share|improve this answer
@Daniel - yes! you've nailed it, re: the internal system we submit to is the bottleneck. –  Metro Smurf Oct 27 '09 at 20:02
@Metro: that doesn't mean your object model has to suffer, just the part that submits it to the internal system needs to be ugly. –  Austin Salonen Oct 27 '09 at 22:01
Sounds like something similar to an adapter - you have your own object model, nicely broken into small classes, and one ugly class where you shove them so that it looks to the internal system as one giant class with 100 properties... –  Mathias Oct 28 '09 at 1:13
add comment

Hmmm... Are all of those really relevant specifically, and only to the invoice? Typically what I've seen is something like:

class Customer:

class Address

class CustomerAddress
.AddressDescription ("ship","bill",etc)

class Order

class OrderDetails

And tying it all together:

class Invoice

When printing the invoice, join all of these records together.

If you really must have a single class with 100+ properties, it may be better to use a dictionary

Dictionary<string,object> d = new Dictionary<string,object>();
d.Add("ShipAddress","1600 Pennsylvania Ave, Suite 0, Washington, DC 00001");

The idea here is to divide your into logical units. In the above example, each class corresponds to a table in a database. You could load each of these into a dedicated class in your data access layer, or select with a join from the tables where they are stored when generating your report (invoice).

share|improve this answer
What benefits will Dictionary give here, exactly, except for more clumsy syntax and lack of type safety? –  Pavel Minaev Oct 27 '09 at 19:56
Well, a typed dictionary wouldn't cause lack of type safety. Also, as I've said, normalizing the data is a much better way to go. Using a dictionary, though, is far more expedient than declaring a class with 100+ properties. I've NEVER seen an instance where that was necessary, or desirable. –  David Lively Oct 27 '09 at 19:59
@ztech - I can't see a dictionary being a viable solution if you have properties of differening types. Then you would have to store them as type Object. As Pavel said, this will quickly lead to type safety, for example when I put "foo" into InvoiceDate. –  Philip Wallace Oct 27 '09 at 20:15
Like I said, I don't think a dictionary is a good idea. But it's comparably bad to creating a class with 100+ properties. Choose your insanity. –  David Lively Oct 27 '09 at 20:46
Why is d.Get("Address_Line_1") better than inv.AddressLine[0]? Also in any reasoable business app you would probably have a good deal of validation rules for each field and the class as a whole. You end up with a humungous mess if you implement with a dictionary. –  James Anderson Oct 28 '09 at 10:47
show 1 more comment

It would be too many columns when your class / table that you store it in starts to violate the rules of normalization.

In my experience, it has been very hard to get that many columns when you are normalizing properly. Apply the rules of normalization to the wide table / class and I think you will end up with fewer columns per entity.

share|improve this answer
add comment

Unless your code actually uses many of the attributes at many places, I'd go for a dictionary instead.

Having real properties has its advantages(type-safety, discoverability/intellisense, refactorability) but these don't matter if all the code does is gets these from elsewhere, displays on UI, sends in a web-service, saves to a file etc.

share|improve this answer
@zvolkov - around 90% of the attributes are editable by the processors and is used throughout the UI. –  Metro Smurf Oct 27 '09 at 19:59
@Metro, that's irrelevant. Are they referenced by the code directly (e.g. Invoice.Subtotal)? If not, you can always marshal between dictionary and textboxes for editing purposes. –  zvolkov Oct 27 '09 at 20:03
@zvolkov - yes, they are directly referenced by the code. I'm not convinced a dictionary is the direction we want to go here; specifically, we would like to have everything strongly typed. –  Metro Smurf Oct 27 '09 at 20:09
But used in what way? This seems very much like a problem for a data driven approach, where rather than have a class you have a definition file that defines all the attributes you support, and metadata about them (like display name). The UI can pull from this dictionary an attribute to edit, from which it can get a display name, and a means to get the current value and to set new updated/new values. –  Kendall Helmstetter Gelner Oct 27 '09 at 20:10
I think also, in general you are way too hung up on the static typing. If you want the ultimate in typing it involves, well, a lot of typing - as in 100 attributes defined in a class. For things like this a more flexible middle ground where you get some type checking at points but not 100%, is going to be so much easier to work with that the gains over any type mismatch issues will be huge. –  Kendall Helmstetter Gelner Oct 27 '09 at 20:14
show 3 more comments

It's considered bad O-O style, but if all you're doing is populating an object with properties to pass them onward for processing, and the processing only reads the properties (presumably to create some other object or database updates), them perhaps a simple POD object is what you need, having all public members, a default constructor, and no other member methods. You can thus treat is as a container of properties instead of a full-blown object.

share|improve this answer
I agree, it may not be good O-O, but it's a better solution than a dictionary for this situation. –  Ash Oct 28 '09 at 1:19
@Loadmaster - some of the properties are initially populated. They are then updated as needed and stored until ready to be sent off to the consuming system. I'm going to update the question with a bit more background (may be later tonight or tomorrow). –  Metro Smurf Oct 28 '09 at 1:37
add comment

I used a Dictionary < string,string > for something like this.

it comes with a whole bunch of functions that can process it, it's easy to convert strings to other structures, easy to store, etc.

share|improve this answer
... not statically typed, not type-safe in general, non-refactoring-friendly, not idiomatic C#, etc. –  Pavel Minaev Oct 27 '09 at 19:55
but it'll definitely get you laid. –  Oren Mazor Oct 27 '09 at 19:59
Great you can now apply the Calculate_Sales_Tax method to the Zip code. –  James Anderson Oct 28 '09 at 1:34
add comment

You might find some useful ideas in this article about properties by Steve Yegge called the Universal Design Pattern.

share|improve this answer
add comment

You should not be motivated purely by aesthetic considerations.

Per your comments, the object is basically a data transfer object consumed by a legacy system that expects the presence of all the fields.

Unless there is real value in composing this object from parts, what precisely is gained by obscuring its function and purpose?

These would be valid reasons:

1 - You are gathering the information for this object from various systems and the parts are relatively independent. It would make sense to compose the final object in that case based on process considerations.

2 - You have other systems that can consume various sub-sets of the fields of this object. Here reuse is the motivating factor.

3 - There is a very real possibility of a next generation invoicing system based on a more rational design. Here extensibility and evolution of the system are the motivating factor.

If none of these considerations are applicable in your case, then what's the point?

share|improve this answer
@alphazero - I'm not sure I follow. But, to answer: 1=true, 2=possibly, but not now, 3 is unlikely in the coming years. Can you expand on your answer? –  Metro Smurf Oct 28 '09 at 1:29
In that case it makes sense to compose the object of parts. You can partition based on scenarios 1 or 2, depending on which is the stronger motivation. –  alphazero Oct 28 '09 at 1:43
add comment

It sounds like for the end result you need to produce an invoice object with around 100 properties. Do you have 100 such properties in every case? Maybe you would want a factory, a class that would produce an invoice given a smaller set of parameters. A different factory method could be added for each scenario where the relevant fields of the invoice are relevant.

share|improve this answer
@Frank - In our case we will be consuming most of the properties. The other properties are derived from what we consume. –  Metro Smurf Oct 28 '09 at 1:33
add comment

If what you're trying to create is a table gateway for pre-existing 100-column table to this other service, a list or dictionary might be pretty quick way to get started. However if you're taking input from a large form or UI wizard, you're probably going to have to validate the contents before submission to your remote service.

A simple DTO might look like this:

class Form
    public $stuff = array();
    function add( $key, $value ) {}

A table gateway might be more like:

class Form
    function findBySubmitId( $id ) {} // look up my form
    function saveRecord() {}       // save it for my session
    function toBillingInvoice() {} // export it when done

And you could extend that pretty easily depending on if you have variations of the invoice. (Adding a validate() method for each subclass might be appropriate.)

class TPSReport extends Form { 
    function validate() {}

If you want to separate your DTO from the delivery mechanism, because the delivery mechanism is generic to all your invoices, that could be easy. However you might be in a situation where there is business logic around the success or failure of the invoice. And this is where I'm prolly going off into the weeds. But it's where and OO model can be useful...I'll wage a penny that there will be different invoices and different procedures for different invoices, and if invoice submission barfs, you'll need extra routines :-)

class Form { 
    function submitToBilling() {}
    function reportFailedSubmit() {}
    function reportSuccessfulSubmit() {}
class TPSReport extends Form { 
    function validate() {}
    function reportFailedSubmit() { /* oh this goes to AR */ }

Note David Livelys answer: it is a good insight. Often, fields on a form are each their own data structures and have their own validation rules. So you can model composite objects pretty quickly. This would associate each field type with its own validation rules and enforce stricter typing.

If you do have to get further into validation, often business rules are a whole different modelling from the forms or the DTOs that supply them. You could also be faced with logic that is oriented by department and has little to do with the form. Important to keep that out of the validation of the form itself and model submission process(es) separately.

If you are organizing a schema behind these forms, instead of a table with 100 columns, you would probably break down the entries by field identifiers and values, into just a few columns.

table FormSubmissions (
    id         int
    formVer    int -- fk of FormVersions
    formNum    int -- group by form submission
    fieldName  int -- fk of FormFields
    fieldValue text
table FormFields (
    id         int
    fieldName  char
table FormVersions (
select s.* f.fieldName from FormSubmissions s
left join FormFields f on s.fieldName = f.id
where formNum = 12345 ;

I would say this is definitely a case where you're going to want to re-factor your way around until you find something comfortable. Hopefully you have some control over things like schema and your object model. (BTW...is that table known a 'normalized'? I've seen variations on that schema, typically organized by data type...good?)

share|improve this answer
add comment

Do you always need all the properties that are returned? Can you use projection with whatever class is consuming the data and only generate the properties you need at the time.

share|improve this answer
sounds a little cryptic? example plz? –  zvolkov Oct 27 '09 at 20:35
add comment

You could try LINQ, it will auto-gen properties for you. If all the fields are spread across multiple tables and you could build a view and drag the view over to your designer.

share|improve this answer
add comment

Dictionary ? why not, but not necessarily. I see a C# tag, your language has reflection, good for you. I had a few too large classes like this in my Python code, and reflection helps a lot :

for attName in 'attr1', 'attr2', ..... (10 other attributes):
    setattr( self, attName, process_attribute( getattr( self, attName ))

When you want to convert 10 string members from some encoding to UNICODE, some other string members shouldn't be touched, you want to apply some numerical processing to other members... convert types... a for loop beats copy-pasting lots of code anytime for cleanliness.

share|improve this answer
add comment

If an entity has a hundred unique attributes than a single class with a hundred properties is the correct thing to do.

It may be possible to split things like addresses into a sub class, but this is because an address is really an entity in itself and easily recognised as such.

A textbook (i.e. oversimplified not usable in the real world) invoice would look like:-

 class invoice:
    int id;
    address shipto_address;
    address billing_address;
    order_date date;
    ship_date date;
    line_item invoice_line[999];

  class line_item;
    int item_no.
    int product_id;
    amt unit_price;
    int qty;
    amt item_cost;

So I am surpised you dont have at least an array of line_items in there.

Get used to it! In the business world an entity can easily have hundreds and sometimes thousands of unique attributes.

share|improve this answer
Not to nit-pick as I know the above is an off-the-cuff answer, but using a statically-sized array to hold line items is a bad idea. Better to use List<line_item> in C#. –  David Lively Oct 28 '09 at 15:16
add comment

if all else fails, at least split the class to several partial classes to have better readability. it'll also make it easier for the team to work in parallel on different part of this class.

good luck :)

share|improve this answer
add comment

Your Answer


