Jimmy Bogard - Blowing Up the Bike Shed with Conventions @ DevConf 2017

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so welcome everyone my name is Jimmy you can find me on twitter @ @j bogart don't forget to use that @ tag it helps feed my ego to see me and on the top of the leaderboard there you can also find everything I do on github so github.com /a bogart projects there and also presentations as well I blog on Jimmy Bogart comm I also used to vlog in another website on those techies so you may have read a few my blogs over the years on there some of the other projects actually be talking about today because it's it's relative to our convention discussion over then right so automap or mediator and then one will talk about today 2 is the HTML tags one so yeah this talk is about blowing up the bike shed with conventions and I'll explain what all that means as we go through the go through the title here I'll go through there go through the talk here um so the idea of bike shedding came from us Parkinson's Law of triviality there's another there's another few laws out there that aren't as fun as this one so not not the law about not the law about every online discussion devolve into something about Nazis or Hitler that's Godwin's law not that law this law Parkinson's Law of triviality says that humans spend a great deal of time on trivial details why the while the more important matters are skipped and this is especially true for us as developers we spend a lot of time on stupid stuff that doesn't actually matter not stupid stuff that doesn't actually matter to the in value to the client we spend a lot of time automating our our jobs and that's ok it's the other stuff that doesn't really provide any value at anyone then we seem to spend a lot of time on and so this this idea Parkins law originally came from a focus group that they that I psychologists put together to help design a nuclear power plant and a nuclear power plant is pretty complicated there's probably a lot of things where you want to get right but it's so complicated and no no one person can really grasp everything that's going on here like it's probably really important those cooling towers are hooked up ok and something about those cooling towers and nuclear I'd actually have no idea how this all works but it's pretty important to get everything right but what this group was focusing on when they said we want you to design and build a nuclear power plant they didn't they didn't focus on the really important matters the things like make sure it doesn't blow up instead they focused on like the little Hut in the lower right hand corner right down there which was where people park their bicycles on the way to work and so they focused all of their time and energy not on designing this but on designing this the bike shed and so this is known as bike shedding where we spend all of our time and energy on the things that we can grasp the things that we can understand they're really they're really the really small things that we can fit in a little box and say I understand everything that's going around here but the more important details the overall architecture of the system the more the the things that actually matter to the end-user and the business those are the things we don't really talk about because those are harder conversations harder details to get right and so we tend to skip over them in favor of the really boring stuff and so this is known as bike shedding and a lot of projects I see that are that are grown over many many years have a lot of bike shedding going on and there's a lot of different ways in which we as developers actually do this bike shedding and we're all guilty of it even you and you over there - you're asleep so you're ok everyone bike sheds a little bit so what are the things that we see that we argue about as developers that really don't matter at all to the end value deliver things like class names have you had meetings where you have to decide a class name yes class design member naming folder structure like you have to decide between infrastructure and services maybe have two folders like that do you have separate projects for each of those these are the kind of things that we talked about different patterns of course we argue about what patterns are the right ones to use HTML layouts this is the this is the one where people move things by like pixel by pixel to make sure they're just exactly right eight different HTML widgets so what what is the best date picker out there you could probably spend a good two days going through all the different date pickers to figure out what is the absolute best one even doesn't really matter how we do validation and probably the one I I see the most or sequel object names anyone have a database with at least four different naming conventions yes so you probably have things like tables have plural and not plural names some tables have a prefix TBL name of the table maybe it's TBL underscore and the name of the table as well it gets more difficult when you get into view and stored procedure names or procedure names SP and SP underscore to have both of those as well yes it seems like every time there's a new tech leader DBA on the project they have to make their mark in the system with their opinions about holidays things should be built and so it becomes almost like a Geological Survey through time you can see whose opinion was being enforced and what given point of time throughout this application and you see this sort of thing devolve where if I'm if I'm a developer new to the project what is the right way of doing things well there is no enforced right way I have to go look at the last way of doing things so I may go on source control like what was the last poll request accepted okay looks like that was the right folder structure a naming convention so I'll do it that way because that's way it should be because I was little just to happen to be the last thing was done but that doesn't mean it was the right way it was just the last way of doing things so these kind of micro decisions where I'm deciding class structure folder names all those kind of things that don't really matter to the end user don't provide value those are the kind of things I can see derail projects from the developer side we're spending all overtime on little details that don't actually matter as opposed to actually driven delivering business value there's a secret though here that is little painful for us as developers which is that our opinion actually doesn't matter in the end your naming convention opinion your folder structure opinion none of that actually provides any business value to the end users and so ultimately it doesn't really matter in the end what I greatly prefer and want to have in the systems I build is consistency over correctness if things are all the same even if they're all not my way of doing things that's more important that having my opinion being put on top of a project now if I'm in a system where the opinionated way of doing things is causing productivity issues then okay I can go ahead and have my weight my new way of doing things but I always have the law of to because there's no more than two ways of doing things in a system and there has to be a plan for moving from the old way to the new way where I tend to see things tend to go wrong is when a new tech league comes on they have their new way of doing things but they don't ever have a plan of finishing out and getting rid of the old way so they leave and then a new tech lead comes in and then their new ways in there it's now I have three ways of doing things and then they get bored and they get tired of having to deal with two ways and another way and so on and on and on so I eventually have so many different ways of doing things there's no consistency in the code base so for me personally I don't really care what your naming convention is what's your structure what your layout is as long as I adhere to those rules that's more important than having my own opinion being put in the codebase now that's all well and good to say we want to enforce we want to minimize the number of opinions being put into our codebase won't have a consistency throughout the entire code base but how do we enforce those kind of opinions across our codebase how do we make sure that everyone does everything the same way and the way we do this is with conventions this is how I enforce rules about how to build our applications throughout the entire system so what are conventions this is something that was popularized from Ruby on Rails Ruby on Rails said you know instead of us having all this explicit code we were copying and pasting and over and over again instead of us doing things like code generation that worked well once but there's always something need to be changed instead that said let's build our application and our framework so that it's designed around these conventions and the conventions about how software should be built would then be enforced in the entire application framework so conventions are a set of coding policies that are applied and/or enforced across the entire code base and by making sure that my policies are enforced I make sure that no new persons opinion however valid they may be don't leak into my codebase and generally muck things up so why should I care I would say for most sized projects this kind of thing doesn't really matter quite as much but for projects that tend to be long term that have to live a number of years or are of a certain size then I want to have some sort of consistency enforced in my projects so a couple of projects that we've really found at conventions work well for us actually I thought if anyone was in my talk this morning these are the same two prejudices talking about but really for all of our projects that I do at my company a consulting company we have convention based development and both of these were very large applications both of them had hundreds and actions I think the first project had over a thousand different controller actions and a lot of different things I was under a deal with what I wanted to make sure that as these projects were developed over many many years that the same coding standards that I had on the first few months of the project would be the same coding standards ID coding standards to have on the on the year five of the project with both of these different projects I was on so unfortunately the firm acquis were dealing with asp.net MVC had zero conventions that had defined for us it had really no no preferred way of how you build applications they just said here are a bunch of tools and is compiled e up to you how you want to build the system so we had to figure out what was the right way that we wanted to build applications and so we looked at a number of different systems out there at the time to see what what are what are ways people were building NBC applications at the time and what makes most sense for us in the.net land at the time we were looking at a couple other major frameworks on how to build NPC applications which would be rails at the time and pythons Django project as well both of those projects are built on top of languages so it was a little bit tough to translate they monkey punching wait no that's right right donkey patching no whatever it is and what it meant for em what it meant for us and the statically type land so omits looking at the different things available for us in an application and figuring out what are the right ways that we want to build those systems now unfortunately the the documentation of the time for Microsoft was really really bad ways of building systems it was great examples of how not to build systems for example this is from the like the official Microsoft documentation about how you should build a controller action that performs a post and does stuff and so this is the wrong way of doing things so this one for example it it's a post action to create in this case a new instructor and the thing that it would be using to model bindings against that is what it was using to bind those raw request parameters into an object was the actual live domain object the the data object that was connected to the ORM behind the scenes and this can pose a problem actually Ruby on Rails had the same issue a couple years before this and they solved the issue in the exact same way so the issue with Ruby on Rails is you can indirectly expose your active record models which are things connected straight to the database as things that we bound directly against request parameters and so originally Ruby on Rails would blindly take all those key value pairs of request parameters and apply them to the actor vector object and then go ahead and save without any validation that said these are the permits that are actually wanted you to bind against at all and so this is this vulnerability which is known as the mass assignment vulnerability was discovered by a developer and so the developer opened a github issue that said hey you had the security flaw someone could just post any parameters they wanted as long as they matched some column that existed and that active record object it would get saved and persisted I guess the rubric and rails team wasn't as timely in their in their response to the github issue and so that what the developer wound up doing is they learned that Ruby on Rails was the underlying framework and still is of github so they open a pull request to close the issue or to patch the issue using a way of either a net list of includes or a clue exclude to say includes these parameters or exclude these parameters and because they knew that Ruby on Rails was the underlying framework of github they exploited this vulnerability to make themselves an administrator of the project to accept the pull request to close the issue so that's kind of cute way of doing things the Ruby on Rails team was like not exactly excited about that they want him to go through normal process of opening up an issue and waiting for them to respond but it's a pretty big issue if you knew something was built by Ruby on Rails you can just start put you just start guessing on different variables and be able to take control of a system things like oh this is a user edit screen kind of make myself an administrator kind of add roles to myself just post those things up and then you could extend the extend that extend your data in a way that wasn't actually meant to in the system so the way that the MVC team knew about this and exposed a way for you to to close this security goal was to provide this incredibly Genki way of having a comma-separated list of string parameters that match to property names on your objects now I don't know about you but I never get strings then related to property objects wrong I always type them correctly and I certainly never switch letters around or accidentally forget one every time something new shows on the screen I'd never do that I always make sure all my port requests never have any security flaws but of course that's not true maybe it's true for me but of course my team maybe they don't have that same level of rigor that I do with the things I build so this is not gonna scale I mean every time I add a property the screen I'm gonna have to go back and remember to do something so in general and my program if I have to remember to do something I'm going to get just gonna I'm going to assume I'm going to forget so I'd rather have a programming part paradigm it says instead of you having to remember to do saeng's I will design the system in such a way that you cannot forget and if you forget it'll just break so instead of us doing this where we have this domain object directly being bound with request parameters and this having to remember this crazy comma separated list of string instead we had a very cunning plan we'd build these things we called view models which are essentially D tos that represented only the properties I would be showing or editing on that screen for that one individual requests not to be shared anywhere else now with this view model I am binding directly against this for forum posts as opposed to my live domain object so this is already - already a an approved list of all the properties I would bind against and if I want to have a new edit field on a screen I would have to have it in this DTO as an explicit new property that was added and if I forget to put that property on there my application won't even run or compile it'll just completely fail if I remove something from here then again my application won't won't compiler or run at all so by by building up these individual view models for every single screen I can enforce a policy of don't use a domain object for your posted in put your posted in models this is where we had a moment of panic though or me we as in me I was a tech lead on this project because I knew that I was going to have hundreds of controllers hundreds of actions I didn't think I was gonna have a thousand actions I probably would have pumped the brakes a little bit earlier if I knew that it's gonna be that big hundreds of view models hundreds of views how would it enforce some kind of commonality between all these difference DT o--'s are going to be created and so when we started the project every single page would have its own DTO but every single DTO was bespoke handcrafted custom built just for that one screen and so there's no consistency about the naming or anything for any of the details anywhere else so if I'm one page I wanted to call something full name another page I just called it name there was nothing that was enforcing any kind of naming conventions between those two every single new page it was up to the developer to invent what that detail would look like so I knew like I don't want to do this I don't want to have to enforce all these different conventions for all these different pages so I took a step back and said okay what what kind of patterns do we have here across our application so I looked at both gets and post because those are the two kind of main things or going out of my system I looked at the gets and said okay what are what are the kinds of things I'm doing here well I'm taking taking some potential some parameter from the outside world going and getting something from the database and then I'm doing a projection from that more complex model into a more simplified model sometimes it was a sort of a simple projection like we have here sometimes it could be more complex but the big deal was I always had this going on which was building out a model projecting information from a more complex model into this individual one so originally there was no patterns in place around what this DTO look like but there were some things I thought I could enforce so instead of us for every single dto deciding how every single thing should look perhaps I can just have some policy being enforced and if you haven't guessed it this is where my project automatic aim from was trying to just simply enforce a policy of making the DTO look always a certain way following a certain set of rules so what was that policy well first of all on the new DTO I would want to make sure that one it would automatically map property names that were exactly the same so just copy over those details exactly there was some times we had calculated fields and calculated properties so if there's some kind of like get method that did a more complex calculation I could just map the result of that value of that calculation into a single property based on the name so just like remove the gets take off the parentheses I have a property and I'm done for more complex properties maybe I'm navigating a set of fields I would just remove the dots from whenever I was navigating and say yes that should be the property name on the destination side they also meant that I could somewhat handle collisions I would assume that no would have liked foo bar Baz versus food bar Baz that would just be totally confusing from the object design in the first place so I try to have some some obvious conventions there has just said if there's a collision and maybe throw an exception but that really shouldn't happen in practice but just remove the dots find everything down into a single property name and that will be how I would automatically map from one property the next I also wanted to handle the obvious like lists raised enumerations primitive values just figure all that out it should be that big of a deal and so the results was was autumn a per and which instead of me explicitly mapping out how that complex domain object maps into this dumb DTO instead I would say just one line of code say map that complex object into the eto via a series of rules that say names must match and remove the dots to find things out things like that I can even have more complicated sort of mappings as well so autumn a per also supports the idea of link projections so in link projections with Auto mapper instead of me hydrating the complex domain objects in memory and then mapping that result out and instead what I can do is use link to replace a select projection in link with a projection from autumn a per so it builds out a select projection hands it to the ORM ORM translates that select projection into sequel and I go basically straight from sequel to my DTO through an enforce set of policies that say these are how the property names almost match up so all those lines of code in my system that were mapping junk from a complex model to a dto we were able to just essentially get rid of now there were more complicated cases that were we needed handle especially but for like 95% of the things that we're doing we were able to say map that one thing to the other so that basically took care of all of our gets we no longer had any more arguments those stupid arguments about what the what the naming convention should look like how the property should look all those arguments just to wit away and said you know what we have a tool that enforces a standard so just use that tool that enforces a standard if it doesn't work then things won't map up and your application will break call it a day we also looked after going through the get side we looked at the post side now on the post side where I'm writing data back this is where things became more complicated if I look at the actual work being done here I've got some validation junk loading the thing and then redirecting at the bottom the more interesting part here when I started to compare across different controller actions it wasn't so common there was no real policy being I couldn't force that this is the real interesting part of the application and in fact this is the stuff I wanted a developers to really focus on this is the real work being done in her system so because we had more behavioral entities the logic was a lot more complicated and there were no real patterns that we saw in there it was always very custom to the work being done so in this case we said you know what this is the this is the cool part of the part of the system this is what's interesting to our users so let's just leave it alone we won't use any kind of automated mapping tool to try to map back into these complex objects which is why for the people that use have used auto map or you probably have problems mapping back into things and that's because we never I never want it to be an actual use case it's it's the part where I'm mapping from complex data objects into a dumb DTO that was the thing we can enforce a lot of policies on now our team didn't stop here we saw this is just one pattern we saw emerge across the lifetime of our application but what other places do we see they want to enforce a set of conventions to remove these stupid arguments that we're having so there are a number of different conventions we saw out there ones that can be and one that ones it could be explicitly enforced like auto map or does through its behaviors and some of the ones what we saw they were more implicitly enforced so in this case our implicit conventions these are ones where the policy doesn't necessarily derive any sort of behave your system so the autumn app or tool will enforce enforce policies via how it maps but there's some times where there's no actual behavior behind the scenes instead we have policies enforced by just some rules that we check so if anyone's used things like anyone here you style cop the thing that slows down your compiler a lot or is that FX cop I get them confused those are those are again one of those tools I have a love-hate relationship usually a hate hate because there's some tech Lee that wants to check all the buttons and enforce all these crazy rules and it just makes everyone's super angry like oh you put two spaces instead of one space rejected from your reject that one so I try to I try to balance developer productivity and annoyance versus things that are actually important so you don't want to go too crazy here but we can use things like automated tests to enforce that so one example we had was we would secure every single controller action or system via authorized attributes on that controller action but it was again one of those things that I could forget to do so how do I make sure that I don't forget to put that permission on every single controller action in the system well I guess we could use code reviews right everyone gathered in a room and point out how bad everyone's code is and everyone feels hated whenever L I hate everyone afterwards or you can use pull requests as your means and code of view or you can use pair programming to make sure those things are enforced but again those are all human base ways of enforcing a policy and any time a person is involved in enforcing these things again that's something that we could easily forget even if we have the most complete checklist we have possible instead I can use automated tests to do this so that's what we wind up doing we wrote unit tests that would scan our system using the type metadata information from reflection to say let me look at all the controller actions defined in my system and if any one of those does not have that correct attribute on it then throw an exception fail the test and tell the developer you forgot one now there are always exceptions to this so we may have a list of controller actions that didn't need it like maybe the login page didn't need a controller didn't need that secured attribute there with a specific permission but that was a kind of a one-off thing for the most part though we want to be able to say if you forget to do something I'll have a failed test that just blows up in your face and so we do this for a lot of things in her system things like type naming conventions so making sure that our our view models were named controller action and then like model we would actually have a unit test that ran it said make sure that if I call something by this by this name that there's a corresponding controller action with that same name again that's when as a developer I'm creating a new class I don't have to make a decision about what that class name should be it's not that just an ID instead I have a policy that says this is what your naming convention should be visibility rules as well to say what things should be private versus public organization we settled on feature folders so making sure that we organized not things not by kind but by the thing that user was doing we'd build tests around that to make sure that we were following those conventions going forward now of course I guess someone could disable those tests but that's kind of a jerk move those are things I could look for in a pillow request and like ah that that Namie conviction test failed and you just commented out that test okay don't do that please but for the most part our developers were we're good enough to be able to handle these sort of things on the other side of this I have explicit conventions these are ones where my conventions are now adjust not only define a policy but the policy is actually enforced by how that how that set of code runs and what actually outputs on the other side and so as part of this will have opinionated rules about how things should be done and if we need to have something that some things that changed then we can customize those so for example it should be easy for a developer to replace this set of code that does manual mapping of stuff was something that automatically maps and it should be very obvious to them the rules that are in place there so those one our first rules of these conventions is that policy should be very obvious it should be enforcing a policy I'm already doing by copying and pasting code but it shouldn't be this magic policy that everything kind of wires up by itself I don't I don't as a developer opted into that myself so that's why we had opt-in behaviors for autumn APRA you actually had to tell it that you want to map these two things together and once she told it then it would enforce the policy but if you don't want to and enforce this policy you wouldn't tell the tool that you wanted to do this our second big role is that policies not driving behavior should be testable so things like the property names need to be matched up well that can be a little bit difficult to make sure that everything lines up properly so we said okay what happens if you miss if you if you spell something wrong on the destination side so we said that okay if you're building this view model that is a special view model just for this view then I assume that you're gonna want to map all those different things and if you don't want a map but you have to tell me that you don't want to map it so we we as in me made a very short little one-liner that says assert configuration is valid and what that will do is run through all your mappings and say make sure that everything is on the on the destination side has some kind of mapping associated with it and if it doesn't then it's going to throw an exception in your unit test and say oops you didn't map us saying you need to go fix this you know this is try to help that because this is all behind the scenes I need to have some way to make sure that everything's going to be executed properly and a unit test is a way we'll do this our final rule was that policies need to be debuggable I should be able to get at the configuration and print it out and say what is my what is all these things that are getting wired up automatically what is actually the the configuration behind the scenes and so tools that do a lot of auto wiring of stuff will have ability to just print out all the configuration associated with it so that one what do I have light at the end actually returns a string and it prints out all the different configuration values that you have associated so if you need a debug something you can go look to see what's actually all the configuration I have here today so when I look at a real world example of us doing this with not just some behind the scenes mapping tool but something that was actually driving in user value for things like DT OS those were things that the developers were arguing about but we also found that that kind of arguing and bike shedding actually leaked all the way out to the product owners so we're here I've had product owners that argue about like what date picker to use just me oh gosh I must have bad product owners I guess so they'll argue things like I don't for this page I want the date picker to the little date icon to be on the right and then some other product owner comes in and says I don't like the way that page was done can we put the date picker on the bottom or stupid things like labels being on top versus the side every single page in the application which is own special snowflake designed it just for that one product owners whim on on one given day and so what we wanted to do is say right use product owners are spending way too much time arguing about stupid stuff on the HTML what we're gonna do is build out a style guide that says this is how the our entire application needs to look and enforce that convention when we actually build a system Iris's sometime with like UX designers that feel like every single page needs to be its own special way of building things and there's no consistency across the given application because every single page is completely custom built to whatever that UX person wanted to do that day so we looked at the code behind the scenes for the templates we were using and we saw the same kind of thing that's sort of boring dumb repetitive code that we'd copy and paste over and over again any we're using bootstrap everyone should raise our hand because everyone's using bootstrap right it's what it's what you do and bootstrap kind of encourages kind of copy/paste junk we have the same div form group tags all that sort of stuff is just the same for every single element we show you want to show on the screen and this kind of stuff I just get super annoyed about like I have to copy and this over and over again and have to make sure I do the right one over and over again because if I get it wrong then I have a new bad standard going forward this is one of the cases too that I always had to go to the last page that was created to say what was the last right way of building a page and hopefully that wasn't anything special and have to do it on that page as well so we wanted to not do this you didn't want to have all this copy pastes junk of labels go on top file by the editor and the met the validation message goes over here and then copy paste again for 20 fills in the screen times 400 different pages and then I've got this junk copy pasted everywhere we wanted to enforce how those elements would look across the entire application now unfortunately there's nothing really good in MVC or MVC core to help you with this so we looked at a couple different things and this one we looked at template of helpers and in MVC core we also looked at tag helpers and neither of those provided a great way for you to compose HTML together they're very there they're almost entirely string based and in my systems I try not to have as much string concatenation as possible that's the thing that can get really wrong and it wasn't easy for us to build more complex things together the other thing we found is they're neither these were there they're way too much code or way too much like you have to get it just right code if anyone here's tried to build a template at helper or tag helper there's a lot of code you have to get like just right for it to work properly so he said write the built-in primitives don't really work so what we wound up going with was an open source library called HTML tags to enforce conventions about how HTML needs to be rendered now what's different about HTML tags and other libraries we've used these HTML tags actually uses the same metadata system that the other helpers use in order to build out HTML that is tailor-made for every single kind of property or system it's how does it work well it starts out with I want to request an element to be shown on the screen so I say I want to request an input element or an output element that request gathers up all the metadata information you can find like what's the property name what is the property type of that one are there any attributes or annotations defined on that individual property a guy there's all that kind of metadata information together and passes it through a set of policies it's a based on these this metadata information how should I build the final HTML this gets pushed out to a tagged model and this is one of the other differences between HTML tag helpers and MVC core and the other stuff and old MVC as well this is an object model as opposed to a series of strings that you have to concatenate together so I can more easily manipulate an object versus dealing with string Joc the final step is of course I have to put a string on a page so yes there is a here's that final string and so the goal for us what to say so this these two things what they really represent is I want to output a form block of HTML for a title property and a form block a code for what does the other one credits property and I don't want to have to tell the exact HTML every single time for the most part it doesn't really change what I really want to do is to make it look something like this it just says what's the title form block what's the credit form black what's the department form block and then enforce how that should be built up behind the scenes so the tooling we use for this included razor views we still wanted to keep those this the normal template engine of the MVC framework we're using then our HTML tab library for the tag model so those the tag model objects and the HTML tag library also has tag inventions that say if you have a property that has this metadata build it using these individual rules so in this library you basically start out with a blank slate that says I have some different kinds of tags you can build and you tell it when you request that kind of element what it should do and it's all through this fluid interface so we can start with some baselines like editors always add that stupid form control class from bootstrap now bootstrap is not semantic HTML and that you always have to tell it like yes it's an imp in element but it's a form control element why don't you know it's a form control element because it's an input tag I don't know why but you always have to tell it what these different things are the labels always have that stupid control label class so I'd say when I stab build a label always add that control label class whenever someone requests this we wanted to have some different sensible defaults like okay the property name if I request a label for property it should always be that string if I want to opt out of that through an annotation or attribute then use that value instead as opposed to the actual property name and for things like start date right it's a camel case Pascal case whatever it is so whenever a request a property that has this naming convention of camel Pascal case then can you just split the property names and put a space in between every single capital letter because I would always want to do that I never want to ever want to Jam these things together and so the HTML tag library lets us do this it says okay labels when you see this display attribute attribute then go ahead and modify it and change the text to the attribute value name that comes out of that attribute defining this rule once means that for the entire rest of my application if I request a label I only need to put that display attribute on for to enforce this rule even stupider things like every boolean should be a checkbox obviously like why would I have a boolean defined in my model that is not a checkbox bloomers M represents a true or false value oh just two states and so a checkbox corresponds to that before I would have to explicitly opt in every single time I would show an input to say oh by the way this property is a boolean so I have to remember to say do a checkbox not the other thing instead after I teach the convention that all boolean should have a type of checkbox I never I never have to tell it ever again I just say give me an input and based on it seeing that it's a boolean it'll say Oh bullying's those are always checkboxes we also could build new primitives in our system like display labels display labels are slightly different than input or editor labels editor labels aren't actual label elements and they're tied to the sides of the input element but display labels on the screen are slightly different they don't they're not built with the same HTML so we can tell it this new way of doing things I said you know what actually for display labels we don't want to put a tag in there it's just the raw text itself and when you spit out the text use the property name and break that property in a map based on the camelcase so when I build display labels I can say always display them always build them by this display default display label builder and if you have that same display attribute we had for the other labels also modify that for that as well so now that we built the kind of fundamental building blocks of editors labels input elements and input open elements output elements editor labels and display labels we can now start to tackle this more complex set of HTML that's being built out we saw that about 90% of our HTML for inputs look basically like this I had an outer div that was a div class form group then there was the label based on the property and there's another inner div with this medium column 10 whatever that is I sure mean something in bootstrap I just copy and paste that thing over and over again and then finally I have the actual input and valid intersections I have on here now if I'm copying and pasting this over and over and over again what I'd like to do is say kind of just establish a a primitive that says build a form block for all these pieces and just do that instead as opposed to copying and pasting the same stupid code over and over again now if I was using just raw asp net MVC or MVC core what are the things I can use to try to do that I've got partials partials are good for HTML focused elements but partials are really bad for passing model information down so that's not a really good fit for this one I could build another HTML helper extension that returns a string but that's not that great because I'm mixing in these different like HTML tag way of doing things + raw HTML and they don't really mix together I have to do more string concatenation and I want to try to avoid that as much as possible there are custom tag helpers in MVC core but those are complicated to build you have to make a new class for every single one you do of those so that's again more complicated but what I could do is then instead of trying to mix those NBC concerns that don't all fit with this I can use again that same HTML tags library in HTML tag library because it's object base is now really easy for me to build up and mix the convention base way of building HTML with these other more larger primitives so in this code what I'm doing is I'm first building up a div tag via an object as opposed to a string I say give me a new div tag add a CSS class and looks if the syntax looks familiar is because the developer that built this was heavily inspired by jQuery at the time so is this very like fluent syntax that kind of matches what jQuery did alright that div tag and now I want to have the label tag but the label tag I want to use that same label helper I was using before so I say okay go ahead and give me the the use the label method to return the fully form label tag as an object as opposed to I had before and if I need to modify it I'll have a call back with that label modifier to modify the label tag do the same thing with the input that says give me the input for that property based on the expression return it back and then finally I can append those two tags to my outer div tag so I have an outer div tag and then finally those two inputs and labels as one set of HTML tag that gets converted to string so the final form looks more like this then will be had before I have the normal form blocks that are always the label and input and validation has one single line to say give me a form block for all these different things for things that don't have labels I can drop down into the more basic building blocks these input ones as well and if I do want to use the built-in ones from MVC I can still use those as well that's thinking nothing's forcing me to completely use this entire new library I can go back and use the other ones as well so this meant that our developers that were building systems like this really just built D TOS map that DTO using autumn a per and then here they're just like just put all these different form blocks on the screen because they're straight their screen should be by and large very consistent in how they should be laid out this removes probably 90% of the bike shedding in our systems where we're arguing over layouts and positions of things that said nope licious enforce a style convention through a tool and then no longer have those conversations with our product owners or the developers how all these different pieces should be put together but wait I know you were thinking okay this is great this is using server-side rendering but no one here uses using server-side rendering anymore right everyone here is using angular that's what everyone's doing that now so yeah what about I'm not using server-side rendering I'm using some other thing like derp angle to Randal regular reacts or something like that and that's when I get sad because I hate those frameworks with a passion and so we have to go back to the drawing board said okay well that's that's all well and good for server-side rendering how can we have that same kind of policy enforcement on the client side and so I have to go back and look and say well how are these things being put together I kind of have a mix I have a mix of this is a angular I believe with those little double mustache looking things over there and so it has a mix of HTML and these bound these bound elements here now angular does have a way for you to you in the newer versions bind directly in HTML so I can still use the library I have before but the way these are typically built is whenever you have a request you make a post to get all the information and returns back or get and then returns back all that all the information back to the browser with including templates and all that sort of stuff so all the rendering happens on the browser side but the meta de is over on the server side so the way we saw this problem in our systems was do that same sort of conventional base building of HTML and what we do is we'd actually pass those templates of whatever single page application thing we were doing through the template parser on the server that had all that complex metadata of the models we had behind the scenes and only after we went through the template parsing those were the final templates we actually passed to the front-end single page applications that would then bind those data objects to the screen this was complicated so I would only really do this if I was able to enforce those kind of conventions on both sides a lot of times when I have more more complicated behavior in the client side there is no like one way of laying things out it's more a lot more complicated client-side behavior so I would only attempt this only if I can look at several screens say it looks like we have a lot of copying and pasting going on and not a copy casing of code but copying and pasting of concepts so let's go ahead and pull those out into something that can enforce those concepts for your policies so some parting thoughts conventions are good they're okay to use magic in these systems is bad so if you find yourself having too much magic or too much explicit configuration don't use the tool but absolutely do not use cogeneration cogeneration will not enforce these kind of policies for you it's just a broken system and won't give you to this nice happy place I'm enforcing a coding policy going forward so that was blowing up the bike shed with conventions if you want to see a running example of this you can go to my github at comm /j Bogart I have a set of sample projects for both a speii net MVC regular NBC I have a sample for HP net core and also asp net core on dotnet core just search for you'll see them they're all pin repositories there so go check them out if you want to see a running example all these otherwise I'll have time for questions and thank you very much so questions yes I totally made that up by the way yes I said 90% but I just believe me trust me so essentially the question was what's the learning curve on you using these kind of tools I'd say for for our teams we we do make that part of the onboarding process it's not just blindly use these tools and good luck with it we do teach them like the the concepts behind it to say this is the reasoning behind how we build these systems so we actually like an onboarding process is like a week that's taking through a lot of these concepts to say you know we arrived at this final point we want to take you on the same journey we went through to get to this point so that you understand why we do the things we do and not just say you know here's a bunch of things and don't don't don't have don't understand why we put all these things together it's really important for us to communicate the why behind these things - I would say yeah it get rid of 90% of the arguments on that project but in the next project we reevaluate all those decisions again about what are the policies we actually need to enforce on this individual one this project as well we actually waited I waited for probably two or three months to have enough features built up to say let me take a step back what are we actually doing here have enough examples to work with and then use those as the basis of a policy to enforce going forward and it's not necessarily something I just from the starting gate saying let's use all these libraries and enforce all these rules and maybe the rules don't actually make sense I still want to evaluate whether those rules actually make sense for any given project you said there's a part to you okay so those two parts learn to curve it okay all right well thank you very much if you want to talk to me afterwards with more questions I'll be hanging out here or maybe here or maybe at the beer place over there but I'll be around thank you very much
Info
Channel: DevConf PL
Views: 1,257
Rating: 5 out of 5
Keywords: DevConf 2017, Jimmy Bogard
Id: DD1hGmomJws
Channel Id: undefined
Length: 52min 2sec (3122 seconds)
Published: Fri Sep 29 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.