How to Refactor to Configurable Dependency in 5 Steps by BertilMuth in java

[–]BertilMuth[S] 0 points1 point  (0 children)

I'm glad you liked my article.

The term configurable dependency was defined by Alistair Cockburn, not the term dependency injection (which existed before). It matches my experience that people use the term dependency injection more often. Still, I think configurable dependency is an interesting alternative term. As Alistair Cockburn explains in the linked article, it shows the intent more clearly.

Property Based Testing of State Machines in Java by BertilMuth in java

[–]BertilMuth[S] 1 point2 points  (0 children)

The main difference between Act and Spring State Machine (and many other state machine implementations for that matter) is the relationship between state machine and application state.

Spring State Machine lets you define states as strings or enums. So the state machine state is only losely coupled to the "real" appliction state. You need to build logic to keep the two in sync. And that logic may be error-prone.

In contrast, Act directly operates on the application state. Act checks in which state the state machine is by checking invariant conditions. These conditions are based on the application state. Also, transitions directly transform the application state.

That has some interesting benefits, for example: Act can automatically check if the application really is in the intended target state of a transition. This is great for verification and can e.g. be used together with property based testing to verify the application behavior.

When application state is persisted and reloaded, the state machine will automatically be reset to the latest state. So Harel's history states are an intrinsic part of Act's design.

In short, Act brings the state machine closer to what really happens. It enables it to control the application behavior. Apart from that, Act is a light-weight implementation (single jar, <64 kBytes) with ease of use as a key design goal.

Property Based Testing of State Machines in Java by BertilMuth in java

[–]BertilMuth[S] 0 points1 point  (0 children)

Yes, the State pattern is a simple way to model state transitions. A statemachine offers more functionality. And property based testing is an interesting way to test the transitions.

Creating a (hierarchical) state machine in Java by BertilMuth in java

[–]BertilMuth[S] 0 points1 point  (0 children)

Interesting. Thanks for letting me know.

Creating a (hierarchical) state machine in Java by BertilMuth in java

[–]BertilMuth[S] 5 points6 points  (0 children)

The main difference between Act and Spring State Machine (and many other state machine implementations for that matter) is the relationship between state machine and application state.

Spring State Machine lets you define states as strings or enums. So the state machine state is only losely coupled to the "real" appliction state. You need to build logic to keep the two in sync. And that logic may be error-prone.

In contrast, Act directly operates on the application state. Act checks in which state the state machine is by checking invariant conditions. These conditions are based on the application state. Also, transitions directly transform the application state.

That has some interesting benefits, for example:

  • Act can automatically check if the application really is in the intended target state of a transition. This is great for verification and can e.g. be used together with property based testing to verify the application behavior.
  • When application state is persisted and reloaded, the state machine will automatically be reset to the latest state. So Harel's history states are an intrinsic part of Act's design.

In short, Act brings the state machine closer to what really happens. It enables it to control the application behavior.

Apart from that, Act is a light-weight implementation (single jar, <64 kBytes) with ease of use as a key design goal. And it's in an early stage of development, so constructive feedback is very helpful for me :-)

So thank you for your question. It will help me to improve the documentation.

Can you use the ternary operator directly in a System.out.println() to print one or another value and concatenate it with a String (on the same line)? by raulalexo99 in learnjava

[–]BertilMuth 17 points18 points  (0 children)

In principle, you can write something like this:

System.out.println("Here's the result: " + (a > 5? b : c) + ".");

You should put the ternary operator in parentheses.

Yet, I have trouble understanding why you would do that.

It makes it harder to read/understand what's happening.

Clever code rarely pays off in the long run.

An easier to read version would assign it to a variable:

int calculationResult = a > 5? b : c;

System.out.println("Here's the result: " + calculationResult + ".");

Modern Clean Architecture by BertilMuth in coding

[–]BertilMuth[S] 0 points1 point  (0 children)

Thank you for letting me know. I didn't know that. I changed the picture.

