Data Concurrency

0

Category : ,

Concurrency Conflicts

A concurrency conflict occurs when one user displays an entity's data in order to edit it, and then another user updates the same entity's data before the first user's change is written to the database.

Pessimistic Concurrency (Locking)

before you read a row from a database, you request a lock for read-only or for update access. If you lock a row for update access, no other users are allowed to lock the row either for read-only or update access. If you lock a row for read-only access, others can also lock it for read-only access but not for update. complex to program. requires significant database management resources can cause performance problems as the number of users of an application increases The Entity Framework provides no built-in support for it

Optimistic Concurrency

Optimistic concurrency means allowing concurrency conflicts to happen, and then reacting appropriately if they do. There are 3 different approaches:
  1. You can keep track of which properties conflicting users have modified and update only the corresponding columns in the database. Can't avoid data loss if competing changes are made to the same property of an entity. Often not practical in a web application, because it can require that you maintain large amounts of state in order to keep track of all original property values for an entity as well as new values.
  2. Client Wins or Last in Wins allow all changes to happen, if you don't do any coding for concurrency handling, this will happen automatically.
  3. Store Wins prevent 2nd user's change from being updated in the database. Typically, you would display an error message, show this user the current state of the data, and allow her to reapply her changes if she still wants to make them.
my thanks to this article on handling data concurrency with Entity Framework:
https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application

Career development

0

Category : ,

Learning & Improving

The best way I know of to excel in software is to keep a growth mindset. The more you can learn and improve, the more career options you'll have.

Improvement can be broken down along two lines: input and output. I've tended to go through phases in my career where I've done more input than output, and (less often) vice versa, but I've found both to be essential for improvement.

Input

There are innumerable ways to gain knowledge: articles, books, papers, MOOCs, conversations, experimentation, project documentation, access to experts who are willing to answer questions, and many more. Quality and efficiency vary across these

Personally, I've gotten a ton of value out of reading books and applying what I've learned. concentrating your reading more on classic books that'll help you throughout your career. Book authors have spent many months, maybe years, distilling their years of experience into a well-crafted format that you can inhale over a few weekends.

I'll mostly stick to broad areas here rather than specific book recommendations, but you can check out my Goodreads profile for more specifics if you're curious.

Learn about software career development. For broad career development issues, I'll make an exception in this post and highly recommend Apprenticeship Patterns, The Pragmatic Programmer, and The Passionate Programmer. Bluntly, if you were to stop reading this post right now and go read those three books instead, I'd think you made a wise decision.

Learn about code. Again, I prefer books to blog posts.
Learn about the specific languages and frameworks that you're concentrating on.
Learn about software design & architecture principles and patterns.
Learn about test-driven development and refactoring.
Learn about the platform you're deploying to.
Learn about foundational computer science concepts.

Learn about communication. There's a lot of material out there, both in the software space and outside. The way you communicate is a crucial part of the way others perceive you, whether it's in conversations, in emails, or in documentation. Learn about logical fallacies, cognitive biases, and nonviolent communication. Look for materials on communicating in effective writing, presentations, and difficult conversations.

Read open-source code. My experience is that reading OSS code is most effective when you've got a specific purpose in mind. But it can also be instructional to clone a repository from GitHub, run the tests, try and reproduce issues in the issue tracker, etc. At worst, you get an idea of how someone else codes and what's easy or hard for you to understand. And at best, you'll find yourself leaning over into the output side of things, which we'll discuss next.

Output

Write code. This isn't necessarily the most important skill you'll need in your software career, but it's certainly the one that's most unique to the role of a software developer. There are lots of ways to practice writing code, but my personal favorite is doing code katas.

Code katas have a couple of main schools of thought, and I like both of them for different reasons:

  • Repetition. By solving the same problem many times with the same or similar solutions, you get to understand the problem really well. This gives you a sense of mastery, which I've found to be great for my emotional well-being when I'm mostly frustrated by programming problems. You can treat these as either a meditation, where you're thinking deeply, or as a race, where you're honing your skills with the tools. Some folks even treat repetition katas as a performance, with or without musical or spoken accompaniment.
  • New problems/solutions. The idea here is that most of the coding part of the job is about thinking about and solving new problems, ones that might be related to ones you've seen before but aren't identical. With new problem katas, you're intentionally putting yourself in the uncomfortable position of not-knowing, where we each need to learn to be OK as we're moving toward solutions. You can find lots of examples of bite-sized katas—many have ridiculous names, but they can still be great exercises to work through.

