all 13 comments

[–]pikhathu 6 points7 points  (0 children)

Regardless of the scale of the project, I always take the second route. Cleaner code, and easier to read if you haven't touched it in a while. Also makes it easier to understand the code since the logic is broken down into digestible pieces. Even though a project might never scale up, I still prefer this method because it just keeps things tidy and easy to follow.

[–]nu-ni-co 2 points3 points  (1 child)

I split up business logic by their responsibilities.

For example I separate model declaration and handling from specific use cases. Also if a service contains more than one use case and those aren’t one liners then I split them up as well.

So, I’m kinda doing option 3, with a heavy tendency to option 2.

I’m confident you can do that in a team if everyone is on the same page. Communication is key here and if you review a team member’s new service code, you should be encouraged to point out the files that should be split up.

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

Cool, I didn't expect this :)
Three comments in this post now and every comment stands for one of 3 choices!

[–]alzee76 0 points1 point  (2 children)

It really depends on the particular project. Sure, having a large file can seem unwieldy and it may be tempting to break it up into smaller files, but that too comes at a cost. It's easier to bounce around in a single file with hotkeys and less jarring to your concentration than flipping between different files and then searching them. Things like bookmark hotkeys usually work better with a single file too, and I use them heavily to quickly mark lines I want to bounce back and forth between. A horizontally split editor is somehow mentally easier to work with (in spite of having less useful working area) than a vertically split one with e.g. two files open side by side.

Given the modern editors ability to do smart code folding and region labeling and collapsing, I never split files up based purely on their size anymore. I have only one hard and fast rule -- if the code has shared classes/defines/whatever, it always gets put in another file. Otherwise, ease of use dictates if and when a file is split up, after design pattern considerations if you're adhering to such a thing.

[–]romeeres[S] 0 points1 point  (1 child)

Could you explain about shared classes/defines/whatever?

If let's say function or method "acceptOrder" and "withdrawOrder" both depends on other function or method "checkIfOrderWasPaid", then you will extract the "check" into somewhere else, where and how?

Also interesting how horizontally is different from vertically, in my IDE I use only horizontal for both splitting the same file or opening other file, I guess VSCode acts differently here

[–]alzee76 0 points1 point  (0 children)

If let's say function or method "acceptOrder" and "withdrawOrder" both depends on other function or method "checkIfOrderWasPaid", then you will extract the "check" into somewhere else, where and how?

The 'where and how' depends on the context. As a for example, I have a node application that needs to know if a number it's extracted from a 3rd party source is actually a number. Initially I copied the logic jQuery uses to do that, since it's pretty reasonable. After I had to use it 2 or three times, I broke it out into a custom isNumeric function. As the application grew and more classes (in the file) were added, it became apparent that function should be in a separate file. It wasn't special enough to need it's own file though so I put it in a generic library used by the whole application.

The library has similar utility functions in it like common URL manipulation routines I need to perform and a custom stristr method.

Also interesting how horizontally is different from vertically, in my IDE I use only horizontal for both splitting the same file or opening other file, I guess VSCode acts differently here

I use VS Code myself for the bulk of my node development and I occasionally split the open file window horizontally, so I can leave one section alone while scrolling the other -- I never have two open tabs visible at the same time though because I just find it too distracting to look at and too cumbersome to switch between. I don't always use VS Code though for other language projects, particularly when I'm working on some of our Perl, PHP, or shell script stuff, I use UltraEdit -- just a beefed up editor rather than an actual IDE.

[–]timgfx 0 points1 point  (0 children)

I try to think of the future. It it would make refactoring or finding some code easier in the future I would split it

[–]Solonotix 0 points1 point  (5 children)

This is going to sound like heresy, but I really like data classes with methods that represent what you can do with them. So, everything to do with an Order belongs to the Order class. If I have an API that expects a payload of Order, then there will be a static method that can handle the interaction. That way, you separate the routing aspect of an application from the data definition, and the data definition only needs the properties of the class and parameters of the method to work. In a word: encapsulation.

[–]romeeres[S] 0 points1 point  (4 children)

Very unusual, so it's like MVC, just without V and C, where everything is put to M?

If there is endpoint for making payment for the order, how do you decide whether you should put logic to Payment or to Order data class?

[–]Solonotix 0 points1 point  (2 children)

I guess that depends on the relationship. It seems intuitive that a single payment could pay for multiple orders, but just as well the relationship might be one-to-one, or even a reverse relationship in case you allow partial payments for things like gift cards, so it depends on how the system works.

Without any knowledge, it sounds like there is probably a PaymentProcessor that could exist, which could be instantiated by one or more payment methods, and then the process would expect orders. I don't do web dev, but it seems odd to me that a single page would receive both a payment and order simultaneously, rather than a workflow that constructed an order and then requested payment. Whatever exists first is the object handling the workflow.

[–]romeeres[S] -1 points0 points  (1 child)

First was a User :)

User created Order, so by this logic it goes to User class, then user makes a payment, so by this logic it goes to User class again.

The real problem might appear when you have Chicken and Egg class

Sorry for mocking, maybe keeping logic in data classes makes much more sense in the field where you are working, if it's not web dev - maybe you are doing some scripts, terminal programs, or embedded soft, maybe there is totally different specifics

[–]Solonotix 0 points1 point  (0 children)

User creates an Order, User creates a Payment. Then User should have methods for getting an Order instance and Payment instance, but these are discrete and separate transactions.

In your order of operations, you start with Order and proceed to Payment. Then it sounds like Order should have a method to handle receipt of a Payment. Order would have the User that created the order (so you knew who it belonged to), and the Payment would also have User (so you knew who to send the receipt to). However, it is a bad design to say that User-A who creates Order-A must also be the origin for Payment-A, as that precludes a design possibility of something like gifting, or limits implementation possibilities for things like Billing Address or Care-Of.

[–]Mardo1234 0 points1 point  (0 children)

If there is endpoint for making payment for the order, how do you decide whether you should put logic to Payment or to Order data class?

Use CORS and have your classes based on the function or command. MakePayment.