Blog

  • The Value Of Re-inventing The Wheel

    The Value Of Re-inventing The Wheel

    A prior post discussed some of the challenges with using code generators.  One thing we did not cover was the value of re-inventing the wheel.  In particular, this holds true when we are learning problem-solving.  That means one of the ways to become better developers is to solve problems that have already been solved.  The objective is not so much the solution as the process.

    Skipping Ahead Without Re-inventing The Wheel

    Software developers often use frameworks and code generators to improve productivity.  They also can find ways to quickly code a series of common modules through libraries and pre-built scripts.  That approach is obviously a route to rapid development.  However, it also is a potential way to allow skills to rust from lack of use.  We can say we do not need to re-invent the wheel, there is no value in solving something where the solution is known.  However, that is not completely true.  There is value in analyzing a problem and finding a solution even when it is known.  We learn how to think in a critical and logical manner.  There are also repeated patterns in developing solutions.

    Repetition Across Solutions

    The idea of patterns emerging in problem-solving is not often discussed.  They tend to be a sort of obvious secret or maybe even common sense.  Nevertheless, we need to be able to apply these patterns to become better problem solvers.  The stories about Sherlock Holmes show some of these.  Sometimes it is all a matter of deduction, or maybe a process of elimination.  There are these sorts of solution patterns that can be used over and over in solving even very complex problems.  The more we are familiar with these patterns, the more we can combine them into new and complex solutions.  When we skip to the solution on common problems, as we do with code generators, we also pass on that learning opportunity.

    I think that persistence is often undervalued. That is another skill we do not develop when we take the shortest path to a solution. There is value in spending time banging one’s head against a problem while we try to solve it. We also can develop good habits as we struggle through those “simpler” problems. Think of code generators and frameworks as a way of pushing the cost of developing skills down the road. There are times that is needed. However, we may end up paying an exorbitant price in the future. That is not much different from pushing upgrades off to the future and eventually paying a huge price or even being blocked from an upgrade path.

    The Power of Persistence

    One of the traits of a strong developer is persistence.  We encounter all manner of obstacles that require us to persevere as developers.  These are well-known among us and range from simple headaches like a hard-to-find misspelling to magic numbers and complex configuration combinations.  Re-inventing the wheel can be a path to practice such patience and perseverance.  The benefit of these well-known problems is that we have ways to move us forward when we are blocked.  We get to go through the motions with a form of training wheels to help us get past steps that stop our progress.

    These are areas where practice helps us.  Thus, using tools that help us skip ahead on problems can remove that practice and the related benefits.  A similar example is a basketball player that skips free throws because they know they can make them.  We also have mental “muscles” that can be exercised to create muscle memory and better performance in other areas of problem-solving.

  • Payment Strategies – Finding a Comfortable Time Frame For You And Customers

    Payment Strategies – Finding a Comfortable Time Frame For You And Customers

    One of the challenges all consultants face is setting up payment strategies for their customers. There is a need to keep revenue flowing while providing a reasonable amount of time for processing invoices. That is not as much a problem when there are multiple customers and they pay regularly. However, it can be crippling to a business when bill payments (or payroll) are delayed due to accounts receivable (AR) issues. A small company or individual consultant can struggle with this. Thus, it is worth our time to examine some options.

    Not One Size Fits All

    Note that the discussion is on strategies and not a single strategy. I have found this to be one of the first steps in meeting your needs and your customers’ needs. One way to slice up the approaches is based on your trust or experience with customers. This approach provides more grace in payments to your established customers while limiting risk for newer ones. Payments terms can be based on AR age or AR total. Both of these are easy enough to track for even a small company and can be set in contract requirements.

    I find that both approaches are helpful in small consulting companies. Some projects generate minimal revenue month over month. That can lead to small receivables sitting on the books for several months. At the other extreme, large revenue items can be critical to cash flow. When they are not received on time, the business can struggle. That latter situation is often a challenge for small consulting companies or individuals due to the feast or famine nature of this business.

    Payment Strategies Based on Trust

    Trust of customers and their payment processes is most effective when it is based on past experience. Therefore, it is best to start all new customers with a tighter set of rules and then loosen them after they have gone through multiple pay cycles. I recommend a minimum of three complete cycles. One or two is too easy to be an aberration or just them trying to keep new accounts current. Then, as you see consistent invoice and payment cycles, you can adjust your requirements to fit cash flow needs.

    Cash Flow Is King

    We all want to sign contracts and get those billable hours flowing. However, we need to see the payments for those hours flowing as well. When planning payment strategies, you need to be aware of your business’s monthly budget/payables and related payment terms. There is often a delay of 30 days or more from invoice to first payment, which can cause challenges if you do not have reliable cash reserves. Take note of your bank’s deposit hold terms as well. Receiving a payment is not the same as those funds being available. That may seem minor. However, we can see fewer and larger deposits for some customers that trigger the hold rules. I have often seen this pop up when a customer delays a few payments and then catches up in one big check.

    Splitting Invoices And Pre-Payments

    Many companies are hesitant to be aggressive with payment strategies when they start. Therefore, they set and accept customer-friendly terms but can lead to struggles as the business gets off the ground. Nevertheless, it is easier to reduce restrictions and policies than add them. Therefore, the best time to take a hard-line stance is when you start a customer relationship.

    Multiple invoices and early invoicing can help with this. Some companies invoice immediately on receiving a signed contract. That can cut down the time to payment by weeks or more. Likewise, it is more acceptable to pre-invoice some portion of the project or request a fee to start work. This strategy reduces risk and ensures you have some cash flow from the time the project begins. It may not solve all the problems, but it is an excellent first step.

  • Reasons To Avoid Code Generators

    Reasons To Avoid Code Generators

    When one goes looking for reasons to use code generators, the articles tend to skew positive. I guess most people need to be convinced that these are good tools. However, there is a dark side to code generators. Well, that may be a bit over-dramatic. However, there are reasons that a code generator should be avoided and definite drawbacks to using one. Allow me to make the case against these productivity tools.

    Ignorance By Abstraction

    The first problem we can look at is what I call ignorance by abstraction. This effect happens when we shield people from the underlying process for any task. For example, you look at your watch and read the time. You have no idea how it “knows” what time it is. You are ignorant of that functionality or process. Code generators often provide that abstraction. Yes, a developer can always review the source code. However, how often do you see that happening? There may be an initial deep dive into the generated code when the tool is evaluated. That is where it ends in most cases. You assess the tool and then trust it. Future developers may blindly use it and never even see the source code.

    Confusing Custom With Standard

    Frameworks also suffer from this weakness, but code generators hide it better. This situation occurs when a developer gets so used to how a tool helps, they think it is part of the environment. There are many developer tools that fall into this category. The result can be great for productivity but can also end with tool lock-in or limit career moves. I have come across developers that end up stuck in a job because they are so reliant on the tools that the company provides. That may seem like a win for the company, but it can scare away better talent. These environments also deter those that want to focus on learning a language or environment. Instead, your team is just learning tool usage.

    Performance And Maintenance Woes

    An often overlooked weakness in code generators (and frameworks) is how they provide a general solution. In some cases, this just leads to unused code. On the other hand, it can lead to slow code that is difficult to maintain. It can be frustrating and time-consuming to sort through excess code while debugging. There also are performance issues that often arise. The best way to build a code generator that allows for extensible code is through abstraction. However, those abstraction layers take time to process during runtime. That can cause performance issues that cannot be overcome. The generated code provides a baseline that cannot be moved without removing the tool. When you hit those sorts of walls, you will hear a lot of wailing and gnashing of teeth.

    Regeneration Nightmares

    I worked on code generators early in my career for a tool called Power Builder. We ended up often having more layers on top of the primary tool than it supported. We ended up spending hours each week in generation and regeneration and compiling cycles. I lost track of how many hours were spent in non-productive waiting for a system process to complete. This was not uncommon in those days of application compiles that often took dozens of minutes or more. Nevertheless, we had to be aware of what might be over-written in our code during a regeneration process. Likewise, there are side effects we might have on the same. I am not sure the resulting time savings were worth it.

    Scalability and Extension

    That leads to another weakness code generators can run into. They do not always scale. I have run into this often with RDBMS object mapping generators. The tools have an approach that makes assumptions that make sense until you get to large or complex solutions. The problems may occur as name collisions, objects with too many properties, tables with too many columns, or overhead that buries the system. Consider what audit information adds when you scale it to large and complex systems. Do you really need audit information for every data lookup item?

    While some solutions and generators provide configuration or customization, that can also be expensive in both time and performance. There is a chance that an update of the tool or even a new code generation will break custom code. Those changes may also fall outside of the patterns the code generator uses and have a negative impact on application performance. Think of it as the tool plotting a specific course through the generated code. Then, the customization tries to change the course. There is a form of working against yourself that occurs in those situations that can cause maintenance and performance degradation.