Katas are typically fairly constrained problems compared with "the real world"—more on the order of a single sitting, though some can get quite tricky and take much longer.

Breakable toys are much more realistic and larger-scope projects than katas, but they still aren't mission-critical.So it's OK if they get broken as you're learning. Having a breakable toy lets you see how different ideas work in the long term, which is super-helpful in the work world.

Open source software can be pretty intimidating to get into, but there are a few reasons I still think it's a good idea to look at. First, you can get practice learning a new codebase. Second, for many (not all) open-source projects, the level of code quality is pretty high. You'll get a chance to see how experienced folks approach problems and solve them, by browsing issue and pull request history.

Learn to use the project really well if you don't already. This will force you to go through the existing documentation, and you'll probably find some low-hanging fruit: typos, grammar issues, hard-to-understand explanations, etc. I've also heard good things about OSS issue aggregators like OpenHatch and Up for Grabs for finding projects that fit the bill here.

Practice empathy and communication in your daily interactions. When little misunderstandings occur, ask yourself how they happened and what you can do in the future to prevent them. And how can you get past the misunderstanding with everyone feeling better afterward than before. When you're talking, ask yourself what your audience needs from you—do they need all the details, or do they mostly care about the highest-level bits? These skills are among the most crucial for any job that requires collaboration.

Managing your time

decide what your goals are at a high level, and find ways to move in that direction incrementally. One idea is to take a tip from agile project management: take your big hairy audacious goal (product), figure out the first step or two towards it (releases), break the first one down to the first few medium-sized goals toward it (epics), and break those down into goals that you can knock out in a single sitting (stories). In this way, you can fit learning into the space that's available, rather than having to rely on luxuries like wide-open nights and weekends.

Find mentors

We all need feedback. Without feedback on how we're progressing, it's easy to divorce our own self-assessment from reality, and to think that we're doing much worse or better than we really are.
try to find at least one person who can help guide you in your progress. My first real mentor didn't have a formal mentoring role, but he was the developer in the next cube, he was a few years ahead of me in experience, and he understood how to communicate the basics. Between his direct feedback and the books he told me to read
You can find mentors outside the workplace, too.
  • CodeNewbie is a Twitter chat, podcast, blog, and community with tons of great ideas about breaking into and excelling in this industry, with participants at all levels.
  • Social media: Despite its [my] faults, I've found Twitter to be particularly well-populated with software experts sharing tips, links, and stories. And some people are willing to answer questions directly—others have too many folks jostling for their attention, so don't feel too bad if they can't make time for you directly.
  • User groups: If you're in an area that has them and you can make the timing work, user groups can be a great place to meet other folks who are excited about software. Check out Meetup for topics you might be interested in. Introduce yourself and make connections—if you're like me this will be hard, but you might just meet your next employer here.
  • Open source software: The people reviewing your pull requests are already giving you direct feedback! Maybe not career-level stuff, but they might be up for that too as you contribute more.

the name of the relationship isn't all that important—what you really want here is to get external feedback and make progress toward your goals.

my thanks to this fantastic blog post:
https://8thlight.com/blog/colin-jones/2017/10/24/advice-for-early-career-developers.html

Clean Architecture

0

Category :

Alot of modern architectures(a lit of which is on the original post referenced at the bottom) are trying to achieve the same objective, which is the separation of concerns. They all achieve this separation by dividing the software into layers. Each has at least one layer for business rules, and another for interfaces.

Each of these architectures produce systems that are:

  1. Independent of Frameworks. The architecture does not depend on the existence of some library of feature laden software. This allows you to use such frameworks as tools, rather than having to cram your system into their limited constraints.
  2. Testable. The business rules can be tested without the UI, Database, Web Server, or any other external element.
  3. Independent of UI. The UI can change easily, without changing the rest of the system. A Web UI could be replaced with a console UI, for example, without changing the business rules.
  4. Independent of Database. You can swap out Oracle or SQL Server, for Mongo, BigTable, CouchDB, or something else. Your business rules are not bound to the database.
  5. Independent of any external agency. In fact your business rules simply don’t know anything at all about the outside world.

The diagram at the top of this article is an attempt at integrating all these architectures into a single actionable idea.

The Dependency Rule

The concentric circles represent different areas of software. In general, the further in you go, the higher level the software becomes. The outer circles are mechanisms. The inner circles are policies.

