I'm trying to create a diagrams of user interactions. In many cases I have to take some arguments like: mousePosition.x or touchDown.duration etc, and pass it through some f(x) function to render different UI using these arguments as interface properties.
Let's take an example of basic slider interface. [-----o-----]
I want to diagram a simple behavior of manipulating slider's knob. My logic is as follows:
pre condition: mousePosition.x = knobPosition.x; knobPosition.x = n
event: mosuseDown
event: mouseMove.x
if knobPosition.xMin < mousePosition.x < knobPosition.xMax
render: knobPosition.x = mousePosition.x
if ( mousePosition.x > knobPosition.xMax )
render: knobPosition.x = knobPosition.xMax
if ( mousePosition.x < knobPosition.xMin )
render: knobPosition.x = knobPosition.xMin
My first thought was to diagram this behavior through State Machine, although it becomes messy for more complex examples. Maybe there is some modeling language that was design to model these kind of behaviors?
Your logic is a kind of decision tree. This can best be modeled using an activity diagram. Each if-statement is a decision symbol in the diagram.
Related
Following a functional programming paradigm, I have a CQRS architecture with event sourcing as the main persistence mechanism.
Currently my aggregates consist of
a set of command handlers (behavior)
a reducer to fold events to the current aggregate state (data)
A command handler does
fetch the event stream for a given aggregateId
folds the current aggregate state
applies some business logic based on the current state
persist any events created in step 3
Example of a command handler
type CommandHandler = (
state: AggregateState,
command: Command
) => E.Either<Err.Err, DomainEvent[] | void>;
Basically steps 1, 2 and 4 are abstracted away in a generic function:
// pseudo-code
const wrapCommandHanler = (handler: CommandHandler) => {
return wrapped = (command: Command) => {
const events = fetchEvents();
const state = applyReducer(events);
const newEvents = handler(state, command);
persistEvents(newEvents);
}
}
So my command handlers are quite lean and focused and only contain the business logic.
I read about DDD, but the given examples were following a OOP paradigm. In these examples the command handler would call an aggregate method where the aggregate is a class that contains state and domain logic.
But in my case the aggregate state and behavior is separated and my command handlers ARE the aggregate behavior. So my command handlers contain the domain logic.
My question(s):
Is this approach "correct" / valid DDD or am I shooting myself in the foot with this? If not, what is the main purpose of separating an aggregate function and a command handler?
You'll probably want to review Jérémie Chassaing's recent work on Decider
My question(s): Is this approach "correct" / valid DDD or am I shooting myself in the foot with this?
It's fine - there's no particular reason that you need your functional design to align with "Java best practices" circa 2003.
If not, what is the main purpose of separating an aggregate function and a command handler?
Primarily to create a clear boundary between the abstractions of the problem domain (ex: "Cargo Shipping") and the "plumbing" - the application logic that knows about I/O, messaging, databases and transactions, HTTP, and so on.
Among other things, that means you can take the aggregate "module" (so to speak) and move it to other contexts, without disturbing the relationships of the different domain functions.
That said, there's nothing magic going on - you could refactor your "functional" design and create a slightly different design the gives you similar benefits to what you get from "aggregates".
When doing pure functional DDD, the commands (I'm deliberately not using "object") correspond to the methods of an aggregate (if using types, you can say that the type corresponds to the interface and each instance to an invocation; the ultimate handler function corresponds to the body of the method).
Technically, if event sourcing, it's the pas de deux of the command and event handler which define the aggregate, though the command handler probably carries more of the load.
These two definitions of an aggregate in Scala are effectively the same thing. For the OO-style, I'm using a more "durable state" approach and the FP-style is event-sourced (OO-style event-sourced (aggregate methods return a Seq[Event] and you have some means of defining event handlers) and FP-style durable-state (no EventHandler and the command handler returns a State) are both possible, but IME feel unnatural). Both are equivalently unit-testable (event-sourced arguably moreso, especially for property-based testing):
// Note that Map here is an immutable Map (i.e. a value object)
// Domain has been simplified: assume that Item includes price and there are no discounts etc.
// OO and "durable state"-style persistence... application basically loads a cart from persistence, maps external commands into method calls, saves cart
class ShoppingCart(val itemCounts: Map[Item, Int], val checkedOut: Boolean = false) {
def addItem(item: Item, qty: Int): Unit =
// Collapsing the failed validations into a single do-nothing case
if (!checkedOut && qty > 0) {
itemCounts.get(item) match {
case Some(count) =>
itemCounts = itemCounts.updated(item, count + qty)
case None =>
itemCounts = itemCounts + (item -> qty)
}
}
def adjustQtyOfItem(item: Item, newQty: Int): Unit =
if (!checkedOut && itemCounts.contains(item)) {
newQty match {
case neg if neg < 0 =>
// do nothing
()
case pos if pos > 0 =>
itemCounts = itemCounts.updated(item, newQty)
case 0 =>
itemCounts = itemCounts - item
}
}
def removeAllOfItem(item: Item): Unit =
adjustQtyOfItem(item, 0)
def checkOut(): Unit =
if (!checkedOut) {
checkedOut = true
}
}
// FP and event-sourced persistence
object ShoppingCart {
case class State(itemCounts: Map[Item, Int], checkedOut: Boolean)
sealed trait Command
case class AddItem(item: Item, qty: Int) extends Command
case class AdjustQtyOfItem(item: Item, newQty: Int) extends Command
case object CheckOut extends Command
val RemoveAllOfItem: Item => Command = AdjustQtyOfItem(_, 0)
sealed trait Event
case class ItemsAdded(item: Item, qty: Int) extends Event
case class ItemsRemoved(item: Item, qtyRemoved: Int) extends Event
case class AllOfItemRemoved(item: Item) extends Event
case object CheckedOut extends Event
val CommandHandler: (State, Command) => Seq[Event] = handleCommand(_, _)
val EventHandler: (State, Event) => State = handleEvent(_, _)
val InitialState = State(Map.empty, false)
private def handleCommand(state: State, cmd: Command): Seq[Event] =
if (!state.checkedOut) {
cmd match {
case AddItem(item, qty) if qty > 0 => Seq(ItemAdded(item, qty))
case AdjustQtyOfItem(item, newQty) if state.itemCounts.contains(item) && newQty >= 0 =>
val currentQty = state.itemCounts(item)
if (newQty > currentQty) {
handleCommand(state, AddItem(item, newQty - currentQty))
} else if (newQty == 0) {
Seq(AllOfItemRemoved(item))
} else {
Seq(ItemsRemoved(item, currentQty - newQty))
}
case CheckOut => Seq(CheckedOut)
case _ => Seq.empty
}
} else Seq.empty
private def handleEvent(state: State, evt: Event): State =
evt match {
case ItemsAdded(item, qty) =>
state.get(item)
.map { prevQty =>
state.copy(itemCounts = state.itemCounts.updated(item, prevQty + qty))
}
.getOrElse {
state.copy(itemCounts = state.itemCounts + (item, qty))
}
case ItemsRemoved(item, qtyRemoved) =>
state.get(item)
.map { prevQty =>
state.copy(itemCounts = state.itemCounts.updated(item, prevQty - qtyRemoved))
}
.getOrElse(state)
case AllOfItemRemoved(item) =>
state.copy(itemCounts = state.itemCounts - item)
case CheckedOut =>
state.copy(checkedOut = true)
}
}
Part of the confusion probably stems from "command handler" having a specific meaning in the application layer (where it's something from outside) and a slightly different meaning in the context of an event-sourced aggregate (the application layer command handler in an event-sourced application is basically just an anti-corruption layer translating external commands into commands against the aggregate (for instance the commands against the aggregate probably shouldn't contain an ID for the aggregate: the aggregate knows its ID)).
Is this approach "correct" / valid DDD or am I shooting myself in the foot with this?
DDD is based on two principles :
You should model your business logic (BL) using OOP in a "domain layer"
The domain layer contains the BL, the whole BL and nothing but the BL
By putting your business logic in your reducers you have failed the DDD principles and have achieved an anemic domain model. Your domain is indeed so anemic that it is even not modeled using OOP. This is important because by doing so, you violate the single responsibility principle (SRP) by having your reducers having two responsibilities : translating a series of event into state and validating business rules.
If not, what is the main purpose of separating an aggregate function and a command handler?
With the query handlers, command handlers implement parts of the interface specification, and lies in the application layer. It receive information from the clients (commands) and does some low level validation (for instance, reject malformed messages or unauthenticated requests). The command handler then calls other layers for them to do their job: the infrastructure layer for event store access, reducers for event to aggregates translation, and the domain layer for business rules validation and integrity. The code in these handlers is application specific as another application in the same domain will inherently have different interface specification and different commands to handle.
Aggregates are responsible for business logic and business rules. It is an abstraction of the actual concepts you are trying to manipulate. Good domain modeling try to be as application ignorant as possible, in order to increase reusability. A domain model could be used for multiple applications that does similar business. Whether you implement a piece of software used by pharmacists when delivering medications, or another one used by medicine doctors to prescribe them, you can use the same domain layer modeling drug interactions. Using OOP in your domain layer allows to model very complex business logic using very simple code. By putting the business logic in a separate layer, you can have a small team of developers working closely with business experts of the matter, to model all the business logic, constraints and processes, relevant to a set of applications. You can even unit test your domain.
Please note that your approach is perfectly acceptable, and can be very efficient. Doing DDD for the purpose of doing DDD is not a good practice. Doing good DDD modeling is not an easy task and should be considered as a mean of reducing complexity of large domain models.
I am trying to create a wall with 2 layers and each layer materials are different. When I try to set the CompoundStructure for the wall I am getting an exception that CompoundStructure is not valid.
CompoundStructure cStructure = CompoundStructure.CreateSimpleCompoundStructure(clayer);
wallType.SetCompoundStructure(cStructure);
Can anyone tell me how I can create compound structure for layers with different materials?
First of all, solve your task manually through the end user interface and verify that it works at all.
Then, use RevitLookup and other database exploration tools to examine the results in the BIM elements, their properties and relationships.
Once you have done that, you will have a good idea how to address the task programmatically – and have confidence that it will work as expected:
How to research to find a Revit API solution
Intimate Revit database exploration with the Python Shell
newWallMaterial = wallMaterial.Duplicate("newCreatedMaterial");
newWallmaterial2 = wallMaterial.Duplicate("NewCreatedMAterial2");
//roofMaterial3 = roofMaterial2.Duplicate("NewCreatedMAterial3");
bool usr = newWallMaterial.UseRenderAppearanceForShading;
//newWallMaterial.Color = BuiltInTypeParam.materialCol;
foreach (Layers layer in layers)
{
if (layer.layerId == 0)
{
c = new CompoundStructureLayer(layer.width, layer.materialAssignement, newWallMaterial.Id);
newWallMaterial.Color = color;
clayer.Add(c);
}
if (layer.layerId == 1)
{
c1 = new CompoundStructureLayer(layer.width, layer.materialAssignement, newWallmaterial2.Id);
newWallmaterial2.Color = color;
clayer.Add(c1);
}
Say I have a game scene, CarLevelScene which is a level where I have to drive a car a certain distance. I have a "distance remaining" gauge in one corner of the scene and a "fuel remaining" gauge in another corner. In favor of single responsibility, I want to extract this from the CarLevelScene js file. In addition, on update, both of these gauges depend on some shared data (since fuel depends on distance traveled).
Right now, I essentially do something like this:
let fuelGuageState;
let distanceGuageState;
export default class CarLevelScene {
init() {
fuelGuageState = new FuelGuageState(this); // have to pass in this to create game objects in the scene. Or do I?
distanceGuageState = new DistanceGuageState(this);
}
create() {
fuelGuageState.create();
distanceGuageState.create();
}
update() {
...
let distance = someCalc(...); // possibly from some distance model object
let fuel = someOtherCalc(distance, ...);
fuelGaugeState.update(fuel);
distanceGaugeState.update(distance);
}
}
My question is, is this the conventional way to create and use components in Phaser 3? Essentially, it would make the scene an organizer of components that simply feed the correct data to each update method. It feels a bit smelly. There's temporal coupling and a lot of dependency management.
Are there official docs that deal with the appropriate organization of components in code?
Below is a working code of a ToolbarButton in Genie. The objective is to get the uri for the chosen file and return it back to the construct/init of the class. The problem is that in all examples I’ve come across global _variables are used (as shown in the code below). It looks unintuitive and I fear that whenever the code gets larger, it will become more difficult to remove bugs, since these variables will start to accumulate. Is any other way of making the function openfile return the uri to a regular variable within the construct/init of the class?
Here is the code:
uses
Granite.Widgets
Gtk
init
Gtk.init (ref args)
var app = new Application ()
app.show_all ()
Gtk.main ()
// This class holds all the elements from the GUI
class Application : Gtk.Window
_view:Gtk.TextView
_uri:string
construct ()
// Prepare Gtk.Window:
this.window_position = Gtk.WindowPosition.CENTER
this.destroy.connect (Gtk.main_quit)
this.set_default_size (400, 400)
// Headerbar definition
headerbar:Gtk.HeaderBar = new Gtk.HeaderBar()
headerbar.show_close_button = true
headerbar.set_title("My text editor")
// Headerbar buttons
open_button:Gtk.ToolButton = new ToolButton.from_stock(Stock.OPEN)
open_button.clicked.connect (openfile)
// Add everything to the toolbar
headerbar.pack_start (open_button)
show_all ()
this.set_titlebar(headerbar)
// Box:
box:Gtk.Box = new Gtk.Box (Gtk.Orientation.VERTICAL, 1)
this.add (box)
// A ScrolledWindow:
scrolled:Gtk.ScrolledWindow = new Gtk.ScrolledWindow (null, null)
box.pack_start (scrolled, true, true, 0)
// The TextView:
_view = new Gtk.TextView ()
_view.set_wrap_mode (Gtk.WrapMode.WORD)
_view.buffer.text = "Lorem Ipsum"
scrolled.add (_view)
def openfile (self:ToolButton)
var dialog = new FileChooserDialog ("Open file",
this,
FileChooserAction.OPEN,
Stock.OK, ResponseType.ACCEPT,
Stock.CANCEL, ResponseType.CANCEL)
//filter.add_pixbuf_formats ()
//dialog.add_filter (filter)
case dialog.run()
when ResponseType.ACCEPT
var filename = dialog.get_filename()
//image.set_from_file(filename)
if (dialog.run () == Gtk.ResponseType.ACCEPT)
_uri = dialog.get_uri ()
stdout.printf ("Selection:\n %s", _uri)
dialog.destroy ()
Or shouldn't I worry at all about _variables accumulating?
First a note on terminology and then a generalisation.
A "global variable" can be accessed any where in your program, so its scope is global. The _variables you are referring to in your question are private fields within the scope of your object. They can only be accessed by code that is defined in that object. You are, however, right to be concerned about the accumulation of private working variables within your objects.
Designing objects is hard to do and techniques and ideas have evolved over several decades of practise and research. The SOLID acronym, introduced by Michael Feathers, sums up five principles for object oriented design that provide useful criteria for evaluating your design. Also the book, Design Patterns: Elements of Reusable Object-Oriented Software, by Gamma et al. and first published in 1994, provides a good summary and categorisation of designs in object oriented programming. That book uses a document editor as a case study for demonstrating the use of such patterns. Both the SOLID principles and the design patterns in the book are abstractions, they won't tell you how to write a program but they do give a set of common ideas that allows programmers to discuss and evaluate. So I will use both of those tools in my answer, but be aware in recent years additional techniques have been developed to further enhance the software development process, specifically test driven development and behaviour driven development.
The S in SOLID stands for the Single Responsibility Principle and is a good starting point for looking at your example. By calling your object, Application, and thinking of the private working variables as global variables then it suggests you are writing the whole application within a single object. What you can do is start to separate Application in to a number of different objects that focus more on a single area of responsibility. First though I thought I would rename the Application object. I went for EditorWindow. In my example below EditorWindow also has a Header and a DocumentView.
Compile the code below with:
valac -X -DGETTEXT_PACKAGE --pkg gtk+-3.0 text_editor_example.gs
The use of -X -DGETTEXT_PACKAGE is explained at the end of this answer.
[indent=4]
uses
Gtk
init
Intl.setlocale()
Gtk.init( ref args )
var document = new Text( "Lorem Ipsum" )
var header = new Header( "My text editor" )
var body = new DocumentView( document )
var editor = new EditorWindow( header, body )
var document_selector = new DocumentFileSelector( editor )
var load_new_content_command = new Load( document, document_selector )
header.add_item( new OpenButton( load_new_content_command ) )
editor.show_all()
Gtk.main()
class EditorWindow:Window
construct( header:Header, body:DocumentView )
this.window_position = WindowPosition.CENTER
this.set_default_size( 400, 400 )
this.destroy.connect( Gtk.main_quit )
this.set_titlebar( header )
var box = new Box( Gtk.Orientation.VERTICAL, 1 )
box.pack_start( body, true, true, 0 )
this.add( box )
class Header:HeaderBar
construct( title:string = "" )
this.show_close_button = true
this.set_title( title )
def add_item( item:Widget )
this.pack_start( item )
class OpenButton:ToolButton
construct( command:Command )
this.icon_widget = new Image.from_icon_name(
"document-open",
IconSize.SMALL_TOOLBAR
)
this.clicked.connect( command.execute )
class DocumentView:ScrolledWindow
construct( document:TextBuffer )
var view = new TextView.with_buffer( document )
view.set_wrap_mode( Gtk.WrapMode.WORD )
this.add( view )
interface Command:Object
def abstract execute()
interface DocumentSelector:Object
def abstract select():bool
def abstract get_document():string
class Text:TextBuffer
construct ( initial:string = "" )
this.text = initial
class DocumentFileSelector:Object implements DocumentSelector
_parent:Window
_uri:string = ""
construct( parent:Window )
_parent = parent
def select():bool
var dialog = new FileChooserDialog( "Open file",
_parent,
FileChooserAction.OPEN,
dgettext( "gtk30", "_OK"),
ResponseType.ACCEPT,
dgettext( "gtk30", "_Cancel" ),
ResponseType.CANCEL
)
selected:bool = false
var response = dialog.run()
case response
when ResponseType.ACCEPT
_uri = dialog.get_uri()
selected = true
dialog.destroy()
return selected
def get_document():string
return "Reading the text from a URI is not implemented\n%s".printf(_uri)
class Load:Object implements Command
_receiver:TextBuffer
_document_selector:DocumentSelector
construct( receiver:TextBuffer, document_selector:DocumentSelector )
_receiver = receiver
_document_selector = document_selector
def execute()
if _document_selector.select()
_receiver.text = _document_selector.get_document()
A common high-level pattern for graphical user interfaces is model-view-controller (MVC). This is about de-coupling your objects so they can be easily re-used and changed. In the example document has become the object that represents the model. By making this a separate object it allows multiple views to be given of the same data. For example when writing a StackOverflow question you have an editor window, but also a pre-view. Both are different views of the same data.
In the example the header toolbar has been further separated into different objects using the command pattern. Each button in the toolbar has an associated command. By having the commands as separate objects the command can be re-used. For example the key binding Ctrl-O may also use the Load command. This way the code for the command attached to the open document button doesn't need to be re-written for attaching it to Ctrl-O.
The command pattern makes use of an interface. As long as an object implements the execute() method then it can be used as a command. The Load command also makes use of an interface for the object that asks the user which URI to open. Gtk+ also provides a FileChooserNative. So if you wanted to switch to using a FileChooserNative dialog instead of a FileChooserDialog you would just need to write a new object that implements the DocumentSelector interface and pass that to the Load command instead. By de-coupling objects in this way it makes your program much more flexible and the use of private fields are kept confined to each object.
As a side note, when compiling your example there were a few warnings: warning: Gtk.Stock has been deprecated since 3.10. The example in this answer uses the newer way:
for the open document icon the GNOME developer documentation for Stock Items states "Use named icon "document-open" or the label "_Open"." So I've used document-open. These names are from the freedesktop.org Icon Naming Specification
for the OK button in the file chooser dialog the GNOME Developer documentation states "Do not use an icon. Use label "_OK"." The underscore before means it is internationalised and translated by gettext. gettext uses 'domains' which are translation files. For GTK+3 the domain is called gtk30. To enable gettext when your program is compiled a macro for the default domain needs to be passed to the C compiler. This is why the -X -DGETTEXT_PACKAGE is needed. Also in the Genie program Intl.setlocale() is needed to set the locale to the runtime environment. When this is done using something like LC_ALL="zh_CN" ./text_editor_example to run your program will show the OK button in Chinese if you have that locale installed
This code works but I would like to know whether this is good solution? Would this solution using Expression Tree be considered better than Emit and OpCodes?
var target = Expression.Lambda(
Expression.Block(
new ParameterExpression[] { },
Expression.Call(
typeof(MessageBox).GetMethod("Show", new[] { typeof(string) }),
Expression.Constant(1.ToString(), typeof(string))
)
),
new ParameterExpression[] { }
);
AssemblyName aName = new AssemblyName("DynamicAssemblyExample");
AssemblyBuilder ab =
AppDomain.CurrentDomain.DefineDynamicAssembly(
aName,
AssemblyBuilderAccess.RunAndSave);
ModuleBuilder mb =
ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");
TypeBuilder tb = mb.DefineType("MyDynamicType", TypeAttributes.Public);
var method = tb.DefineMethod("dynamicMethod", MethodAttributes.Public | MethodAttributes.Static);
target.CompileToMethod(method);
The code in your example seems like just "example" code. I don't see it as requiring expression trees. If I read it correctly it is merely creating the constant expression () => MessageBox.Show(1.ToString());.)
Expression trees are great, among others, when actual dynamic code needs to be created i.e. when interpreting some other language within a program or for operations that would otherwise require reflection (e.g. in programs such as Automapper.)
Are they better than emitting the op-codes directly. It really depends: can do a better job than the compiler? Emitting op-codes is like writing assembly, it is time consuming and you really need to know what you are doing to be able to write optimal code. Is the performance difference between compiler and hand optimized code worth the extra effort?