I was wondering, how can one represent "if" statement on a collaboration diagram?
if (somethingShouldBeDone) {
//multiple conditions
// Do it
} else {
// Do something else
}
Can it be represented at all? The thing is ... in my code, fair amount of conditions are checked to determine a variety of actions. If i am going to show the actions, I'd like to explicitly state that actions are caused by particular events.
If possible create an image representation of a solution.
You may use guards for representing the conditions that must be true for a message to be passed.
The following example is equivalent to
if (x<y) {
object2.message1();
object3.message3();
} else {
object2.message2();
}
Related
I want to check a condition that depends only on its structure (but not the actual values it holds), and do something in either case. I can think of three ways do this: with match, if let, or if matches!. I'm not sure if there are any drawbacks to any of these or if they are effectively equivalent.
Am I safe to use any of these or are there known drawbacks that I might run into with one or more of these? Is there a fourth way that I haven't thought of?
match self.context.get(s) {
Some(Bound::Function(_, _)) => Err("Parse Error".to_string())
_ => {
self.context.insert(s.clone(), ...);
Ok(None)
}
}
if let Some(Bound::Function(_, _)) = self.context.get(s) {
Err("Parse Error".to_string())
}
else {
self.context.insert(s.clone(), ...);
Ok(None)
}
if matches!(self.context.get(s), Some(Bound::Function(_, _))) {
Err("Parse Error".to_string())
}
else {
self.context.insert(s.clone(), ...);
Ok(None)
}
Your three solutions are equivalent. As of today they even compile to the same machine code: https://godbolt.org/z/d4acvY5G3
Performance-wise, you would need to benchmark but I suspect that the fastest would be to use the entry API. Something along the lines of:
match self.context.entry (s) {
Entry::Occupied (_) => Err("Parse Error".to_string()),
Entry::Vacant (e) => {
e.insert (Bound::Number(evaluate(&self.context, parseadd(tokens))?));
Ok (None)
}
}
Note that depending on the rest of your code, this solution might require to always clone s whereas yours don't clone it if the entry already exists. However:
Your solutions only avoid cloning when an error occurs, which should be a rare occurrence and less performance-sensitive than the non-error case.
If performance is really an issue, it would probably be best to avoid cloning altogether if possible (but that depends on where s comes from).
As with all performance-related questions, you should measure it in your environment to see if it brings any significant improvement (and you should only try to improve it after you have shown that it is a performance bottleneck for your application).
I'm trying to apply ubiquitous language to my domain objects.
I want to convert a Data Transfer Object coming from a client into the domain object. The Aggregate's Constructor only accepts the required fields, and the rest of parameters should be passed using aggregate's API even when the Aggregate is being created(by say CreateAggregate command).
But the DTO to Aggregate mapping code becomes a bit messy:
if(DTO.RegistrantType == 0){
registrantType = RegistrantType.Person()
}
elseif(DTO.RegistrantType == 1){
registrantType = RegistrantType.Company()
}
//.....
//.....
var aggregate = new Aggregate(
title,
weight,
registrantType,
route,
callNumber,
)
//look at this one:
if(DTO.connectionType == 0){
aggregate.Route(ConnectionType.InCity(cityId))
}
elseif(DTO.connectionType == 1){
aggregate.Route(ConnectionType.Intercity(DTO.originCityId,DTO.DestinationCityId)
}
//..........
//..........
One thing I should mention is that this problem doesn't seem a domain specific problem.
How can I reduce these If-Else statements without letting my domain internals leakage, and with being sure that the aggregate(not a mapping tool) doesn't accept values that can invalide it's business rules, and with having the ubiquitous language applied?
Please don't tell me I can use AoutoMapper to do the trick. Please read the last part carefully.'
Thank you.
A typical answer would be to convert the DTO (which is effectively a message) into a Command, where the command has all of the arguments expressed as domain specific value types.
void doX(DTO dto) {
Command command = toCommand(dto)
doX(command)
}
void doX(Command command) {
// ...
aggregate.Route(command.connectionType)
}
It's fairly common for the toCommand logic use something like a Builder pattern to improve the readability of the code.
if(DTO.connectionType == 0){
aggregate.Route(ConnectionType.InCity(cityId))
}
elseif(DTO.connectionType == 1){
aggregate.Route(ConnectionType.Intercity(DTO.originCityId,DTO.DestinationCityId)
}
In cases like this one, the strategy pattern can help
ConnectionTypeFactory f = getConnectionFactory(DTO.connectionType)
ConnectionType connectionType = f.create(DTO)
Once that you recognize that ConnectionTypeFactory is a thing, you can think about building lookup tables to choose the right one.
Map<ConnectionType, ConnectionTypeFactory> lookup = /* ... */
ConnectionTypeFactory f = lookup(DTO.connectionType);
if (null == f) {
f = defaultConnectionFactory;
}
So why don't you use more inheritance
for example
class CompanyRegistration : Registration {
}
class PersonRegistraiton : Registration {
}
then you can use inheritance instead of your if/else scenario's
public class Aggregate {
public Aggregate (CompanyRegistration) {
registantType = RegistrantType.Company();
}
public Aggregate (PersonRegistration p) {
registrantType = RegistrantType.Person();
}
}
you can apply simmilar logic for say a setRoute method or any other large if/else situations.
Also, i know you don't want to hear it, you can write your own mapper (inside the aggegate) that maps and validates it's business logic
for example this idea comes from fluentmapper
var mapper = new FluentMapper.ThatMaps<Aggregate>().From<DTO>()
.ThatSets(x => x.title).When(x => x != null).From(x => x.title)
It isn't too hard to write your own mapper that allow this kind of rules and validates your properties. And i think it will improve readability
Wondering if there is a way I can use sql.eachRow like a generator, to use it in a DSL context where a Collection or Iterator is expected. The use case I'm trying to go for is streaming JSON generation - what I'm trying to do is something like:
def generator = { sql.eachRow { yield it } }
jsonBuilder.root {
status "OK"
rows generator()
}
You would need continuation support (or similiar) for this to work to some extend. Groovy does not have continuations, the JVM also not. Normally continuation passing style works, but then the method eachRow would have to support that, which it of course does not. So the only way I see is a makeshift solution using threads or something like that. So maybe something like that would work for you:
def sync = new java.util.concurrent.SynchronousQueue()
Thread.start { sql.eachRow { sync.put(it) } }
jsonBuilder.root {
status "OK"
rows sync.take()
}
I am not stating, that this is a good solution, just a random consumer-producer-work-around for your problem.
I'm confused by the terminology in ListChangeListener.Change in JavaFX. I had an observable list and called set(index,newValue) on the list.
On the resulting change I observed the following change attributes:
wasRemoved() == true
wasReplaced() == false
wasUpdated() == false
Thankfully, getAddedSublist() contained the new value but I would have expected wasReplaced or wasUpdated to be true.
What change would these two fields be true?
My own stupid mistake. I copied the example from the Javadocs and added several else if blocks, e.g.
if(change.wasAdded()) {
//doAdd
} else if (change.wasRemoved()) {
//doRemove
} else if (change.wasReplaced()) {
//doReplace
}
doReplace() was never getting called because it was an else if and not an if. Thanks to #ftkg for the advice to get me here.
I thought that I had come across this before, but I can't remember when or what language it was.
Basically if I have the following in C#:
someCondition = true
if(someCondition)
{
// Do Something
if(anotherCond) {
someCondition = false;
continue;
}
// Do Something Else
}
In C# this will break out of the body of the if statement when someCondition changes, meaning that //DO Something Else only gets processed if someCondition doesn't change...
Is there a language that will do the interior if statement checking/continue automatically i.e. be able to write:
someCondition = true
if(someCondition)
{
// Do Something
if(anotherCond){
someCondition = false;
}
// Do Something Else
}
with the same behaviors as the previous? Obviously there are multiple ways to get this behavior in every language conceivable, what I am interested in is if there is a language that by design has this functionality.
Edit: Reduced the examples so hopefully people can see what is happening, when someCondition changes (i.e. the condition that the if statement relied on to begin, we should break out of the remaining if statement. I am not looking for a way to do this in C#, or any particular language, but for a language that does this automatically.
You can create a property in C# that throws an exception on any condition you set, aka truth=true. The exception will break out of the loop to wherever you have your catch.
An example in C#:
public class MyException : Exception { }
public bool truth
{
get { return _truth; }
set
{
_truth = value;
if(value)
throw new MyException();
}
}
bool _truth;
I think you can simulate what you want in C# like so:
void ExecuteWhile( Func<bool> condition,
IEnumerable<Action> executeWhileTrue,
IEnumerable<Action> executeWhileFalse)
{
if (condition())
{
foreach (Action action in executeWhileTrue)
{
action();
if (!condition())
return;
}
}
else
{
foreach (Action action in executeWhileFalse)
{
action();
if (condition())
return;
}
}
}
and then use it as such:
truth = true;
while (true) // loop forever
{
ExecuteWhile( () => truth,
new List<Action> { () => { /* do something that might set truth to false*/},
() => { /* do something else*/}},
new List<Action> { () => { /* do something that might set truth to true*/},
() => { /* do something else*/}});
}
And to answer your question: no, I don't think there is a language with this as a build-in feature.
As far as I understood, the following is wanted:
if (cond) {
A;
B;
C;
}
shall behave as if written thus:
if (cond) {
A;
if (cond) {
B;
if (cond) {
C
}
}
}
IMHO, this would be a silly feature, unlikely to be implemented in any language except maybe in INTERCAL.
Why do I think that?
Well, suppose someone wants to refactor the code and moves B;C to a subroutine.
if (cond) {
A;
BC();
}
subroutine BC() { B;C }
The block - according to our feature - will mean as before:
if (cond) {
A;
if (cond) BC();
}
But what about our subroutine? The language designer has 2 choices here:
Treat the call BC() as atomic, i.e. in the subroutine, the
condition cond is not checked before statement C. This would mean
such a simple refactoring would change the meaning of the program
drastically.
Somehow pass the information that every statement must be guarded
with cond to the subroutine so that the behaviour of our block remains
unchanged. This, of course, leads to the silly situation that the
behaviour of any subroutine would depend upon the context it was
called in. A subroutine with n atomic statements would have n possible ways to behave even if it had no arguments and would not use non local mutable state explicitely, depending on how many of the statements would be actually executed. (Note that nowadays the trend is to minimize the most often harmful effects of shared non-local state. OO languages do it with encapsulation, FP languages by banning mutable state altogether.)
In any case, no matter how the language designer decides, we would have a feature that is the direct contradiction of the principle of the least surprise. It is clear that programs in such a language would be utterly hard to maintain.
If you broke you big bunch if/else statements into succinct little methods which tested each little piece of the puzzle, you could rely on the compilers short circuit boolean evaluation
I'm not sure if that helps as your example is a big vague. You don't say if you're doing any processing or if it's just a bunch of checks. Either way, breaking your code into smaller methods may help you out.
You can use a do..while loop:
do
{
} while (truth == true);
thats if i've understood correctly!
You say while true... but while what is true. I would think your loop will run infinitely regardless of the language used. Assuming true will be a real condition... I would say just set the exit condition in one of the if blocks. You question is a bit hard to understand. Also the continue is unnecessary.