I am modelling a DVD Rental Store:
A Client gives its clientNumber to the System.
The System checks whenever the given clientNumber is valid.
The Client gives the name of the DVD he wants to rent.
...
...I will later have to form an association between a new instance of Rent DVD class concept to the current Client c.
My Domain Model is something like:
I've made the Contract for the first and second operations as:
Preconditions: none
Postconditions: there exists a Client c such that c.clientNumber = clientNumber.
Now, I don't know if I should form an association between this Client c and the DVDStore(that I intend to use as front-end). If I don't make the association, how will I later be able to "reference" this same Client? Should I be making an association between Client and a different concept?
Thanks
Yes, one has to create an association between Client and DVDStore. Otherwise (as stated), you can't later refer to the same Client (at least without having to search for it... again!).
Related
I want to see the difference of Delivery Class 'A' and 'C'. C for data entered only by the customer, but how can I see it on the code?
I created two tables of type 'A' and 'C'. I add data with ABAP code. I thought I couldn't add data to the table I created with C, but they both work the same.
For A Type:
DATA wa_ogr LIKE ZSGT_DELIVCLS2.
wa_ogr-ogrenci_no = 1.
wa_ogr-ogrenci_adi = 'Seher'.
INSERT ZSGT_DELIVCLS2 FROM wa_ogr.
For C Type:
DATA wa_ogr LIKE ZSGT_DELIVERYCLS.
wa_ogr2-ogrenci_no = 1.
wa_ogr2-ogrenci_adi = 'Seher'.
INSERT ZSGT_DELIVERYCLS FROM wa_ogr2.
Datas get trouble-free when I check with debugging.
Is there a live demo where I can see the working logic of C? Can you describe Delivery Class C better?
Tables with delivery class C are not "customer" tables, they are "customizing" tables. "Customizing" is SAPspeak for configuration settings. They are supposed to contain system-wide or client-wide settings which are supposed to be set in the development system and then get transported into the production system using a customizing transport. But if that's actually the case or not depends on what setting you choose when generating a maintenance dialog with transaction SE54. It's possible to have customizing tables which are supposed to be set in the production system directly without a transport request.
Tables with delivery class A are supposed to contain application data. Data which is created and updated by applications as part of their every day routine business processes. There should usually be no reason to transport that data (although you can do that by manually adding the table name and keys to a transport request). Those applications can be SAP standard applications, customer-developed applications or both.
There is also the delivery class L which is supposed to be used for short-living temporary data as well as the classes G, E, S and W which should only be used by SAP on tables they created.
But from the perspective of an ABAP program, there is no difference between these settings. Any ABAP keywords which read or write database tables work the same way regardless of delivery class.
But there are some SAP standard tools which treat these tables differently. One important one are client copies:
Data in delivery class C tables will always be copied.
Data in delivery class A tables is only copied when desired (it's a setting in the copy profile). You switch it off to create an empty client with all the settings of an existing client or to synchronize customizing settings between two existing clients without overwriting any of the application data. You switch it on if you want to create a copy of your application data, for example if you want a backup or want to perform a destructive test on real data.
Data in delivery class L tables doesn't get copied.
For more information on delivery classes, check the documentation.
I'm trying to configure my teamspeak server and I don't know how to do some things, so I'm asking help to configure it... here is what i wanted to do:
I have some categories like 'Minecraft' or 'Planetside 2' or 'Devlopment' and each categorie contain some channel and sub channel. which lead to something like that:
Then about users :
First, there's me: the admin.
Then I want to be able to put some people in a 'Moderator' group
Me and moderators can define some people as 'Categorie leader'. for example, I can put people A to be a 'Minecraft Category leader'
A Categorie leader can define who is in his categorie (of course moderator and admin can also), for instance: My Minecraft categorie leader A can put people B to be a Minecraft Player. But a Minecraft Categorie leader can't put People C as a 'Planetside 2 player'.
This configuration is show on this picture:
Then about the channel !
I will take the example of the Planetside 2 Categorie :
I will have 2 channels in the categorie : the first one will allow only Planetside 2 player, Planetside 2 leader and admin to access it. the second one will allow everybody to access.
How can I do that ?
For the moment I didn't try anything, as I don't want to do some mistake that would make it hard ton configure. But I was thinking about channel group, and allow a channel group to access a particular channel. I found some topics on google which make me think it's not that hard.
But then, i don't find anything which can help me to do the part where I want my Categorie leader putting channel groupe only for his categorie.
Any idea ?
Thanks for your help.
For your first question, unfortunately, this is not possible.
TeamSpeak permission is based on a numeric system, instead of a tree hierarchy system.
In other words, if my value is greater than yours, I have power over you.
So back to your case, the most you can do is a four-level rank, with Admin -> Moderator -> Leader -> Members.
In other words, if your leader made their own member groups, all other leaders can access it (since they got higher power than the member group), which is not something you'd want, but that's the sad reality of it.
Now, to your second question on channel groups, this is doable, just follow the instructions:
set all channel's needed_join_power with a value greater than 0, also make sure that you set the needed_join_power of the channel you want to exclusively for leaders is higher than that value.
set admin and moderator's join_power higher or equals to the value you set for step 1.
set the SERVER GROUP of the default Member group's join power to 0
set up channel groups with Leader and Member, both with join_power higher than the value in step 1, also make sure Leader's join power is higher than Member's
Grant Leader with the power to move user
Done. Once this is complete, the leader can move users into their channel and grant the user with the associated channel groups. When the user is assigned with the associated channel group, they can freely move in and out of the channel at free will.
I am working on using Optaplanner to solve the following a complex vrp problem with many requirements. I was able to handle most of them except for the following 2 aspects.
Pickups before DropOffs only
Enforce a specific path on the way to pickup customers.
The goal is to pickup a group of customers who are going to destinations that close together and put them in the same vehicle.
Thanks in Advance! I appreciate the help!
The Problem is very similar to the example VRP TimeWindow example but with the following changes.
Customers will be picked up at fixed locations (in a circuit)
Every pickup Customer will have a drop off destination (outside of
Circuit)
The vehicle will not head to a drop-Off then come back to pickup
again. (Once vehicle leaves circuit all it does is drop-Off its
customers at set location)
The Vehicle moving in the circuit has to move in a specific path
(imagine a 1 way street)
Planning on Using Road Distances with the Score between each Pickup-to-Pickup is Known. Pickup -> Drop-Off is not known (Planning on using Air).
I'm having a hard time in enforcing that after leaving the circuit to drop-Off customers a vehicle may not come back to pickup more customers, and having this work with the fixed path a vehicle can make in the circuit.
My main idea was to do the following.
Added a TYPE attribute to the customer to differentiate between pickup & customer
Added a variable listener to the customer class that keep track of all the DropOffIds currently when a vehicle arrives to it so that it only goes to a dropOffLocation if it has a passenger heading to that place. When a vehicle arrives to a dropOff it removes that item from the list. (Essentially serves as a stack).
The problem is theoretically this isn't stopping from a vehicle picking up a customer dropping him off then picking up another, if the customers locations are relatively close.
Also having a hardtime enforcing a fixed route a vehicle must take in a circuit, was planning on using a Cost Matrix to use the soft constraint to enforce the route implicitity(A vehicle wont go backwards or a skip a point as the cost would be too high), but not working the way it should be.
I might consider a domain model like this:
#PlanningEntity
class Pickup implements PickupOrVehicle {
Customer customer;
#PlanningVariable
PickupOrVehicle previousPickup;
#PlanningVariable
int dropOffPriority;
}
#PlanningEntity // Shadow entity
class Vehicle implements PickupOrVehicle {
...
#ShadowVariable(based on dropOffPriority and previousPickup)
List<Customer> dropOffOrderList;
// For consistency we might also add pickUpOrderList
}
That dropOffPriority should either be globally unique (by initializing it uniquely and only configure SwapMoves for that variable.
Or otherwise, the VariableListener should just order 2 assignments with the same dropOffPriority by their customer's id (because the ordering must be deterministic!).
No sure if it will work well. If you do try it out, do let us know here if it works well or not.
I'm new to server side web development and recently I've been reading a lot about implementing RESTful API's. One aspect of REST API's that I'm still stuck on is how to go about structuring the URI hierarchy that identifies resources that the client can interact with. Specifically I'm stuck on deciding how detailed to make the hierarchy and what to do in the case of resources being composed of other resource types.
Here's an example that hopefully will show what I mean. Imagine we have a web service that lets users buy products from other users. So in this simple case, there are two top level resources users and products. Here's how I began to structure the URI hierarchy,
For users:
/users
/{id}
/location
/about
/name
/seller_rating
/bought
/sold
For products:
/products
/{id}
/name
/category
/description
/keywords
/buyer
/seller
In both of these cases objects in each hierarchy reference a subset of the objects in the other hierarchy. For example /users/{id}/bought is a list of the products that some user has bought, which is a subset of /products. Also, /products/{id}/seller references the user that sold a specific product.
Since these URI's reference other objects, or subsets of other objects, should the API support things like this: /users/{id}/bought/id/description and /products/{id}/buyer/location? Because if those types of URI's are supported, what's to stop something like this /users/{id}/bought/{id}/buyer/bought/{id}/seller/name, or something equally convoluted? Also, in this case, how would you handle routing since the router in the server would have to interpret URI's of arbitrary length?
The goal is to build convenient resource identifiers, don't try to cross-reference everything. You don't have to repeat your database relations in URL representation :)
Links like /product/{id}/buyer should never exist, because there already is identifier for that resource: /user/{id}
Although it's ok to have /product/{id}/buyers-list because list of buyers is a property of product that does not exist in other contexts.
You should think of it in a CRUD fashion, where each entity supports Create, Read, Update, and Delete (typically using GET, POST, PUT, and DELETE HTTP verbs respectively).
This means that your endpoints will typically only go one level deep. For instance
Users
GET /users - Return a list of all users (you may not want to make this publically available)
GET /users/:id - Return the user with that id
POST /users - Create a new user. Return a 201 Status Code and the newly created id (if you want)
PUT /users/:id - Update the user with that id
DELETE /users/:id - Delete the user with that id
Going into more detail, such as /users/:id/about is likely not necessary. While it may work, it may be getting slightly overspecific.
Perhaps in your case you could add in:
GET /users/:id/bought - Array of products that the user bought
GET /users/:id/sold - Array of products that the user sold
where you could return a list of id's (which can be fetched through the products API), or you could populate the Products before sending them back if you wish. If you do choose to populate them, you probably should not then populate users referenced by each product. This will lead to circular includes and is wrong.
And for Products, in your sitation I would use:
GET /products- Return a list of all products
GET /products/:id - Return the products with that id
POST /products- Create a new product. Return a 201 Status Code and the newly created id (if you want)
PUT /products/:id - Update the product with that id
DELETE /products/:id - Delete the product with that id
GET /products/:id/buyers - Array of who bought the product
GET /products/:id/sellers - Array of everyone selling the product
I was reading a similar question on SO: How update an entity inside Aggregate, but I'm still not sure how a user interface should interact with entities inside an aggregate.
Let's say I have a User, with a bunch of Addresses. User is the aggregate root, while Address only exists within the aggregate.
On a web inteface, a user can edit his addresses. Basically, what happens is:
The user sees a list of addresses on its web interface
He clicks on an address, and gets redirected to this page: edit-address?user=1&address=2
On this page, he gets a form where he can modify this address.
I we decided to bypass the aggregate root, this would be straightforward:
We would directly load the Address with its Id
We would update it, then save it
Because we want to do it the DDD way, we have different solutions:
Either we ask the User to get this Address by Id:
address = user.getAddress(id);
address.setPostCode("12345");
address.setCity("New York");
em.persist(user);
The problem with this approach is, IMO, that the aggregate root still doesn't have much more control over what's done with the address. It just returns a reference to it, so that's not much different from bypassing the aggregate.
Or we tell the aggregate to update an existing address:
user.updateAddress(id, "12345", "New York");
em.persist(user);
Now the aggregate has control over what's done with this address, and can take any necessary action that goes with updating an address.
Or we treat the Address as a value object, and we don't update our Address, but rather delete it and recreate it:
user.removeAddress(id);
address = new Address();
address.setPostCode("12345");
address.setCity("New York");
user.addAddress(address);
em.persist(user);
This last solution looks elegant, but means that an Address cannot be an Entity. Then, what if it needs to be treated as an entity, for example because another business object within the aggregate has a reference to it?
I'm pretty sure I'm missing something here to correctly understand the aggregate concept and how it's used in real life examples, so please don't hesitate to give your comments!
No, you're not missing anything - in most cases the best option would be number 2 (although I'd call that method changeAddress instead of updateAdress - update seems so not-DDD) and that's regardless whether an address is an Entity or Value Object. With Ubiquitous Language you'd rather say that User changed his address, so that's exactly how you should model it - it's the changeAddress method that gets to decide whether update properties (if Address is an Entity) or assign completely new object (when it's VO).
The following sample code assumes the most common scenario - Address as VO:
public void ChangeAddress(AddressParams addressParams)
{
// here we might include some validation
address = new Address(addressParams);
// here we might include additional actions related with changing address
// for example marking user as required to confirm address before
// next billing
}
What is important in this sample, is that once Address is created, it is considered valid - there can be no invalid Address object in your aggregate. Bare in mind however, that whether you should follow this sample or not depends on your actual domain - there's no one path to follow. This one is the most common one though.
And yes, you should always perform operations on your entities by traversing through aggregate root - the reason for this was given in many answers on SO (for example in this Basic Aggregate Question).
Whether something is an entity or VO depends on the requirements and your domain. Most of the time address is just a Value Object, because there's no difference between two addresses with the same values and addresses tend to not change during their lifetime. But again, that's most of the time and depends on domain you're modeling.
Another example - for most of the domains a Money would be a Value Object - 10$ is 10$, it has no identity besides amount. However if you'd model a domain that deals with money on a level of bills, each bill would have its own identity (expressed with a unique number of some sort) thus it would be an Entity.