Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>When I ponder on these questions I tend to divide code into a few categories. </p> <ul> <li>Application level</li> <li>Internal Framework level</li> <li>Public Api level</li> </ul> <p>On application level, your classes will most often be leaf classes that is designed to implement a very specific feature within your project scope. They are seldom candidates for re-use and the only dependencies on them are other specific classes in the application itself. </p> <p>Here I allow myself some freedom and I would say that a couple of public properties does not hurt anyone. It's all very localized anyway and as application changes, you still need to understand how you code interacts to make any changes to this code. However, freedom does not equal sloppy.</p> <p>On Framework level, I mean subsystems that is highly re-usable between projects. Could be your salt+hash password classes that has been proven to work over the years. Or maybe a wrapper around an entire third-party product you are dependent on in several projects.</p> <p>Once you reference such a assembly or if the the source files are added to your solution, your application can still be seen as the only consumer of that code. But that code still has to be very contained and should promise to adhere to contracts. If public properties allows for objects to have corrupt state I would say it's a pretty lame framework.</p> <p>On Api level things changes drastically. Now you are designing code that are supposed to be used by many subscribers over time. Just not to get confused with terms, the obvious candidate here is .NET Framework itself. But if you are the one providing an api, that people may even pay for with warranty; you really want a stable system that cannot be abused so easily. </p> <p>What I think is interesting (and mildly amusing) is that all the good principles that have come from OOP-purists and SOLID-purists (and other purists), seems to default to the assumption that all their code is in that high-end support api-level. </p> <p>So to answer your question, I'll give you a couple of questions to think about</p> <ul> <li>Will this object change state? </li> <li>Will changes corrupt assumptions other pieces of code have? </li> <li>If so, would any sane use of my objects actually be abused that way? </li> <li>If my objects are insanely abused is this a local bug or a major support issue? </li> <li>What level of protection do I actually need here? </li> <li>How much effort shall I put into it?</li> <li>Does this come with any documentation?</li> </ul> <p>For an explicit example. In a web project I am quite proud of, a lot of data is cached in singletons (static classes really). We do lock correctly to ensure thread-safety on the GetOrSet. Except for one minor detail. We hand out references to the actual objects in our cache to multiple threads. They are mutable and any attempt to write to their public properties could cause all sorts of problems. Now do we clone them? Make them immutable? Take the performance hit of copying these objects so they can cause no harm? Nope. As we are the only consumer of our own caches, we just took a decision that all data coming from a service should be treated as read only. We use Automapper when we do need a copy. And we check up on this during code review. It works very well. While we had a few bugs, none has of yet been caused by writing to a mutable object. </p> <p>Patient: - My legs hurt when I jump like this.</p> <p>Doctor: - Then don't jump like that!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload