I need some help with pseudocode. The question is as follows:
Write pseudocode for a function, processPayment() that processes
payment by customers and commits the system to delivering the promised
product and service. This function may call on other functions,
possibly from other objects. You do not have to describe the called
functions or the classes that they belong to as long the calls are
reasonably explanatory.
Advertising is displayed while the customer
awaits credit approval. (i.e., you can assume that while the function
is waiting for credit card approval to complete, the next step begins
immediately.)
Advertising is removed as soon as credit acceptance or
denial is received. You can assume that the user has already entered
credit card information and is aware of the costs of each option.
I have this as pseudocode:
processPayment()
do displayAdContent();
while paymentConfirmation(bool) = false;
I keep thinking I need something after processPayment(). Any guidance would be appreciated!
You need a lot more than "something after processPayment()." I would do something like this:
ProcessPayment()
{
if(paymentIsValid)
{
do displayAdContent();
if(isInInventory())
{
try
{
do createAndChargeOrder();
do deliverProduct();
do updateInventory();
}
catch
{
do cancelOrder();
do sendFailedOrderNotification();
}
}
else
{
do notifyNotAvailable();
do offerSimilarProduct();
}
do sendConfirmation();
}
else
{
do paymentNotValid();
}
}
Related
I am writing some validation code and am not sure how to pass validation messages back to the calling code.
Exceptions come to mind, but I think that Exceptions should not be used in user input validation. As #Blowdart puts it:
Exceptions are not
control flow mechanisms. Users often get passwords wrong, it's not an
exceptional case. Exceptions should be a truly rare thing,
UserHasDiedAtKeyboard type situations.
From: https://stackoverflow.com/a/77175/125938. I'm extending that sentiment to all "incorrect" user input that a user might enter.
So the question is what to use instead of Exceptions. For certain situations, I could just use an IsValid… method that returns a bool for validity, but what if I want to pass an error message back with it? Should I create a custom "ValidationError" object, with a Message property? What makes sense and causes Least Astonishment (preferably a tried and tested pattern)?
If I were to do this in a truly object-oriented way, I'd adhere to the separation of concerns principle and compose a chain of classes that each deal with a separate step on the input - validation - output journey.
Let's say we are parsing a date from string as entered by the user.
My first class would encapsulate the raw value and attempt to parse the date (pseudo-code):
class TextualDate {
public TextualDate(string value) {
// just initialize with the provided value
}
public Option<Date> AsDate() {
// try parsing and either return the date or not
// the Option<Date> type is here to suggest that the conversion might not succeed
}
}
Next I'd have a validation class that instantiates the TextualDate class, invokes its AsDate() method and returns the validation result:
class ValidatedDate {
public ValidatedDate(TextualDate value) {
// initialize with the provided value
_textualDate = value;
}
private TextualDate _textualDate;
public ValidationResult Validated {
var maybeDate = _textualDate.AsDate();
// see whether we have a date or not
return new ValidationResult(...);
}
}
In our ValidationResult class, we might find some status property (OK, Failed), any error message either provided directly or as a key to then look-up in a message catalog etc.
This way, we can isolate concerns and only deal with the error messages on the UI layer while being able to use and reuse the validation logic independently.
I was faced with a similar dilemma in the past - I had to write a couple of services that takes data from a 3rd party, manipulating it in various ways, and send that data to other services for further processing.
All of these services might have failed because of wrong or incomplete data, but it was nor unexpected neither exceptional - and I refused to use exceptions for these cases.
I've done an extensive research, reading anything I could get my hands on in this subject in two days, and finally decided the following:
A method might need to return data and might not (sub in Visual Basic, void in Java/C#) - but in both cases, I wanted an indication for success/fail and a potential error message.
If your language of choice supports tuples, you could return a tuple from your methods:
public (bool Success, string ErrorMessage) DoSomething()
{
// implementation here
}
or
public (bool Success, someType Value, string ErrorMessage) DoSomething()
{
// implementation here
}
If not, you can do what I did (That was c#5 - so no value tuples) and create a result class:
public class Result
{
public static Result Success()
{
return new Result(true, null);
}
public static Result Fail(string errorMessage)
{
return new Result(false, errorMessage);
}
protected Result(bool success, string errorMessage)
{
Success = success;
ErrorMessage = errorMessage;
}
public bool Success {get; private set;}
public string ErrorMessage {get; private set;}
}
public class Result<T>
{
public static Result<T> Success(T value)
{
return new Result(true, null, value);
}
public new static Result<T> Fail(string errorMessage)
{
return new Result(false, errorMessage, default(T));
}
private Result<T>(bool success, string errorMessage, T value)
: base(success, errorMessage)
{
Value = value;
}
public T Value {get; private set;}
}
And use it like this:
public Result CouldBeVoid()
{
bool IsOk;
// implementation
return IsOk ?
Result.Success() :
Result.Fail("Something went wrong") ;
}
public Result<int> CouldBeInt()
{
bool IsOk;
// implementation
return IsOk ?
Result.Success(intValue) :
Result.Fail("Something went wrong") ;
}
var result = CouldBeVoid();
if(!result)
// do something with error message
var result = CouldBeInt()
if(result)
// do something with int value
else
// do something with error message
Users often get passwords wrong, it's not an exceptional case.
Yes and no. Whether to throw an exception or not depends on the question you're asking. And in the course of logging a user in, there are typically quite a number of questions being asked before you come to the conclusion whether the user can be logged in or not. The more you break down your code into specialised parts, the more it may make sense to raise exceptions in some of those parts.
Say you specify your login procedure the following way in an HTTP context:
Get the username* and password* from the request.
Fetch the user record* by its username from the database*.
Check whether the record's password* equals* the entered password.
If yes, start a session.
If any of the above steps do not successfully complete, output an appropriate error message.
Any of the items marked with an asterisk above may fail:
The request may not contain a username or password.
There may not be a user record for this username, or the database may be down.
For whatever reason, the record may not have a password and/or be corrupted. The stored password may, for whatever reason, use an unsupported hashing algorithm and hence can't be compared.
It should be rather obvious that in this process there are any number of cases that would be ideal to be implemented as an exception. The actual function which tests the password should probably not throw an exception in case the password is merely false; that should be a boolean return value. But it may still throw an exception for any other number of reasons. If you use exceptions properly, you'll end up with code that looks something like this (pseudo-pseudo code):
try {
username = request.get('username')
password = request.get('password')
user = db.get(username=username)
if (user.password.matches(password)) {
session.start()
} else {
print 'Nope, try again'
}
} catch (RequestDoesNotHaveThisDataException) {
logger.info('Invalid request')
response.status(400)
} catch (UserRecordNotFoundException) {
print 'Nope, try again'
} catch (UnsupportedHashingAlgorithmException, PasswordIsNullException) {
logger.error('Invalid password hash for user ' + user.id)
response.status(500)
print 'Sorry, please contact our support staff'
} catch (DatabaseDownException e) {
// mostly for illustration purposes,
// this exception should probably not even be caught here
logger.exception('SEND HALP!')
throw e
}
So, yes, this is a very simple process, but literally every step along the way has one or more exceptional cases. You ask the question "what is the username the user sent in the request?", and if there's no answer to this question because the user didn't sent any username, you have an exceptional case. Exceptions simplify control flow here a lot as opposed to trying to cover each of these cases with an if..else.
It is NOT an exception if the username is not valid or the password is not correct.
(From the answer you quote from.)
As you can see, we're testing whether the username is "valid" or not by trying to fetch its record from the database. If we have a function whose purpose is to fetch records of users from the database, and there is no such record, then an exception is an entirely valid response. If we defined that function to test whether such a record exists and null or false is a valid return value… fine. But in this case we didn't write it that way, and frankly, that results in simpler control flow I find.
Now, only the password validation itself does not use an exception, since the question asked there is "does this password match that password?", to which the answer can clearly be yes or no. Again, only if something exceptional like an unsupported hashing algorithm turns up can there be no answer to this question and an exception is entirely warranted.
Having said all this, you may notice that most of these cases, except the really fatal one with the database, does not outwardly result in an exception. The component here is expecting and handling certain cases that its sub-components regard as exceptional. This code here is asking the questions, and is prepared to handle Mu as an answer for some of them. Which is to say, a general rule that says "exceptions shouldn't be used in process X, Y or Z because it's not exceptional enough" is too dogmatic. It depends on the purpose of each individual piece of code whether an exception is warranted or not.
Having said all this, what you're asking about is some sort of form validation. The above code shows a case where two pieces of data may each be invalid, and it's using exceptions to in the end still result in a "yes" or "no" response. You can of course encapsulate that in an object like this:
val = new LoginFormValidator()
val.setDataFromRequest(request)
val.validate()
if (val.isValid) {
print 'Hurray'
} else {
print 'You have errors:'
for (error in val.errors) {
print error.fieldName + ': ' + error.reason
}
}
Whether this validator uses exceptions internally for any of this you do not need to care, but in the end it saves all of them as a "yes" or "no" result to its internal properties, from where you can take them either as an aggregate (val.isValid) or individually (for (error in val.errors)).
The return statement is being used in void methods to break out of the logic here. The problem is the consumers of the method wouldn’t know whether the logic in the method ran completely or not, when we do this. However my architect and teams don't agree with that. The reason is that the current consumer in this case doesn't care about the outcome.
I think this is coding anti-pattern. It is like eating exception with out bubbling it up. What's everyone's opinion on this?
Existing code:
Private void XXX(final String parameter) {
try {
if (parameter==null){
return;
}
....
}
My version
Private boolean XXX(final String parameter) {
try {
if (parameter==null){
return false;
}
....
return true;
}
In general having multiple returns is not necessarily an anti-pattern. At worst there might be many exit points in the method which can be confusing for developers who are reading the code and perhaps make it harder to maintain...maybe but that is not what you seem to be asking.
The code samples you provided appear to me to both be anti-patterns.
The problem is the consumers of the method wouldn’t know whether the logic in the method ran completely or not, when we do this.
First, that is what Exceptions are for. If there is a problem while executing the code in the method, throw an Exception with an intent revealing type and a good message describing the problem.
The first version of your code:
Private void XXX(final String parameter) {
try {
if (parameter==null){
return;
}
....
}
seemed to return instead of throwing an Exception with an invalid argument.
The second version of the code:
Private boolean XXX(final String parameter) {
try {
if (parameter==null){
return false;
}
....
return true;
}
Seems to return a boolean as an exit code of "worked" or "didn't work". This isn't very helpful because if it didn't work, you don't know why. Also it requires the calling code to check the return value which they might forget to do.
There's nothing wrong with having an explicit return for a void method. However, it is good general practice--if possible--to have just one return from a method (although you can have more than one if logic demands it and you write the code as simply as possible--no blocks--so that the overall flow is not obfuscated).
Should you simply return in the case you cite? It all depends on the requirements. Your customers appear to be the programmers who will call this method. Do they consider a null parameter to be a logic error for the method or do they consider it to be valid?
If it's the former then I suggest you use an annotation (#NotNull) to ensure that parameter is not null. Unfortunately, there are several of these to choose from so you will have to figure out which suits your architecture best.
If you really don't want to use an annotation (and null is considered an error) then throw an exception.
I can get room's clients list with this code in socket.io 0.9.
io.sockets.clients(roomName)
How can I do this in socket.io 1.0?
Consider this rather more complete answer linked in a comment above on the question: https://stackoverflow.com/a/24425207/1449799
The clients in a room can be found at
io.nsps[yourNamespace].adapter.rooms[roomName]
This is an associative array with keys that are socket ids. In our case, we wanted to know the number of clients in a room, so we did Object.keys(io.nsps[yourNamespace].adapter.rooms[roomName]).length
In case you haven't seen/used namespaces (like this guy[me]), you can learn about them here http://socket.io/docs/rooms-and-namespaces/ (importantly: the default namespace is '/')
Updated (esp. for #Zettam):
checkout this repo to see this working: https://github.com/thegreatmichael/socket-io-clients
Using #ryan_Hdot link, I made a small temporary function in my code, which avoids maintaining a patch. Here it is :
function getClient(roomId) {
var res = [],
room = io.sockets.adapter.rooms[roomId];
if (room) {
for (var id in room) {
res.push(io.sockets.adapter.nsp.connected[id]);
}
}
return res;
}
If using a namespace :
function getClient (ns, id) {
return io.nsps[ns].adapter.rooms[id]
}
Which I use as a temporary fix for io.sockets.clients(roomId) which becomes findClientsSocketByRoomId(roomId).
EDIT :
Most of the time it is worth considering avoiding using this method if possible.
What I do now is that I usually put a client in it's own room (ie. in a room whose name is it's clientID). I found the code more readable that way, and I don't have to rely on this workaround anymore.
Also, I haven't tested this with a Redis adapter.
If you have to, also see this related question if you are using namespaces.
For those of you using namespaces I made a function too that can handle different namespaces. It's quite the same as the answer of nha.
function get_users_by_room(nsp, room) {
var users = []
for (var id in io.of(nsp).adapter.rooms[room]) {
users.push(io.of(nsp).adapter.nsp.connected[id]);
};
return users;
};
As of at least 1.4.5 nha’s method doesn’t work anymore either, and there is still no public api for getting clients in a room. Here is what works for me.
io.sockets.adapter.rooms[roomId] returns an object that has two properties, sockets, and length. The first is another object that has socketId’s for keys, and boolean’s as the values:
Room {
sockets:
{ '/#vQh0q0gVKgtLGIQGAAAB': true,
'/#p9Z7l6UeYwhBQkdoAAAD': true },
length: 2 }
So my code to get clients looks like this:
var sioRoom = io.sockets.adapter.rooms[roomId];
if( sioRoom ) {
Object.keys(sioRoom.sockets).forEach( function(socketId){
console.log("sioRoom client socket Id: " + socketId );
});
}
You can see this github pull request for discussion on the topic, however, it seems as though that functionality has been stripped from the 1.0 pre release candidate for SocketIO.
I've only began with DDD and currently trying to grasp the ways to do different things with it. I'm trying to design it using asynchronous events (no event-sourcing yet) with CQRS. Currently I'm stuck with validation of commands. I've read this question: Validation in a Domain Driven Design , however, none of the answers seem to cover complex validation across different aggregate roots.
Let's say I have these aggregate roots:
Client - contains list of enabled services, each service can have a value-object list of discounts and their validity.
DiscountOrder - an order to enable more discounts on some of the services of given client, contains order items with discount configuration.
BillCycle - each period when bills are generated is described by own billcycle.
Here's the usecase:
Discount order can be submitted. Each new discount period in discount order should not overlap with any of BillCycles. No two discounts of same type can be active at the same time on one service.
Basically, using Hibernate in CRUD style, this would look something similar to (java code, but question is language-agnostic):
public class DiscountProcessor {
...
#Transactional
public void processOrder(long orderId) {
DiscOrder order = orderDao.get(orderId);
BillCycle[] cycles = billCycleDao.getAll();
for (OrderItem item : order.getItems()) {
//Validate billcycle overlapping
for (BillCycle cycle : cycles) {
if (periodsOverlap(cycle.getPeriod(), item.getPeriod())) {
throw new PeriodsOverlapWithBillCycle(...);
}
}
//Validate discount overlapping
for (Discount d : item.getForService().getDiscounts()) {
if (d.getType() == item.getType() && periodsOverlap(d.getPeriod(), item.getPeriod())) {
throw new PeriodsOverlapWithOtherItems(...);
}
}
//Maybe some other validations in future or stuff
...
}
createDiscountsForOrder(order);
}
}
Now here are my thoughts on implementation:
Basically, the order can be in three states: "DRAFT", "VALIDATED" and "INVALID". "DRAFT" state can contain any kind of invalid data, "VALIDATED" state should only contain valid data, "INVALID" should contain invalid data.
Therefore, there should be a method which tries to switch the state of the order, let's call it order.validate(...). The method will perform validations required for shift of state (DRAFT -> VALIDATED or DRAFT -> INVALID) and if successful - change the state and transmit a OrderValidated or OrderInvalidated events.
Now, what I'm struggling with, is the signature of said order.validate(...) method. To validate the order, it requires several other aggregates, namely BillCycle and Client. I can see these solutions:
Put those aggregates directly into the validate method, like
order.validateWith(client, cycles) or order.validate(new
OrderValidationData(client, cycles)). However, this seems a bit
hackish.
Extract the required information from client and cycle
into some kind of intermediate validation data object. Something like
order.validate(new OrderValidationData(client.getDiscountInfos(),
getListOfPeriods(cycles)).
Do validation in a separate service
method which can do whatever it wants with whatever aggregates it
wants (basically similar to CRUD example above). However, this seems
far from DDD, as method order.validate() will become a dummy state
setter, and calling this method will make it possible to bring an
order unintuitively into an corrupted state (status = "valid" but
contains invalid data because nobody bothered to call validation
service).
What is the proper way to do it, and could it be that my whole thought process is wrong?
Thanks in advance.
What about introducing a delegate object to manipulate Order, Client, BillCycle?
class OrderingService {
#Injected private ClientRepository clientRepository;
#Injected private BillingRepository billRepository;
Specification<Order> validSpec() {
return new ValidOrderSpec(clientRepository, billRepository);
}
}
class ValidOrderSpec implements Specification<Order> {
#Override public boolean isSatisfied(Order order) {
Client client = clientRepository.findBy(order.getClientId());
BillCycle[] billCycles = billRepository.findAll();
// validate here
}
}
class Order {
void validate(ValidOrderSpecification<Order> spec) {
if (spec.isSatisfiedBy(this) {
validated();
} else {
invalidated();
}
}
}
The pros and cons of your three solutions, from my perspective:
order.validateWith(client, cycles)
It is easy to test the validation with order.
#file: OrderUnitTest
#Test public void should_change_to_valid_when_xxxx() {
Client client = new ClientFixture()...build()
BillCycle[] cycles = new BillCycleFixture()...build()
Order order = new OrderFixture()...build();
subject.validateWith(client, cycles);
assertThat(order.getStatus(), is(VALID));
}
so far so good, but there seems to be some duplicate test code for DiscountOrderProcess.
#file: DiscountProcessor
#Test public void should_change_to_valid_when_xxxx() {
Client client = new ClientFixture()...build()
BillCycle[] cycles = new BillCycleFixture()...build()
Order order = new OrderFixture()...build()
DiscountProcessor subject = ...
given(clientRepository).findBy(client.getId()).thenReturn(client);
given(cycleRepository).findAll().thenReturn(cycles);
given(orderRepository).findBy(order.getId()).thenReturn(order);
subject.processOrder(order.getId());
assertThat(order.getStatus(), is(VALID));
}
#or in mock style
#Test public void should_change_to_valid_when_xxxx() {
Client client = mock(Client.class)
BillCycle[] cycles = array(mock(BillCycle.class))
Order order = mock(Order.class)
DiscountProcessor subject = ...
given(clientRepository).findBy(client.getId()).thenReturn(client);
given(cycleRepository).findAll().thenReturn(cycles);
given(orderRepository).findBy(order.getId()).thenReturn(order);
given(client).....
given(cycle1)....
subject.processOrder(order.getId());
verify(order).validated();
}
order.validate(new OrderValidationData(client.getDiscountInfos(),
getListOfPeriods(cycles))
Same as the above one, you still need to prepare data for both OrderUnitTest and discountOrderProcessUnitTest. But I think this one is better as order is not tightly coupled with Client and BillCycle.
order.validate()
Similar to my idea if you keep validation in the domain layer. Sometimes it is just not any entity's responsibility, consider domain service or specification object.
#file: OrderUnitTest
#Test public void should_change_to_valid_when_xxxx() {
Client client = new ClientFixture()...build()
BillCycle[] cycles = new BillCycleFixture()...build()
Order order = new OrderFixture()...build();
Specification<Order> spec = new ValidOrderSpec(clientRepository, cycleRepository);
given(clientRepository).findBy(client.getId()).thenReturn(client);
given(cycleRepository).findAll().thenReturn(cycles);
subject.validate(spec);
assertThat(order.getStatus(), is(VALID));
}
#file: DiscountProcessor
#Test public void should_change_to_valid_when_xxxx() {
Order order = new OrderFixture()...build()
Specification<Order> spec = mock(ValidOrderSpec.class);
DiscountProcessor subject = ...
given(orderingService).validSpec().thenReturn(spec);
given(spec).isSatisfiedBy(order).thenReturn(true);
given(orderRepository).findBy(order.getId()).thenReturn(order);
subject.processOrder(order.getId());
assertThat(order.getStatus(), is(VALID));
}
Do the 3 possible states reflect your domain or is that just extrapolation ? I'm asking because your sample code doesn't seem to change Order state but throw an exception when it's invalid.
If it's acceptable for the order to stay DRAFT for a short period of time after being submitted, you could have DiscountOrder emit a DiscountOrderSubmitted domain event. A handler catches the event and (delegates to a Domain service that) examines if the submit is legit or not. It would then issue a ChangeOrderState command to make the order either VALIDATED or INVALID.
You could even suppose that the change is legit by default and have processOrder() directly take it to VALIDATED, until proven otherwise by a subsequent INVALID counter-order given by the validation service.
This is not much different from your third solution or Hippoom's one though, except every step of the process is made explicit with its own domain event. I guess that with your current aggregate design you're doomed to have a third party orchestrator (as un-DDD and transaction script-esque as it may sound) that controls the process, since the DiscountOrder aggregate doesn't have native access to all information to tell if a given transformation is valid or not.
I'm using rooms at the moment however I think the way I'm going about using them isn't practical. This is a portion of my code.
// Add clients that are to be notified to the users room.
for(var c in clients)
{
if(_.indexOf(data.notify, clients[c].id) != -1)
{
clients[c].socket.join(data.user_id);
}
}
// Emit to all that are now in the room.
io.sockets.in(data.user_id).emit('notification', data);
// Remove everyone from this users room so it's free for the next notification.
for(var c in clients)
{
if(clients[c].id in data.notify)
{
clients[c].socket.leave(data.user_id);
}
}
So as you can see I add the correct clients to a room which is an ID of a user who has updated something. Then once I emit the notification to the group I remove all the clients once more from the room to keep it free.
Is there a better way of going about this?