The overriding rule that makes this architecture work is The Dependency Rule. This rule says that source code dependencies can only point inwards. Nothing in an inner circle can know anything at all about something in an outer circle. In particular, the name of something declared in an outer circle must not be mentioned by the code in an inner circle. That includes, functions, classes. variables, or any other named software entity.

By the same token, data formats used in an outer circle should not be used by an inner circle, especially if those formats are generate by a framework in an outer circle. We don’t want anything in an outer circle to impact the inner circles.

Entities

Entities encapsulate Enterprise wide business rules. An entity can be an object with methods, or it can be a set of data structures and functions. It doesn’t matter so long as the entities could be used by many different applications in the enterprise.

If you don’t have an enterprise, and are just writing a single application, then these entities are the business objects of the application. They encapsulate the most general and high-level rules. They are the least likely to change when something external changes. For example, you would not expect these objects to be affected by a change to page navigation, or security. No operational change to any particular application should affect the entity layer.

Use Cases

The software in this layer contains application specific business rules. It encapsulates and implements all of the use cases of the system. These use cases orchestrate the flow of data to and from the entities, and direct those entities to use their enterprise wide business rules to achieve the goals of the use case.

We do not expect changes in this layer to affect the entities. We also do not expect this layer to be affected by changes to externalities such as the database, the UI, or any of the common frameworks. This layer is isolated from such concerns.

We do, however, expect that changes to the operation of the application will affect the use-cases and therefore the software in this layer. If the details of a use-case change, then some code in this layer will certainly be affected.

Interface Adapters

The software in this layer is a set of adapters that convert data from the format most convenient for the use cases and entities, to the format most convenient for some external agency such as the Database or the Web. It is this layer, for example, that will wholly contain the MVC architecture of a GUI. The Presenters, Views, and Controllers all belong in here. The models are likely just data structures that are passed from the controllers to the use cases, and then back from the use cases to the presenters and views.

Similarly, data is converted, in this layer, from the form most convenient for entities and use cases, into the form most convenient for whatever persistence framework is being used. i.e. The Database. No code inward of this circle should know anything at all about the database. If the database is a SQL database, then all the SQL should be restricted to this layer, and in particular to the parts of this layer that have to do with the database.

Also in this layer is any other adapter necessary to convert data from some external form, such as an external service, to the internal form used by the use cases and entities.

Frameworks and Drivers.

The outermost layer is generally composed of frameworks and tools such as the Database, the Web Framework, etc. Generally you don’t write much code in this layer other than glue code that communicates to the next circle inwards.

This layer is where all the details go. The Web is a detail. The database is a detail. We keep these things on the outside where they can do little harm.

Only Four Circles?

No, the circles are schematic. You may find that you need more than just these four. There’s no rule that says you must always have just these four. However, The Dependency Rule always applies. Source code dependencies always point inwards. As you move inwards the level of abstraction increases. The outermost circle is low level concrete detail. As you move inwards the software grows more abstract, and encapsulates higher level policies. The inner most circle is the most general.

Crossing boundaries.

At the lower right of the diagram is an example of how we cross the circle boundaries. It shows the Controllers and Presenters communicating with the Use Cases in the next layer. Note the flow of control. It begins in the controller, moves through the use case, and then winds up executing in the presenter. Note also the source code dependencies. Each one of them points inwards towards the use cases.

We usually resolve this apparent contradiction by using the Dependency Inversion Principle. In a language like Java, for example, we would arrange interfaces and inheritance relationships such that the source code dependencies oppose the flow of control at just the right points across the boundary.

For example, consider that the use case needs to call the presenter. However, this call must not be direct because that would violate The Dependency Rule: No name in an outer circle can be mentioned by an inner circle. So we have the use case call an interface (Shown here as Use Case Output Port) in the inner circle, and have the presenter in the outer circle implement it.

The same technique is used to cross all the boundaries in the architectures. We take advantage of dynamic polymorphism to create source code dependencies that oppose the flow of control so that we can conform to The Dependency Rule no matter what direction the flow of control is going in.

What data crosses the boundaries.

Typically the data that crosses the boundaries is simple data structures. You can use basic structs or simple Data Transfer objects if you like. Or the data can simply be arguments in function calls. Or you can pack it into a hashmap, or construct it into an object. The important thing is that isolated, simple, data structures are passed across the boundaries. We don’t want to cheat and pass Entities or Database rows. We don’t want the data structures to have any kind of dependency that violates The Dependency Rule.

