Complexity vs best practices

Hello, just wanted to vent a little.

A couple years back, we built a project prototype based on UF 0.3. What I appreciated most about UF, was the insistence on good coding practices. It was an educational experience, besides a user management system. It was a bit steep getting into it at first, but things quickly made sense and I could understand the reasoning behind the implementation.

Fast-forward to the past few days, exploring the UF4 documentation for a new project prototype I am working on.

I must say, my impression is that complexity in UF4 seems like it has exploded. I find the jargon, reliance on 3rd party tools, and general complexity overwhelming at this point… Even the simplest task of creating a new page… a) requires several steps at several places, b) seems to drag me in way too deep into UF’s way of doing things, making the work un-portable to other platforms.

Is this a general sentiment, or just my personal experience?

Is there a point of diminishing returns in trying to build a “perfect” architecture, in terms of simplicity and “getting out of the way” for developers?

Thanks

It’s true that we’re a lot more focused on architectural perfection than we were in the past. I don’t think this is a bad thing - actually a lot of components we’ve introduced, like the dependency injection container, have made it easier to avoid some really painful bugs that would come up a lot in UF3. Overall, we’re trying to move UF to follow the battle-tested design patterns that have been proven over the years in other frameworks, to work quite well.

I definitely agree with you on point (a) - there are more files where you have to add code to implement any given feature, like creating a page. I think the problem isn’t so much the architecture itself, but the lack of tooling to automate some of these steps. Laravel’s Artisan tool has a lot of commands for stubbing out some of this “rote code”. I think Bakery could do something similar, and actually this is on our roadmap for UF5. If you can imagine a php bakery create-page command, this would really improve developer efficiency.

I’m not sure I agree with you on (b), though. If anything, UserFrosting is more like other frameworks (Laravel, Zend, Symfony, CodeIgniter, and their counterparts in other programming languages) than ever before. Is there anything particular about “UF’s way of doing things” that you are referring to?

I know that there are other projects out there that like to bill themselves as “getting out of the way”, but you have to consider what they are getting out of the way of. Rapid prototyping? Writing manageable, structured code? Using the tools that the PHP and web development community as a whole (Composer, npm) have adopted as standard practice?

I’m curious to hear more of your thoughts, because education is still a primary focus for UserFrosting. We really do want to help newbie developers cultivate best practices, and UF4 is supposed to help further that along. If we’re failing, I’d like to remedy that.

Also, don’t forget, you can always jump into chat if you’re stuck on something in particular :slight_smile:

An example of where “best practices” fails me…

I wanted to extend the User table, add a few more fields. Typical scenario. And I found this in the docs: UserFrosting Documentation | Extending the User model

Half-way through the guide, I am laughing. If somebody wanted to punish me, severely, for something I did when I was 5 years old, this would do the trick. :slight_smile:

In other words, I found it insanely complicated.

I would much much rather copy and modify the original classes, and database table and move on (if it was possible). Imperfect approach yes, but 1/10th of the work (at worst). I would spend the extra time to focus on the important stuff I want to build on top.

Still fighting this “extending the user model” thing btw…

Just an example.

I would much much rather copy and modify the original classes, and database table and move on (if it was possible). Imperfect approach yes, but 1/10th of the work (at worst).

Sure, you do can do that. The goal here was to decouple the core UF schema from the project-specific changes. This was heavily demanded back in UF3, so it made sense to do it as part of our larger approach to decoupling “core UF” with the Sprinkle system.

If you’d prefer though, you can drop the entire users table in your Sprinkle’s migrations and then recreate it with your own schema.

It’s important to realize, we didn’t design it this way to purposefully to torture you! A tremendous amount of thought and effort has gone into making this a highly decoupled framework - as far as I know, no other frameworks (Laravel included) have our level of decoupling. It does come at the expense of requiring more work to set up, but like I said before, I think a lot of this could be solved with proper tooling to automatically stub out some of the more repetitive code.

I realize the intention and amount of effort in building UF4 must have been massive. I am reporting my experience with UF4 for the purpose of getting useful feedback (like yours) and also for identifying weak(er) parts to improve upon in the future.

I am very glad to read that I can, in fact, override some default UF4 behavior, and cut down on development time. That was what I did in an older UF3 project and it served me well. The Sprinkle system looks awesome so far.

So, if I wanted to add columns to the existing User table, or even change existing columns, how would I go about it in a nice clean way in my Sprinkle? Assuming this is a lot simpler than extending the User model, this is what I am looking for. Any clues or pointers to the docs would be helpful.

Thanks again!

Yup, appreciate that! A lot of what you’ve mentioned echoes my overall sentiment as well when I’m dogfooding UF for my company’s platform. So, it’s good to know that other UF’ers are feeling the same way. This will heavily drive the way we make decisions in the UF5 roadmap.

You can use Laravel’s Blueprint methods to modify existing tables in a migration, in the same way that you’d use a migration to create a new table. You should use a migration rather than screwing with the table in phpmyadmin, because it makes your schema portable and reusable among different environments. Fiddling with the DB directly is for noobs :stuck_out_tongue:

You’ll still need to do something with the User model, either copying or extending it, for the following reasons:

  • You may want to add additional mass fillable columns;
  • You may want to add relationships with other tables/models

I would suggest that you extend User rather than copying and modifying it, if only for the simple reason that it’s less code you’ll need to maintain on your end when UF receives updates. Since you won’t be creating an auxiliary table for additional properties (columns), you don’t need to bother with the aux method, booting traits, etc.