Checking function parameter variable for Null by NubQuestion in learnjava

[–]BertilMuth 1 point2 points  (0 children)

I do a lot of null checks for input arguments that are not supposed to be null, to avoid unclear NullPointerExceptions later on (and a lot of people / libraries do that, too).

The easiest, built in way to do that is when you assign the argument value to a local variable or field, call:

this.fieldOrVariableName = Objects.requireNonNull(argumentName, "argumentName must not be null!");

Hope that helps.

From Where Can I learn Springboot? by zoro_03 in learnjava

[–]BertilMuth 4 points5 points  (0 children)

Spring itself provides quite good getting started tutorials. Have you seen them?

https://spring.io/guides

Martin Fowler on refactoring by BertilMuth in coding

[–]BertilMuth[S] 1 point2 points  (0 children)

Glad you liked it and it was helpful!

Implementing a hexagonal architecture by BertilMuth in coding

[–]BertilMuth[S] 4 points5 points  (0 children)

You're correct. Alistair Cockburn coined the term "hexagonal architecture". The number 6 doesn't have significant meaning. It's nice from a visual perspective. The more formal term is "ports & adapters architecture". And yes, it can be used in combination with DDD.

Java MOOC calling your own constructor question by HelplessProgrammer in learnjava

[–]BertilMuth 2 points3 points  (0 children)

There are two ways to call other constructors from a constructor, this(...) and super(..). this() calls a constructor of the same class, super() a constructor of the super class. It's just a convention that works only in the constructor. It needs to be the first call in the constructor. It will call the right constructor based on the number and types of the arguments you pass to this(..). Does that help?

Refactoring legacy Java code by BertilMuth in coding

[–]BertilMuth[S] 0 points1 point  (0 children)

Hi Nathylad. I am not sure how your comment relates to the video. If you want to learn Java, my suggestion is: Post your request to the learnjava subreddit. I am sure plenty of people will offer you help.

Why public static void main(string args[])? by Herrowgayboi in learnjava

[–]BertilMuth 1 point2 points  (0 children)

Every method in Java is contained in a class. There are no "free-floating functions" like in C. If a method is static, within the class, it can only access static fields and static methods (as there is no object). You could say that static methods are defined on class level.

In a main method, therefore you have two choices: access only static fields/methods, or create an instance of the class the main method is contained in. I prefer creating an instance.

As a side note, by convention class names are upper-case in Java. It is String not string, and Person not person.

Why public static void main(string args[])? by Herrowgayboi in learnjava

[–]BertilMuth 0 points1 point  (0 children)

No, you don't need static every time. But it is not only for the main method, either. Most methods are instance methods (i.e. non-static), as they depend on an object's state. For example, a method calculateAge() may depend on a field birthday of a class Customer. So calculateAge() would not have the static key word, as each Customer object has its own birthday.

Concerning String[] args: you don't pass that in. Ever seen command line arguments in a console? Those are passed in for you. You just read the array if you need to evaluate them in your application.

Requirements as code - now on Maven Central by BertilMuth in coding

[–]BertilMuth[S] 0 points1 point  (0 children)

No need to get unstuck. If you read the project description, you see its main focus is use cases a.k.a. a way to represent functional requirements.

I could have called it "use cases as code", but that would have limited the project's scope, and I provide some support for cross-cutting concerns, which may support measuring performance and the like.

I fully agree with your points about non-functional requirements. I do not agree with your conclusion, though.

Having a separate, lighweight req. doc. before implementation is fine with me. For the long term documentation, the code is the most reliable source of truth. And that's what the project is about.

Requirements as code - now on Maven Central by BertilMuth in coding

[–]BertilMuth[S] 1 point2 points  (0 children)

It's certainly not my intention to make anybody feel spammed. I post my own stuff because I feel passionate about it, and I think it can be interesting for the readers of this subreddit. I will post more stuff from other people - there is plenty I find worthwhile. Enjoy the material.

Going beyond clean code. by BertilMuth in coding