For example, many database frameworks return a convenient data format in response to a query. We might call this a RowStructure. We don’t want to pass that row structure inwards across a boundary. That would violate The Dependency Rule because it would force an inner circle to know something about an outer circle.

So when we pass data across a boundary, it is always in the form that is most convenient for the inner circle.

Conclusion

Conforming to these simple rules is not hard, and will save you a lot of headaches going forward. By separating the software into layers, and conforming to The Dependency Rule, you will create a system that is intrinsically testable, with all the benefits that implies. When any of the external parts of the system become obsolete, like the database, or the web framework, you can replace those obsolete elements with a minimum of fuss.



my thanks to this great blog post:
https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html

Learn “Why” not “How”

0

Category :

Fleeting Knowledge - Language Specific

That would be a framework’s API and syntax. Knowing those nitty gritty details of Angular and its API is necessary to be productive in an Angular codebase, but it’s useless in any other codebase. I refer to this type of knowledge as the “how” as in, “How do I do X in Angular?”.

Enduring Knowledge

The more enduring kind of knowledge is the “why”. Why does Angular exist? Why does it have the features that it has? What problems is it trying to solve?
Frameworks like Angular may have a short lifespan, but the problems they tackle live on for much longer. Angular was built to tackle the problem of writing, maintaining, and iterating on complex web apps. Any knowledge that helps us approach this problem will be valuable for a long time. In fact, it’s not a huge stretch to swap “web apps” for “software”, and suddenly we’ve got a problem that’s going to last an entire career! That’s the kind of knowledge we want — the enduring kind.

Diving Deep

Asking “why” and getting to those enduring nuggets of knowledge isn’t always easy unfortunately. The context and motivation behind a particular feature is the kind of knowledge that’s harder to come by, but it’s well worth the effort. Let’s go through an example.

Say I google “Why should I use Angular”. I might run into reasons like this:
  1. MVC and separation of concerns
  2. Two-way data binding
  3. Dependency Injection
If I don’t know what MVC and dependency injection are and why they’re good practices, then I’m simply left with more questions. Why would I want dependency injection? And why is separation of concerns useful?
So let’s keep digging (this is super simplified):
  1. Angular uses dependency injection…
  2. …and dependency injection is useful for writing unit tests
  3. …and unit tests are useful for maintaining and iterating on software

Got it! Now I learned about dependency injection, which a generic design pattern that’ll be useful to me past Angular’s lifetime. This knowledge also helps me better understand how and when to use that Angular feature, and when I can ignore it. Practical knowledge for our Angular work today, and enduring design pattern knowledge for the future. Win-win!

In general, asking why is a recursive process, just like installing a software dependency. We have to follow all the recursive dependencies until they all resolve, otherwise we end up with broken software or in this case, incomplete understanding. We have to continually dig deeper until we hit a layer whose value we understand. Kids know this intuitively!

Your brain’s dependency tree

Here’s how I (simplistically) imagine the “Why Angular” knowledge dependency tree:
  1. At the top level we have the most specialized and most fleeting solutions: frameworks like Angular.
  2. One level deeper, we get into specific patterns that are common across different frameworks: DI, MVC, etc.
  3. As we dive deeper, we get into more fundamental software engineering practices, and so on until we arrive at core problems in software engineering.

I love this visualization because it exposes the deeper level concepts for what they are: building blocks. Once we dive deep into a framework that uses MVC and learn what MVC is all about, then we’ll carry that understanding over to any other MVC framework we use in the future. It’s just like when a package manager installs a new package and finds one of the dependencies already installed — it can just reuse it.

Having more building blocks doesn’t just makes us faster learners, it’s also essential for innovating new solutions. Almost every new piece of software is inspired by many other ideas before it. One example is redux, which is inspired by Flux, CQRS, Event Sourcing, and probably more (perhaps Clojure atoms). We stand on the shoulders of giants not just by using the software they built, but by understanding the ideas they introduced.

Personal Reflection

When working on a project the path of least resistance can be copy, paste and ship. But isn’t the best idea for personal growth.

You can get more value from these projects by:
  1. understanding the frameworks(Angular’s) decisions within the context of the problems it was solving
  2. asking why and not being afraid of following the rabbit holes
  3. understanding the motivations and tradeoffs behind the Angular features
