I have an Age Value Object
which validates age betweens 2 const ( MinimumAge and MaximumAge )
At some point i want to be able to change this min and max range dynamically
without editing code after project got published ( for example reading it from DB or fetching it from somewhere else... )
How can i do this without breaking DDD rules and be loyal to Value Object Self-Validating ?
I tried few ways but all broke DDD rules at some point
My suggestion is to not treat a value that can change as an invariant.
If you have different, but invariant, age ranges then you may have more than one Age value object that is abstracted behind an interface and the object making use of the value object has some indicator of the AgeType. For example, you may have a RegistrationAge that validates between ages 2-16 and another for VotingAge that validates from 18-anything. However, if the ages may change then they really shouldn't be hard-coded as invariants in the value object. Instead, they may be provided to the value object as parameters that may be defined outside the domain (database, or some other settings, for instance).
It may be that what you are after is more of a Specification, or your Age value object may act as a specification.
Related
Is it possible to indicate a property is a required field without using data annotation attributes?
Instead of using annotation attributes, I want to set it as a required field, based on particular conditions.
For eg, something like below
if (true)
{
//set myObj.Name as required field
}
Edit: The reason why I need to do is, I'm calling a business service class of our own framework, which I can not touch, and inside the class, when the entity is being saved, mandatory checking is already catered.
But, in my requirement, I need to save my entity several times and , each times, the mandatory checking may be different . That's the reason why I need to mark the properties required fields dynamically.
Otherwise, I have to made my own mandatory checking before calling the business service class, which I don't want to do.
From your description, it seems like you need to provide your "own mandatory checking". I say this for two reasons;
To provide your user meaningful feedback as to why something field is required
Also, to satisfy the contract of your business service class
Can you have a "validate" method that simply runs through your set of rules (that mandatory checking, that you mentioned earlier) and have it return a list of strings indicating the rules that were violated on an attempt to save. Then you can use these strings to populate the text of a message box, logfile or whatever to provide meaningful feedback to the user as to why something wasn't saved, and also ensuring that data that is saved, is compliant to your business service class.
Fluent builder is a well-known pattern to build objects with many properties:
Team team = teamBuilder.CreateTeam("Chelsea")
.WithNickName("The blues")
.WithShirtColor(Color.Blue)
.FromTown("London")
.PlayingAt("Stamford Bridge");
However, using it doesn't seem very clear to me due to one particular reason:
Every Team object has its minimal operational state, in other words, set of properties which have to be set (mandatory), so that the object is ready to use.
Now, how should the Fluent builder approach be used considering that you have to maintain this state?
Should the With_XYZ members modify the part of the object, that can't affect this state?
Maybe there are some general rules for this situation?
Update:
If the CreateTeam method should take the mandatory properties as arguments, what happens next?
What happens if I (for example) omit the WithNickName call?
Does this mean that the nickname should be defaulted to some DefaultNickname?
Does this mean that the example (see the link) is bad, because the object can be left in invalid state?
And, well, I suspect that in this case the fluent building approach actually loses it's "beauty", doesn't it?
CreateTeam() should have the mandatory the properties as parameters.
Team CreateTeam(string name, Color shirtColor, string Town)
{
}
Seems to me the points of Fluent Interface are:
Minimize the number of parameters to zero in a constructor while still dynamically initializing certain properties upon creation.
Makes the property/ parameter-value association very clear - in a large parameter list, what value is for what? Can't tell without digging further.
The coding style of the instantiation is very clean, readable, and editable. Adding or deleting property settings with this formatting style is less error prone. I.E. delete an entire line, rather than edit in the middle of a long parameter list; not to mention editing the wrong parameter
This question could be subjective. I'm not sure if it belongs here or on Programmers
Say I have a data type, X (think of business objects constructed from a relational database). My end goal is represent many instances of this type in a table for a report, with each instance under one of a few different headings.
The heading to display the object under is selected based on arbitrary logic handed down from management, which anybody who's done corporate software development will be familiar with:
Examples:
If the instance has a FooID of 6 and a BarFactor of < 0.5, place it under the "Borked" heading.
or
If the Weight is > 0, and the CreatedDate is before Midnight but after 3PM, and today is not the 3rd Wednesday of the month, the object should be categorised as "Fluffy".
My question: Is there a common idiom for taking an instance of X, applying a potentially headache-inducing amount of logic to the state of the instance and getting a category/string/arbitrary value from the result of that logic?
My ideas so far have been:
A function which takes an X and returns a String. I could easily see this turning into a Megamoth, and a b***** to maintain as requirements are constantly modified.
Define a Heading abstract type, and a factory function which gives me an instance of Heading with the ToString method correctly overloaded. I think this technique will be plagued by the same issues as idea no. 1.
A hierarchy of functions, each splitting the problem up a little further until we arrive at the correct heading.
For example:
public String GetHeading(X x)
{
if (x.Weight > 0)
return WeightGreaterThanZero(x);
else if (x.Weight < 0)
return WeightLessThanZero(x);
else
return WeightIsZero(x);
}
The three "Weight" functions would test further conditions until we arrive at a value. The problem I see here is that we need to track which function called which. The FooIDIs6 function needs to know whether it was called by WeightIsZero or some other function, otherwise any preceding decisions are potentially meaningless. We end up with something like WeightIsGreaterThanZero_FooIDIs6_GrandmotherIsOlderThan100 etc. etc.
I'm not sure that this completely applies to what you are trying to accomplish, but whenever we encounter this type of "fun", we end up providing the business users a user interface to define their rules, then just write enough code to apply the rules to the specific objects.
For example, in one of our applications, we allow the user to specify a set of conditions that, when evaluated to true, will produce a user-defined output.
To do this, we store one record in the database for each portion of the IF statement. Each record specifies the property name in the class, the comparison action (<, =, <>, etc), the comparison value, whether or not the statement begins or ends a group (i.e. parens), and how the current statement is joined with the next (AND or OR).
So you would have
Heading Record (Parent record, which defines the heading to be used)
Heading Selector (Child records which define the if statement)
We can also support user-defined priorities in the parent record so that if a given record has multiple matches, it is the user's responsibility to determine the best match through the proper application of priorities.
At run time, you just build a statement to evaluate the conditions as entered by the user. We use reflection so that we don't have to hard-code property names.
In addition, the same configuration code can be used to generate SQL statements in the cases where it is more appropriate to perform the selection logic in SQL.
We have used this mechanism extensively and have found it to be a very powerful approach to meeting the frequent and varied demands of our customers.
What about a set of category classes that accepts an X and indicates whether it is the correct category for that X? Something like:
var categories = new Category[] { new FooCategory(), new BarCategory(), new FluffyCategory() };
foreach( var x in myListOfXs ) {
var cat = categories.FirstOrDefault(c => c.Matches(x));
if( cat != null ) {
x.Category = cat.Name;
}
}
This question arose when I was trying to figure out a larger problem that, for simplicity sake, I'm omitting.
I have to represent a certain data structure in C#. Its a protocol that will be used to communicate with an external system. As such, it has a sequence of strings with predefined lengths and integer (or other, more complicated data). Let's assume:
SYSTEM : four chars
APPLICATION : eight chars
ID : four-byte integer
Now, my preferred way to represent this would be using strings, so
class Message
{
string System {get; set; }; // four characters only!
string Application {get; set; }; // eight chars
int Id {get; set; };
}
Problem is: I have to ensure that string doesn't have more than the predefined length. Furthermore, this header will actually have tenths of fields, are those will change every now and then (we are still deciding the message layout).
How is the best way to describe such structure? I thought, for example, to use a XML with the data description and use reflection in order to create a class that adheres to the implementation (since I need to access it programatically).
And, like I said, there is more trouble. I have other types of data types that limits the number of characters/digits...
For starters: the whole length issue. That's easily solved by not using auto-properties, but instead declaring your own field and writing the property the "old-fashioned" way. You can then validate your requirement in the setter, and throw an exception or discard the new value if it's invalid.
For the changing structure: If it's not possible to just go in and alter the class, you could write a solution which uses a Dictionary (well, perhaps one per data type you want to store) to associate a name with a value. Add a file of some sort (perhaps XML) which describes the fields allowed, their type, and validation requirements.
However, if it's just changing because you haven't decided on a final structure yet, I would probably prefer just changing the class - if you don't need that sort of dynamic structure when you deploy your application, it seems like a waste of time, since you'll probably end up spending more time writing the dynamic stuff than you would altering the class.
How do you think, is it a good idea to have such an enum:
enum AvailableSpace {
Percent10,
Percent20,
SqF500,
SqF600
}
The question is about the semantics of the values names, i.e. both percentage and square feet. I really believe that it's not a good idea, but I could not find and guidelines, etc. in support of this.
EDIT: This will be used to determine a state of an entity - i.e. as a read only property to describe a state of an object. If we know the total space (i.e. the object itself knows it), we have the option to convert internally, so we either have only percentage, or square feet, or both. The argument is, that "both" is not a good idea.
The above is an example of course, but the real problem is that some data providers send us totals (sq.f.), and others percentage, and my goal is to unify the UI. I'm free to make some approximations, so the exact values will be adapted based on how accurate we want to present the information.
The question is only about the semantics of the value names, not the content - i.e. if it is a good idea to put percentage in an (potential) int enum.
The answer: No, it is not a good idea to use enums for representing values. Especially values in two semantically distinct scales. You should not use enums for values.
The reason: What's the relation between the enum values from the two scales, like Percent10 and SqF600? How do you expand the list of values you can represent within your code? How do you do comparison and arithmetic operations on these values?
The suggestion (not asked for, but nevertheless here it is. :-)): The semantic of what you are trying to do would be better reflected by a struct that contains two fields - one for absolute area and one for percentage available of that absolute area. With such structure you can represent anything you can represent with the enums above. For example, data providers that give you absolute area, are represented with a struct with the area and 100% available. Data providers that give you percentage, are represented with a struct with the percentage they set and the absolute area such that the percentage of that area is the actual available area the data provider wants to report. You get "normalized" representation of the data from both type of providers and you can add couple of operators to enable comparison and arithmetic calculations with instances.
If at all possible, I'd rather break your example into two values, where your enum is "Percent" and "SquareFeet" and the second value is the quantifier. Tie these together in a struct.
If the context allows for it, it may be even better to create two wrapper types "Percent" and "SquareFeet" and then create some operator overloads, so you can do things like "new SquareFeet(500) + new Percent(20);" and eliminate the use of enums.
Update: Your naming scheme would be appropriate if the values were industry recognized terms, almost to the point of being symbols. For example, it's safe to have an enum that contains values such as "ISO9001" rather than two values (an enum containing "ISO" and an int of 9001). It'd also be appropriate to have an enum like below:
public enum OperatingSystem
{
Windows95,
Windows98,
Windows2000,
WindowsXP,
WindowsVista,
MacOSClassic,
MacOSXTiger,
MacOSXLeopard
}
If the terms "Percentage10" and "Sqf500" are not terms of art or well defined in a spec, data dictionary, etc. then it's inappropriate to use them as values in an enum.