Design Patterns and Coding Standards in Software
-
- Posts: 10339
- Joined: June 15th, 2011, 5:53 pm
Design Patterns and Coding Standards in Software
In software, design patterns are general descriptions of the types of structures that are used in designing software, less general than a paradigm but more general than a specific algorithm.
Coding standards are sets of rules, applied with varying levels of strictness, that are deemed to result in maintainable, reliable, readable, efficient and efficacious code.
To avoid a long OP I'll leave it there for now and see if anyone is interested. If anyone is, perhaps they could start by giving an example of one of the above and trying to see if it in any way exemplifies a principle of design that might count as philosophy, perhaps by counting as "a philosophy", as that term is often used. If nobody is interested, I'll attempt to do that myself.
- Pattern-chaser
- Premium Member
- Posts: 8268
- Joined: September 22nd, 2019, 5:17 am
- Favorite Philosopher: Cratylus
- Location: England
Re: Design Patterns and Coding Standards in Software
The superficial aspects of patterns and coding standards show little of philosophy, I feel, but the deeper concepts that underlie them - the ones that are more general, if not universal - do approach philosophy, IMO.
Sadly, it seems there's only me and you who consider this to be a topic worthy of discussion. Thanks for trying.
"Who cares, wins"
- Papus79
- Posts: 1798
- Joined: February 19th, 2017, 6:59 pm
Re: Design Patterns and Coding Standards in Software
-
- Posts: 10339
- Joined: June 15th, 2011, 5:53 pm
Re: Design Patterns and Coding Standards in Software
Yes, I think one of the ways in which a topic like this is easiest to relate to philosophy is by considering the nature of order and how it relates to the act of design. It could then reach out, via philosophical considerations, to subjects such as Intelligent Design - the arguments put forward by Creationists which rest on the notion that the act of design has particular identifiable features. That then leads to the old joke about why so much of the information encoded in our DNA is apparently unused. (The punchline is that when God wrote the code he added lots of comments, or commented-out large sections.)Pattern-chaser wrote:Patterns, after all, came from the work of architect Christopher Alexander, but the principles were found to be applicable and useful to software design and designers. Those of us that delved into The nature of order found much that is of interest, although few would be willing to delve into it, as the concepts are not simple or easy.
Feel free to do so.Papus79 wrote:...but I feel like I could at least pick at what I think is good for best practices so far. Not sure how far that will go but I'm willing to amble a bit.
From all the various individual rules that get written into coding standard, I wonder if a single general principle could be distilled, that would be less vague than "write good code".
- Papus79
- Posts: 1798
- Joined: February 19th, 2017, 6:59 pm
Re: Design Patterns and Coding Standards in Software
Keep your data tables as open and loosely connected as possible. Avoid unnecessarily hard-binding data, even if it looks tidier in some cases, because you never know when your client will admit that what looked like two very tightly correlated pieces of data is really three or four or that they need you to insert a couple layers of abstraction into that relationship. Best to just keep each category isolated with a guid and slot it in as a guid value on another table.
On that same note keep everything as open, expandable, and 'breathable' as possible in the way you structure the code (avoid too much interdependency) because unlike building a house you never know when your client is going to say they want to add a tower over here, a patio over here, a third and fourth story over here, a full Walmart or Costco over there, or even expand this side to jam a few more rooms into the interior. People are chaotic, apathetic, they'll give disorganized and apathetic requirements that you'll have to wade through, organize, question, etc. and even then you'll only be heading off some of the problems to come - they don't know how any of it works or how how much work it is, they just know they're paying you.
Don't be afraid to apply async and promises liberally, even using observables as puppet wires for other functions so long as you know how to keep them from hooking each other by mistake. Maybe the the additional advice there is do your best to avoid using timeouts to wait for API's or any other long processes, it's dangerous to do that as you're really setting up a race condition and you never know just what kind of antique someone might be using or how bad their VPN tunnel might be, far and away better to actually know - precisely - what event you're waiting before in order to move on to the next line of code and then hook that piece (for me most often a particular promise in series). Async is also important on the server side if you want to avoid those annoying thread pool starvation scenarios where an API call most of the time takes 1.5 second but occasionally it takes 25.
Don't worry about splitting everything into microfunctions or only the or four lines of code per functions (it's fine for utility and export functions maybe), so long as you have good error trapping and feedback and you know how to structure your code to have good failovers with try/catch/finally blocks then you're better off having readable code that sorts out by subject heading and if that particular class starts getting to be something like 4000-6000 lines feel free to start delegating some of the work to another class, particularly if there's some piece of logic that you can see yourself using over somewhere else.
If it's harder work to bundle your API calls for the sake of speed who cares - do it, it'll save a lot of wait time and it's something that'll grind on the patience of the client if they have anything like 5-7 second load times for an app when you can load your resources in 1.5 or 2 seconds by bundling the API call.
Enum's are great for avoiding keystroke errors in your code. If you have some hard-coded values that you're using in the program, especially default values for objects that you're creating, having enums to get them from something like a switch/case helps avoid typographical errors and also makes it much easier to maintain them from one place.
Change detection strategies like onpush, especially with complex UI's, are well worth learning to implement because it helps avoid a lot of the grind, has similar benefits to things like ngZone.
If you're using a typescript framework, like Angular, avoid using the forms and validation they give you - they're pretty bad and you're really better off making your own validation patterns. It might seem like it takes a bit longer to build these things from scratch you also don't have to beat your head into a wall over the way someone else built a validation suite and when you have one or two more requirements on a field than the given validation offers you're not caught in a bind.
You could maybe extend some of the principals in that last paragraph to 'avoid third party black boxes whenever possible - unless you don't mind having someone else in control of your ability to do your job'. Or at least if you're going to use a black box keep it to something very simple like a codec.
The attention you pay to making your code fail if anything veers off course and the more self-checks you build into your system to assure that it fails if it doesn't pass your audits at the end of larger processes (especially with something like a finance or accounting app) the fewer sleepless nights you have. Building your own analytic tools to watch for different types of potential error (like SQL views for example) also helps. Nothing's worse than having something not only fail without error but also not fail in a way that can come across your radar quite quickly.
If you're dealing with contingent data, like a finance app, it might be better to have it constantly rebuilding itself to both catch and mend bugs.
Other than that - keep your code as clean as you can, not to look 'all prim and proper' for someone else but for your own sanity - ie. you'll be the one who has to read it and fix it later most likely and sometimes the logic of what you're looking at could still take an hour or two to refamiliarize yourself with depending on just how much complexity your client had you bake into it - that's bad enough, don't make matters worse by having loads of commented out content, stuff you know is vestigial from prior changes that doesn't do anything, etc.
- Pattern-chaser
- Premium Member
- Posts: 8268
- Joined: September 22nd, 2019, 5:17 am
- Favorite Philosopher: Cratylus
- Location: England
Re: Design Patterns and Coding Standards in Software
Perhaps these more abstract matters are closer to philosophy?
"Who cares, wins"
- mystery
- Posts: 380
- Joined: May 14th, 2021, 5:41 am
- Favorite Philosopher: Mike Tyson
- Location: earth
Re: Design Patterns and Coding Standards in Software
For examples:
A flat concrete roof should have the steel of the proper size and number. none can see it after completion until an earthquake occurs.
A software project should attempt to use common design patterns. none can see it until after a severe defect is reported and the original designer is gone.
In both cases, it is a disaster of epic proportions. Because the cowboy does not drink the cool-aid. Do they not understand or don't care. Should such a thing be a crime? In both cases the financial impact is much. Talent without accountability.
Of course, we have quality control groups in software and building inspection for construction. Is the need for these due to lack of education or laziness in the design process.
-
- Posts: 10339
- Joined: June 15th, 2011, 5:53 pm
Re: Design Patterns and Coding Standards in Software
Yes. Dependency hell is a good way to make code unmaintainable and un-adaptable because it ensures that you can't change one thing without affecting an often unknown number of other things.Papus79 wrote:avoid too much interdependency
This is, among other things, another way to reduce interdependency and encourage encapsulation.Don't worry about splitting everything into microfunctions or only the or four lines of code per functions...
I once had a job at a small company setup by one guy and working on a code base he'd started himself and which he clearly regarded as his baby. Among the coding standards he gave his developers was one that said "Don't encapsulate. We're not children.". He didn't. The large piece of stock market data streaming software he'd given birth to was all based around a single function thousands of lines long. It was almost entirely unmaintainable. But he was the boss. To be fair, he'd still made his fortune from it. Although his wife had made a bigger fortune writing a famous series of children's books. (No, not that one.)
Yes, they avoid "magic numbers". The main pitfall of magic numbers is that they allow lack of type safety by having possible values that don't make sense and being ambiguous. If you see the number '1' in some code, is it supposed to represent "true"? Is it supposed to be a counter? Is it the first item in a list? It's not obvious.Enum's are great for avoiding keystroke errors in your code....
Ideally, anything that doesn't represent a valid state should throw a compiler error or warning.
-
- Posts: 10339
- Joined: June 15th, 2011, 5:53 pm
Re: Design Patterns and Coding Standards in Software
- Pattern-chaser
- Premium Member
- Posts: 8268
- Joined: September 22nd, 2019, 5:17 am
- Favorite Philosopher: Cratylus
- Location: England
Re: Design Patterns and Coding Standards in Software
Yes, and this aims us at the first part of the topic title: design patterns. These are templates that help us implement code according to "need to know", and other similar guidelines.
"Who cares, wins"
- Papus79
- Posts: 1798
- Joined: February 19th, 2017, 6:59 pm
Re: Design Patterns and Coding Standards in Software
When I really think about it, I'd love to have the linter yell at me anytime I break type in some way as well. I ran into an issue recently in Angular where I've been using interfaces to frame objects since I started and I found out that if you threw the wrong object in that had all of the same properties of the object that belongs to... lets just say in this case we're dealing with a Subject or BehaviorSubject... it won't give a red underscore or give any error. It'll throw an error if a property is missing but it won't throw an error if there are extra properties. Adding a ?never property in seemed to fix that, obviously though it's not a satisfying patch and the utility of it would be blown if you had three such related objects or more.
-
- Posts: 10339
- Joined: June 15th, 2011, 5:53 pm
Re: Design Patterns and Coding Standards in Software
Yes indeed. Although I guess relatively few standard design patterns are specifically about encapsulation/"need to know". I suppose they're more often about robust ways to solve particular classes of problems(?)Pattern-chaser wrote:Yes, and this aims us at the first part of the topic title: design patterns. These are templates that help us implement code according to "need to know", and other similar guidelines.
I suppose the ultimate is a tool which allows you to describe, in English (or other human language), what we want to do and for the tool to take care of translating that to code. But, as we know from this site, English can be ambiguous. Failing that, I guess the ideal of Lint-like tools (either as separate tools or built into modern compilers and IDEs), combined with coding standards, is to ensure that compiler errors and warnings tell us if we're doing anything we didn't intend to do. e.g. if we're using a type the wrong way (making a category mistake, we might call it in philosophy) or setting a parameter outside of the bounds we intended it to have.Papus79 wrote:When I really think about it, I'd love to have the linter yell at me anytime I break type in some way as well.
I'm not familiar with Angular. (Had to google it.) But there's perhaps an interesting philosophical point there about the analogy between objects in OO programming and real life objects, and the way in which the class to which an object belongs is recognized. You seem to be saying that in the programming environment you're using the class is recognized by its public properties? But maybe it isn't.I ran into an issue recently in Angular where I've been using interfaces to frame objects since I started and I found out that if you threw the wrong object in that had all of the same properties of the object that belongs to... lets just say in this case we're dealing with a Subject or BehaviorSubject... it won't give a red underscore or give any error. It'll throw an error if a property is missing but it won't throw an error if there are extra properties. Adding a ?never property in seemed to fix that, obviously though it's not a satisfying patch and the utility of it would be blown if you had three such related objects or more.
Maybe this is polymorphism. You mentioned what I assume are two classes (Subject and BehaviorSubject). Is one of them derived from the other? Is a BehaviorSubject a special case of a Subject? If so, does the language you're using allow you to polymorphically pass a reference to a BehaviorSubject via a Subject pointer? If so, that might be why you're seeing the behaviour you've described.
-
- Posts: 10339
- Joined: June 15th, 2011, 5:53 pm
Re: Design Patterns and Coding Standards in Software
- Papus79
- Posts: 1798
- Joined: February 19th, 2017, 6:59 pm
Re: Design Patterns and Coding Standards in Software
Yes and no on Subjects and BehaviorSubjects being like classes (I'm familiar with them from RxJS but I don't know whether they're based on identical concepts in other places - probably are - or what the names of those features would be in the language(s) you're familiar with). They can contain classes but really they're a bit more like defined contents of an observable (an observable is something you can subscribe to somewhere else in the program, that subscription watches for changes in that content, etc.).Steve3007 wrote: ↑May 19th, 2021, 6:16 am Maybe this is polymorphism. You mentioned what I assume are two classes (Subject and BehaviorSubject). Is one of them derived from the other? Is a BehaviorSubject a special case of a Subject? If so, does the language you're using allow you to polymorphically pass a reference to a BehaviorSubject via a Subject pointer? If so, that might be why you're seeing the behaviour you've described.
I think the thing that I probably shouldn't be surprised by - using export interfaces in typescript - you're right about the polymorphism, they're much more like the interfaces in C# than I was initially lead to believe. I didn't get a formal education in programming, it was mostly some combination of Pluralsight and 'fake it to you make it'. Based on that, whether it was tutorials or third-party software connections, I saw people were using interfaces rather than classes for defining their objects and object arrays. There's probably nothing wrong with that as long as one knows what they're dealing with (in which case sure - it's fine to say that if Object1 had five properties A,B,C,D, and E and Object2 has properties A,B,C,D,E, and F, then an interface based on the properties of Object1 should receive both), I have yet to rewrite whole problems with classes instead but I saw some suggestions that this wouldn't necessarily solve the problem either - which, as it is, people talk and I generally prefer to try something myself. I'll have to try a more strictly class-based approach in one of my sandbox projects to see whether it's worth the tradeoffs, whether it actually does stop overload of this kind, etc..
- Papus79
- Posts: 1798
- Joined: February 19th, 2017, 6:59 pm
Re: Design Patterns and Coding Standards in Software
I did complete a short Udemy course recently on Rust (building a HTTP 1.1 server) because it looks like it could be a really good workhorse for making things happen under the hood (connected through WASM) and I have a feeling it's going to get bigger for web apps. The only annoying thing for the moment is that calling Rust asynchronously in typescript/Angular seems to work just fine, you're supposed to be able to call it asynchronously once and then call it synchronously after that - way more practical IMHO - but I haven't come across a working implementation for that initial call and follow-up import and implementation.
2023/2024 Philosophy Books of the Month
Mark Victor Hansen, Relentless: Wisdom Behind the Incomparable Chicken Soup for the Soul
by Mitzi Perdue
February 2023
Rediscovering the Wisdom of Human Nature: How Civilization Destroys Happiness
by Chet Shupe
March 2023