We should learn frameworks not just to build stuff, but to learn new ideas because once a framework is out of use, the ideas are all that’s left. But when a framework doesn’t teach us anything new, I am reminded of Alan Perlis’s quote:

  • “A language [or framework] that doesn’t affect the way you think about programming, is not worth knowing.”

Even if frameworks come and go, we can still learn the ideas behind them and become better engineers, as long as we dive deep enough.




my thanks to this great blog post:
https://hackernoon.com/how-ages-faster-than-why-712e25c9eb3b

Writing Stable Code

0

Category :

In software, we use version numbers to signal that something has changed.

But when it comes to software version numbers, the current leader in version numbering schemes is SemVer (or Semantic Versioning). Don't be fooled, though! Many people claim to know how SemVer works, but have never read the specification. Since this is a critical piece of what we are about to talk about, here is a summary of the spec:

Version numbers take the form X.Y.Z, sometimes augmented with additional pre-release and build information: X.Y.Z-AAA#BBB. And each of those fields means something well defined and specific.

SemVer Summary

  1. X is the major number. Changes in this indicate breaking changes to the API (and/or behavior).
  2. Y is the minor number. Changes to this number indicate that new features were added, but that no APIs are broken as a result.
  3. Z is the patch version. Changes to this indicate that internal changes were made, but that no changes (even compatible changes) were made to the API.

Countless projects use a format that looks like SemVer, but many of them ignore the semantics behind the version number. Often, it seems that version numbers are incremented by "gut feel" instead of any consistent semantic: "This feels like a minor version update."

Why use versioning

Version numbers help your users understand something about the nature of the changes they can expect. If you don't follow a pattern, they are left guessing. And this frustrates people.

Following SemVer introduces rigor on two fronts:

  1. It sends clear signals to users about the depth of changes they can expect in a release.
  2. It sends a clear signal to your developers about what is, and what is not, allowed when it comes to changing the code.

I cannot understate the importance of (2). SemVer helps us impose self-discipline, which in turn minimizes both internal and external disruption.

Reorganizing, Refactoring, and Renaming

If you reorganize the package structure of your public API, or if you do a major renaming, or if you choose to change the methods/structs/classes/etc of your public API, you must increment the major version number.
Such changes mean that anyone who's using your code will experience breakage.

It's okay to make internal changes that don't touch any public API items. So minor internal-only refactoring can be done in minor, and even patch, releases (though we don't recommend doing it in patch releases).

So in effect, the following are not be be changed except during major updates:

  1. Package structure
  2. Public class, struct, enum, trait, interface, etc. names, nor the names of any of the items on these
  3. Constants or public variable names or values
  4. Function/method names
  5. Function/method signatures for existing functions except where the change is additive and the added argument is optional. Return value types and exceptions must also not change.

Introducing New Features

Minor versions may introduce new features, but features must be introduced without breaking existing APIs.

Features are additive in nature: They bring new things, but do not modify or delete existing things.

Deprecating

  1. Mark a thing as deprecated as soon as it is considered deprecated, even if that is a patch or minor release. Deprecation, after all, is a warning condition, not an error condition.
  2. Do not change the behavior of the deprecated thing during minor or patch releases
  3. Remove deprecated things only at major version changes. Until that time, you're still on the hook for supporting them.

Deprecation is a signal that in the future a thing will be removed. But it is not an excuse to change, delete, or ignore the functionality of that bit of code outside of the SemVer constraints.

Errors and Exceptions

Do not make casual changes to what exceptions are thrown and when.

Bugs and Security Fixes: How To Handle Real Life

When the real world comes crashing in, we make exceptions. But professional software developers make them wisely and carefully.

The important concept here is the minimally invasive change. That is, when patching bugs or security releases, we may need to change the API, but we should do it by changing the absolute minimum number of things we can get away with. And we do that even if it means sacrificing our "architectural purity".

Conclusion

The professional software developer has long-term usability and stability as a goal. Yes, well-architected code is important. But there is a time and place for making that your focus. And maintenance releases (minor and patch versions) are not an occasion to refactor, re-organize, or make sweeping modifications.

Be conscientious about how much effort the users of your code put into using your code. I can tell you from experience what we do when the maintenance burden you impose on us gets wearying: We stop using your tools (or we fork them).

SemVer is a communications tool. But to use it well, we must use it accurately. And that means writing code focused on stability.



my thanks to this great article:

http://technosophos.com/2018/07/04/be-nice-and-write-stable-code.html