#order enforcement

1 messages · Page 1 of 1 (latest)

barren stream
#

if you have a chain such as

List<Processor> processors = List.of(a, b, c);

where order is important because the a will be used first, then b and then c. is there a way to ensure a processor that's suppose to be last stays last? do you just post a comment?

maiden oxideBOT
#

<@&987246399047479336> please have a look, thanks.

barren stream
#

i think it's like a chain of responsbility

quartz beacon
#

yeah

#

thats what it is

#

good catch

#

could be handled by some immutable queue, where "first is first" and "last is last", but is never modified, so it'll remain

#

but "chain of command" is the idea

#

@barren stream (i didnt discord-reply, thought a ping would suffice)

barren stream
#

immutable queue? from my experience with these chains it's usually handlers that run before a request is received by the controller and the order of the List is constructed like this

List<Handler> handlers = List.of(a, b, c);

or

List<Handler> handlers = new ArrayList<>();
handlers.add(new AuthenticationHandler());
handlers.add(new ValidationHandler()); // this should be last

the two ways i can think of to ensure the order of the handlers are correct:

  • add a comment so people reading the code will know
  • know the chain and what each handler does
quartz beacon
#

thats a linked structure

#

thats the only difference

#

and queues are very commonly linked structures

#

since queues are processed "first to last"

#

FIFO

#

so the elements get processed in order

#

chain of responsibility can be a bit different, where the current responsibility may rely on the previous

#

but thats a small difference

#

very easy to implement that

quartz beacon
#

you got your answer, solved it yourself

#

chain of responsibility

barren stream
#

yeah so i was asking how would a developer know where something would go in the chain and not screw up the order

quartz beacon
#

by looking at the requirements

#

and abiding the contracts

#

if something screws up the order, then there was no rules set in place, there was no contract

#

or that contract was violated

barren stream
#

from my experience i just add a comment such as this

handlers.add(new AuthenticationHanlder())
handlers.add(new RequireAuthenticationHandler()) // this needs to be after authentication handler
#

i was asking how can you enforce this

quartz beacon
#

through the type system

#

or through a document outlining requirements

#

javadocs

#

contracts

#

if someone does something wrong, they didnt follow the rules

barren stream
#

liked a staged builder

quartz beacon
barren stream
#

yeah that is a bit overkill, but isn't that how you would use the type system to enforce it? i just add a comment usually

quartz beacon
#

youd be surprised at how easy it is to abuse a lot of current systems

quartz beacon
#

hell, even the Collections framework violates stuff, but in a coordinated way

barren stream
#

im not using this library, but you can implement something similar to enforce the order?

quartz beacon
#

because they know that introducing a proper solution would also introduce complexity that isnt really needed

barren stream
#

yeah it does add complexity and you would proably have to add a field for each handler

quartz beacon
#

if its as easy as telling someone "dont do that", and its easy to comprehend... do you really need to enforce it through some crazy type-based security?

#

pick your battles

#

that would be "perfect", if it didnt include the complexity

#

but thats how it is

barren stream
#

gotcha im sticking with my comment

quartz beacon
#

thats why the Collections framework doesn't even support proper immutable types

barren stream
#

or a diagram somwhere so people understand the handler chain potentially

quartz beacon
#

yup

#

some kind of internal (javadoc) or external (independent doc, diagram, whatever) contract

#

and yeah, we want to enforce these contracts in code. but its harder than it sounds sometimes

#

and in this case, that's what it is

#

what matters the most is that the software works, and people have access to it

#

dont let something like that delay a release

#

hope that eases your mind

nova dawn
#

the really basic way i've seen "not empty list" enforced in functional languages is

#

(a, List a)

#

just have a tuple of the first and the rest

#
record NotEmpty<T>(T first, List<T> rest) {}
nova dawn
#

you could use a momento

#
List<Handler> handlers = new ArrayList<>();
var momento = AuthenticationHandler.register(handlers::add);
handlers.add(new ValidationHandler(momento));
quartz beacon
#

nooooooo

#

no momento

nova dawn
#

or whatever the right term is? key?

#

its wacky and evil usually

quartz beacon
#

momentos are used to restore data (like momentos IRL)

#

and they leak implementation

nova dawn
#

and using it to enforce ordering is hard

#

but its not hard to use it to enforce something like "running in context X"

quartz beacon
nova dawn
#

it could actually be strong if you resorted to a linked list

#

like instead of List<Handler> you composed them

#
Handler handler = new AuthenticationHandler().compose(new ValidationHandler())
#

here you could do like

#
Handler handler = new AuthenticationHandler().compose(authCtx -> new ValidationHandler(authCtx))
#

where AuthCtx could be an object giving access to the bits of data that AuthenticationHandler sets

quartz beacon
#

they are going to have a linked list, it'a just that responsibilites are going to be coupled

barren stream
#

a momento o.o? first time hearing that

quartz beacon
#

used for undo actions, history. like a momento irl, which exists to remind you of a past thing

nova dawn
#

momento isn't the right name for this

#

i forget what is though - "key"? "witness"?

#

its not that strong a pattern atm, but it would be with null restricted types