I'm new to domain driven design and would like to hear your thoughts on a design decision:
In my domain, I have the entities "voyage" and "booking".
The constructor for voyage looks like this:
public Voyage(VoyageNumber voyageNumber,
Schedule schedule,
IList<VoyagePrice> voyagePrices,
Location location,
Capacity capacity)
The value objects "voyagePrices" contain information about the price for a certain person type (child, adult, etc.). The capacity contains the maximum number of persons allowed on the voyage.
The constructor for the "Booking" looks like this:
public Booking(BookingNumber bookingNumber,
Customer customer,
Voyage voyage,
IList<ConfirmedPerson> confirmedPersons)
confirmedPersons contains the list of persons one customer wants to book (i.e. 2 adults, 1 child). Now, it is of course required to check the capacity of the voyage before allowing the booking to be saved. I dont think that "voyage" should contain a list of all the bookings made. Would it be okay to check the capacity in a BookingService or in a BookingFactory? Do you have any suggestions, maybe with a small code snippet? Thank you!
It completely possible and valid to have an available capacity be part of a Voyage or a boolean encapsulation like
Voyage.isFull()
Upon retrieval of a specific voyage aggregate from a VoyageRepository this information could be obtained.
However it's not enough, there's always a chance the voyage fills up after you've retrieved it from the VoyageRepository. So you will need to handle that exceptional case, maybe like
public interface BookingService {
Booking book(BookingRequest br) throws VoyageIsFullException;
}
And you'd probably want a BookingRequestFactory
public class BookingRequestFactory {
public static BookingRequest create(Voyage v, Customer c, IList<Person> travelers)
}
BookingRequestFactory can do some basic validation but not all cause the logic of whether it's full or not will probably require collaboration beyond what'd you'd want in a Object Factory, and is probably best handled by a BookingService.
if i anderstood you right you have to connect the two entities. I would suggest you do it just like it would be done in a relational database. Browse to this link: relational database design and read the paragraph: "Many-to-Many Relationships", i think this could be a solution :-)
Related
This problem is a bit hard to expose via the title so I hope the following clarifies my intentions a bit.
Suppose you have the following data classes:
class abstract Employee {
string ID;
}
class FullTimeEmployee : Employee {
string schedule;
}
class PartTimeEmployee : Employee{
string schedulePartTime;
}
class WheelsSpecialist : Employee{ }
class InteriorsSpecialist : Employee{ }
class Workshop {
WheelsSpecialist wheely_guy;
InteriorsSpecialist interiors_guy;
}
Now, suppose that I instantiate my workshop as follows:
var Workshop = new Workshop{
wheely_guy = new PartTimeEmployee(),
interiors_guy = new FullTimeEmployee();
}
Please assume that the structure / inheritance and instantiations here provided are immutable.
What I'd like is to generate an ID set on Employee.ID that survives the runtime and is consist and independent from class properties / developer implementation.
Understand also that: The path of each object property in the workshop instantiation is guaranteed to be UNIQUE.
As so, a good ID for the WheelsSpecialist in Workshop.wheely_guy would be "Workshop.wheely_guy". (for example) because no path will ever be the same when I'm instantiating the workshop.
When I access the object "Workshop.wheely_guy.ID" I'd like to have "Workshop.wheely_guy" there or something analogous.
I imagine something like this would work (non valid C#, logic intact):
class PartTimeEmployee {
//instantiationPath is for example, "Workshop.wheely_guy"
onCreate(string instantiationPath){
this.ID = instantionPath;
}
}
I've tried this with StackTrace and whatnot, but couldn't find a way of doing it right.
Whether this instantiationPath method is used or not, the solution requires that:
I get to keep my structure as is in the example EXCEPT for properties. Those can change.
When I want to add a new dimension to my workshop variable I CAN'T, as a developer, be responsible for awarding a class it's own unique property.
As so, doing something like "this.ID = wheels" manually is not an option (also, depending this ID on properties that the developer must implement is also not viable).
Can this be done some way that meets my demands?
Thank you!
The provided code does not compile, and the object design/inheritance used seems a bit off. You probably want to work on the abstractions themselves. But that is not what you asked (mainly). It's kind of hard to figure out what exactly you asked, but I will do my best to answer what I think you asked (mostly):
"I want a field of an object instance to contain an automatically calculated navigation path by which it is accessible in some collection or composite object unrelated to the object itself" -> while close to impossible in C#, this might be entirely/easily possible in other languages. Still, the concept itself seems a little off.
The premise here is that the Employee object does not and should not know about the Workshop object Think about part-time employees trying to work separate shifts in separate workshops at the same time, and other possible changes in the business logic regarding Employees and Workshops.
Let's walk through some of the possibilities, ordered by viability:
Doing some magic at constructor/instantiation time in the abstract constructor code (Stack Frame walking, callerMember tricks, Reflection?, AST parsing?)
At instantiation, in a constructor, the stack trace does not contain information about which property/field it is about to be assigned to (if at all for that matter, it might just need to be instantiated, not assigned to anything). So there is no way to set such an id at constructor time.
Doing some magic in the Id property getter
There is no way to pass in parameters to a property getter, so we run into the same type of problem as with option 1: the stack trace contains no useful information by the time the getter is accessed.
Make the Employee object know about Workshop
No, just no.
Some weird runtime/weaving magic to "calculate" these paths when they are accessed?
Maybe, but how much effort to put in and to what purpose?
Expression parsing in a separate method:
//Left out the non-compiling code.
public static void Main(string[] args)
{
var Workshop = new Workshop
{
WheelsGuy = new PartTimeEmployee(),
InteriorsGuy = new FullTimeEmployee()
};
Console.WriteLine(GetObjectAccessPath((_) => Workshop.WheelsGuy));
}
public static string GetObjectAccessPath(Expression<Func<Workshop, Employee>> member)
{
string body = member.Body.Reduce().ToString();
// the line below might take some tweaking depending on your needs
return body.Substring(body.IndexOf($"{nameof(Workshop)}"));
}
// Output: Workshop.WheelsGuy
Use Reflection in a separate method to "get" a list of properties that are of any type derived from Employee and based on that Generate a list of ids with something like properties.Select(p => $"Workshop_{p.Name}");
Most viable: Re-design the object model:
(This is my opinion, and the requirements of your project might be different. Even if I am speculating here, the same principles presented here would apply in many other ways).
Extract more abstractions, like Position, Role, and Schedule. Part-time would be a schedule. Wheels guy would be a role. Position would be "an employee that fulfills the role of wheels guy at a workshop." There might be more examples (pay by hour/week/month, tax exemption, etc.).
As a rule, holding too many concerns in one class is a code smell and will get you in trouble quick. You can choose to carve up the classes however you want, but for what you "seem" to want, this part is important: have a class that represents the relationship between employee and workshop.
For example, instead of the Workshop holding instances of Employees: the Position class would hold/know about an Employee, his Role, his Schedule, and the Workshop he works at. The Position's Id could then easily be Id => $"Workshop_{Role}"; or Id => $"{WorkShop}_{Role}", etc. As a bonus, you get the design bonus of the Workshop being free from knowing which types of employees it might hold.
In general, I'd suggest you look into SOLID principles, it's an eye opener.
I am writing a piece of software in c# .net 4.0 and am running into a wall in making sure that the code-base is extensible, re-usable and flexible in a particular area.
We have data coming into it that needs to be broken down in discrete organizational units. These units will need to be changed, sorted, deleted, and added to as the company grows.
No matter how we slice the data structure we keep running into a boat-load of conditional statements (upwards of 100 or so to start) that we are trying to avoid, allowing us to modify the OUs easily.
We are hoping to find an object-oriented method that would allow us to route the object to different workflows based on properties of that object without having to add switch statements every time.
So, for example, let's say I have an object called "Order" come into the system. This object has 'orderItems' inside of it. Each of those different kinds of 'orderItems' would need to fire a different function in the code to be handled appropriately. Each 'orderItem' has a different workflow. The conditional looks basically like this -
if(order.orderitem == 'photo')
{do this}
else if(order.orderitem == 'canvas')
{do this}
edit: Trying to clarify.
I'm not sure your question is very well defined, you need a lot more specifics here - a sample piece of data, sample piece of code, what have you tried...
No matter how we slice the data structure we keep running into a boat-load of conditional statements (upwards of 100 or so to start) that we are trying to avoid
This usually means you're trying to encode data in your code - just add a data field (or a few).
Chances are your ifs are linked to each other, it's hard to come up with 100 independent ifs - that would imply you have 100 independent branches for 100 independent data conditions. I haven't encountered such a thing in my career that really would require hard-coding 100 ifs.
Worst case scenario you can make an additional data field contain a config file or even a script of your choice. Either case - your data is incomplete if you need 100 ifs
With the update you've put in your question here's one simple approach, kind of low tech. You can do better with dependency injection and some configuration but that can get excessive too, so be careful:
public class OrderHandler{
public static Dictionary<string,OrderHandler> Handlers = new Dictionary<string,OrderHandler>(){
{"photo", new PhotoHandler()},
{"canvas", new CanvasHandler()},
};
public virtual void Handle(Order order){
var handler = handlers[order.OrderType];
handler.Handle(order);
}
}
public class PhotoHandler: OrderHandler{...}
public class CanvasHandler: OrderHandler{...}
What you could do is called - "Message Based Routing" or "Message Content Based" Routing - depending on how you implement it.
In short, instead of using conditional statements in your business logic, you should implement organizational units to look for the messages they are interested in.
For example:
Say your organization has following departments - "Plant Products", "Paper Products", "Utilities". Say there is only one place where the orders come in - Ordering (module).
here is a sample incoming message.
Party:"ABC Cop"
Department: "Plant Product"
Qty: 50
Product: "Some plan"
Publish out a message with this information. In the module that processes orders for "Plant Products" configure it such that it listens to a message that has "Department = Plant Products". This way, you push the onus on the department modules instead of on the main ordering module.
You can do this using NServiceBus, BizTalk, or any other ESB you might already have.
This is how you do in BizTalk and this is how you can do in NServiceBus
Have you considered sub-typing OrderItem?
public class PhotoOrderItem : OrderItem {}
public class CanvasOrderItem : OrderItem {}
Another option would be to use the Strategy pattern. Add an extra property to your OrderItem class definition for the OrderProcessStrategy and use a PhotoOrderStrategy/CanvasOrderStrategy to contain all of the different logic.
public class OrderItem{
public IOrderItemStrategy Strategy;
}
public interface IOrderItemStrategy{
public void Checkout();
public Control CheckoutStub{get;}
public bool PreCheckoutValidate();
}
public class PhotoOrderStrategy : IOrderItemStrategy{}
public class CanvasOrderStrategy : IOrderItemStrategy{}
Taking the specific example:
You could have some Evaluator that takes an order and iterates each line item. Instead of processing if logic raise events that carry in their event arguments the photo, canvas details.
Have a collection of objects 'Initiators' that define: 1)an handler that can process Evaluator messages, 2)a simple bool that can be set to indicate if they know what to do with something in the message, and 3)an Action or Process method which can perform or initiate the workflow. Design an interface to abstract these.
Issue the messages. Visit each Initiator, ask it if it can process the lineItem if it can tell it to do so. The processing is kicked off by the 'initiators' and they can call other workflows etc.
Name the pieces outlined above whatever best suits your domain. This should offer some flexibility. Problems may arise depending on concurrent processing requirements and workflow dependencies between the Initiators.
In general, without knowing a lot more detail, size of the project, workflows, use cases etc it is hard to comment.
In an ETL application I am working on, we have three basic processes:
Validate and parse an XML file of customer information from a third party
Match values received in the file to values in our system
Load customer data in our system
The issue here is that we may need to display the customer information from any or all of the above states to an internal user and there is data in our customer class that will never be populated before the values have been matched in our system (step 2). For this reason, I would like to have the values not even be available to be accessed when the customer is in this state, and I would like to have to avoid some repeated logic everywhere like:
if (customer.IsMatched) DisplayTextOnWeb(customer.SomeMatchedValue);
My first thought for this was to add a couple interfaces on top of Customer that would only expose the properties and behaviors of the current state, and then only deal with those interfaces. The problem with this approach is that there seems to be no good way to move from an ICustomerWithNoMatchedValues to an ICustomerWithMatchedValues without doing direct casts, etc... (or at least I can't find one).
I can't be the first to have come across this, how do you normally approach this?
As a last caveat, I would like for this solution to play nice with FluentNHibernate :)
Thanks in advance...
Add a class that inherits from Customer called MatchedCustomer (e.g.). Then step #2 becomes the process of promoting a Customer to a MatchedCustomer. You still need to write the code to do this; typically it's done in the constructor:
public class MatchedCustomer : Customer
{
public MatchedCustomer(Customer customer)
{
// set properties from customer, i.e.
FirstName = customer.FirstName;
}
}
I didn't understand absolutely clear but it seemed that you need just to create a Proxy-class for your class with data.
I'm part of a team tasked to revamping our old VB6 UI/COBOL database application to modern times. Before I was hired, the decision was made (largely on sales, I'm sure) to redo the UI before the database. So, now we're using WPF and MVVM to great effect, it's been amazing so far, especially using CSLA as our Model layer.
However, because our development is side-by-side with the next version of the old product, we're constrained a bit. We can't make any changes (or minimal changes) to the calls made to the COBOL database. This has been fine so far, albeit pining back to the glory days of SQL Server if you can believe it.
Where I've hit a particularly nasty roadblock regarding our BO design is in dealing with "light" business objects returned in lists and their "full" counterparts. Let me try and construct an example:
Let's say we have a person object in the DB with a bunch of fields. When we do a search on that table, we don't return all the fields, so we populate our lite object with these. These fields may or may not be a subset of the full person. We may have done a join or two to retrieve some other information specific to the search. But, if we want to edit our person object, we have to make another call to get the full version to populate the UI. This leaves us with two objects and attempting to juggle their state in 1 VM, all the while trying to keep the person list in sync on whatever parent object it sits after delete, edit, and add. Originally, I made our lite person object derive from ReadOnlyBase<>. But now that I'm dealing with the same list behavior you'd have with a list of full BOs except with half full, half lite, I'm thinking I should've just made both the lite and full versions derive from BusinessBase<> and simply made the lite version setter properties private.
Has anyone else out there come across and found a solution for this? After sleeping on it, I've come up with this potential solution. What if we wrap the full and lite version of our BO in another BO, like this:
public class PersonFull : BusinessBase<PersonFull>
{
...
}
public class PersonLite : BusinessBase<PersonLite>
{
...
}
public class Person : BusinessBase<Person>
{
public PersonFull PersonFull;
public PersonLite PersonLite;
}
public class PersonList : BusinessListBase<PersonList, Person>
{
}
Obviously everything would be CSLA registered properties and such, but for the sake of brevity they're fields there. In this case Person and PersonList would hold all the factory methods. After a search operation PersonList would be populated by Person objects whose PersonLite members were all populated and the PersonFull objects were all null. If we needed to get the full version, we simply tell the Person object to do so, and now we have our PersonFull object so we can populate the edit UI. If the Person object is to be deleted, we can easily do this with the CSLA delete procedures in place, while still maintaining the integrity of our lists across all the VMs that are listening to it.
So, I hope this made sense to everyone, and if anyone has a different solution they've successfully employed or criticism of this one, by all means!
Thanks!
(Reposted from: http://forums.lhotka.net/forums/thread/35576.aspx)
public class PersonLite : ReadOnlyBase<PersonLite>
{
public void Update(PersonFull person) { }
}
public class PersonFull : BusinessBase<PersonFull>
{
// blah blah
}
I would update the "lite" object with the changes made to the "full" object, and leave it as ReadOnlyBase. It's important to remember that the "ReadOnly" in ReadOnlyBase means an object that is only read from the database, and never saved to it. A less elegant, but more accurate name would be NotSavableBase, because such objects lack the DataPortal_XYZ machinery for anything but fetches. For obvious reasons, such objects usually have immutable properties, but they don't have to. ReadOnlyBase derives from Core.BindableBase and implements INotifyPropertyChanged, so changing the values of its properties will work just fine with binding.
When you save your "full" object, you pass the newly saved instance to the Update(PersonFull) method of the instance that sits in your list, and update the properties of the "lite" object from the "full" object.
I've used this technique many times and it works just fine.
If you look over Rocky's examples that come with the CSLA framework, you'll notice that he always separates the read only objects from the read/write objects. I think this is done for good reason, because the behaviors are going to be drastically different. Read only objects will be more performance based, their validation will be very different, and usually have less information altogether. The read/write objects will not be as perfomance based and rely heavily on validation, authorization, etc.
However, that leaves you with the dilemma you currently find yourself in. What I would do is overload the constructor of each class so you can pass them between each other and "copy" what you need out of each other.
Something like this:
public class PersonLite : BusinessBase<PersonLite>
{
public PersonLite(PersonFull fullPerson)
{
//copy from fullPerson's properties or whatever
}
}
public class PersonFull : BusinessBase<PersonFull>
{
public PersonFull(PersonLite litePerson)
{
//copy from litePerson's properties or whatever
}
}
You could do this with a factory pattern as well, which is Rocky's preference I believe.
Just a very general question, that not only applies to this example.
Let's say you have an Online Shop and you want to implement Vouchers/Gift Certificates, but with Constraints. Let's say you have a voucher for 20% off, but that applies only to products added within the last 3 weeks, but not to ones in a special promotion.
I see two ways to solve it: The first way is to code your shop to "natively" support all crazy types of vouchers. This seems to be the classic way, but it means a lot of work beforehand and very little flexibility (After all, you can't know beforehand what you need, and maybe Sales may come up with some really great new promotion which requires new vouchers - by next Monday).
The second way is a Plug-In way: Vouchers are like Plugins and each Voucher has it's own Code. You pass in the Shopping Basket into the Voucher and then the Voucher itself checks each item if it applies, makes the neccessary changes and returns the changed shopping cart.
I just wonder, what is the Design Pattern for Case 2? It looks a bit like IoC/DI, but then again not really because Vouchers are not replacing any existing functionality. It's more like a set of Object with a Special Interface (i.e. IVoucher), and then a Queue of IVoucher Object that gets iterated over. Is there a standard pattern (and best practice) for these types of "Manipulators"?
Edit: Thanks for the Answers. To clarify that just a bit, the Vouchers (or Manipulators - as said, this is not only a question about online shops but about a similar situations) are "heavy" objects, that is they have Business Logic in them. So I can say that a Voucher only applies if the Customer signed up before January 1 2008, only if the customer ordered at least 100$ in the past 6 months, only applies to articles in the Category X, "stacks" with other Vouchers except for Items marked as Reduced etc. etc. etc. So my concern was more about how to keep a clean structure to make sure the Vouchers get all that they need to check whether they apply and to be able to manipulate the Cart, so I wondered about what the standard for such situations are, which is exactly what the Visitor Pattern seems to do.
It's a case where you could use the strategy pattern along with the vistor pattern to calculate the value of the basket.
A vistor could visit each item in the basket utilising different strategies (in this case discount vouchers) and using those to calculate the full cost of the basket.
The vouchers used could be retrieved from a database in some way and injected into the visitor quite easily.
The voucher strategy could look something like this:
public interface IVoucher
{
decimal CostOf(CartItem cartItem);
}
The default would be something like this:
public class FullPriceVoucher : IVoucher
{
public decimal CostOf(CartItem cartItem)
{
return cartItem.Cost;
}
}
A 10% discount would be something like:
public class TenPercentOffVoucher : IVoucher
{
public decimal CostOf(CartItem cartItem)
{
return cartItem.Cost * 0.9m;
}
}
Then you could have a visitor for calculating cart value like this:
public class CartValueVisitor
{
private IVoucher voucher;
public CartValueVisitor(IVoucher voucher)
{
this.voucher = voucher;
}
public decimal CostOf(Cart cart)
{
return cart.Items.Sum(item => voucher.CostOf(item));
}
}
Which you would use like:
var cart = GetACart();
var fullPriceCartValueVisitor =
new CartValueVisitor(new FullPriceVoucher());
var tenPercentOffCartValueVisitor =
new CartValueVisitor(new TenPercentOffVoucher());
var fullPrice = fullPriceCartValueVisitor.CostOf(cart);
var tenPercentOffPrice = tenPercentOffCartValueVisitor.CostOf(cart);
This obviously only works with a single voucher at a time but should give you an idea of the general structure.
The previous answers suggesting Visitor and Strategy patterns sound fine to me, although Visitor is overkill in the typical case where each purchase item is an object of the same concrete class. The purpose of Visitor is to allow dynamic dispatch on two (or more) object types -- the visited objects are part of one hierarchy, and the visitors are part of another. But if only one object type (the concrete type of the class implementing IVoucher) varies, then regular old single-type virtual dispatch is all you need.
In fact I personally wouldn't bother with any "pattern" at all -- your own description is exactly what's needed: create an interface, IVoucher, and a bunch of classes that implement that interface. You'll also need a factory method that takes a voucher code and returns an IVoucher object having the appropriate concrete type.
Beware Non-Commutative Vouchers!
The fact that you mention a queue of IVoucher-implementing objects will be run against the purchase items implies that more than one voucher may be used. In this case you need to be careful -- does applying voucher A, then voucher B always have the same effect as applying B then A? Unfortunately many typical "special offers" would seem not to have this property (e.g. if voucher A gives you $10 off and voucher B gives you 5% off, the order definitely matters).
A quick and dirty way out of this is to assign each voucher a distinct numeric "priority" value, and always apply vouchers in priority value order. To reduce the probability of "weird" combinations of vouchers driving you bankrupt, it's probably also a good idea to limit voucher combinations to some set of allowed combinations specified in your code somewhere. (This could be as simple as a list of lists of voucher codes.)
Maybe the Visitor pattern? The different types of vouchers are the visitors, which visit the shopping basket and manipulate it.
I don't think IOC is the solution here.