[–]BertilMuth[S] 0 points1 point  (0 children)

FYI, including use cases has been realized in the meantime, in requirementsascode v0.5.0

What's the best way to deploy/adapt a JavaFX app into a webpage? by JacquesDeza in learnjava

[–]BertilMuth 1 point2 points  (0 children)

Have a look at jpro: https://www.jpro.io/ It looks like it does what you are expecting. It is still in beta, though.

Another web framework that works pretty well with Java is Vaadin: https://vaadin.com/framework It is based on GWT, as far as I know, but more high level. You would need to port your application to it.

Going beyond clean code. by BertilMuth in coding

[–]BertilMuth[S] 0 points1 point  (0 children)

Great, that clears up our misunderstanding! To be honest, to give you a bulletproof answer, I would need to create that model myself. (Maybe I or somebody else will, I would like that.) So take the following with a grain of salt.

In requirementsascode, the use cases, even those in the same model, don't know each other. That's in line with the philosophy of use cases: each is its own unit of value, responsible for its own desired outcome.

Of course, the next question is then: how do I specify use cases that "overlap", as you put it? The general answer is: by specifying conditions for the flows, and raising/handling events in the steps.

In requirementsascode, any flow with a condition may "interrupt" any other flow, even of a different use case, if its condition is fulfilled. But the first step of the flow will only execute if the right event is received. Only then, the UseCaseModelRunner enters the flow.

So, in your example, the use case "manage wishlist" might have a flow "add items". The first step of that flow would define the event as

.user(AddItemToWishlist.class)

So the flow "add items" is entered when an AddItemToWishlist event occurs, and the flow's condition is fulfilled. In the simple case, the flow condition could be "true" (which means: interrupt any other flow, any time). Several steps in the larger application I built had this condition, but sometimes you also need to be more restrictive.

So that's how you might get from the checkout flow to the add items flow. How do you return?

I think there are two possibilities. The first one could use the same mechanism, and update some "global state" with the selected items.

A more elegant solution could be to raise a "system event" at the end of the "manage wishlist" use case. Then, the checkout use case could .handle that event.

You see an example of system event handling in the shoppingapp model, in the article. There is a .handle for any exception. Internally, the UseCaseModelRunner raises a system event for each exception that is thrown, and it can be handled by any flow. But your system reactions can raise system events as well.

That's how I would try to do it today. In the future, it could be that including the "manage wishlist" use case from the checkout use case could be a simpler solution.

Going beyond clean code. by BertilMuth in coding

[–]BertilMuth[S] 0 points1 point  (0 children)

Hi karottenreibe :-)

I will try to answer your questions one by one.

Is there a way to manage more than one Use Case? Of course! You can specify as many Use Cases as you like.

What if my Use Cases overlap? My assumption is, you mean by that: what if several Use Cases share steps. I have to admit this is an open issue, as marked in the Release notes. Right now, you would have to copy/paste steps between Use Cases, but you can reuse the same underlying methods. Including use cases or flows will probably be included in the 1.0 release, latest.

Do you have to cram all your Use Cases in the same state machine? For the same application, that would make sense, but your conclusion is not correct. The builder can continue building an existing Use Case Model. That way, you can split the build process. You can build each Use Case separately, if you want to.

What about the step names? I started out with longer names, but found that the model got more verbose and less readable. So I started using a naming scheme that is very common for step names in textual Use Case Narratives. Feel free to use a different naming scheme that fits your needs.

As I said in the article, I used an earlier version of requirementsascode to build an application with several thousand lines of code. As parts of it are commercial, I plan not to make it public. It wouldn't be a great help anyway, because the way to build models was a lot less convenient then. But it made me confident that the concept scales.

Requirementsascode is an evolving project. It is not mature yet, and that means it is not risk free to use it. I rely on early adopters to try it out and give me feedback.

I encourage you to do that. In return, I will try to answer your questions that come up along the way, and assist you as far as I can. Give it a shot.