<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.2.2">Jekyll</generator><link href="https://dovidkopel.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://dovidkopel.com/" rel="alternate" type="text/html" /><updated>2025-05-01T23:19:08+00:00</updated><id>https://dovidkopel.com/feed.xml</id><title type="html">Dovid Kopel - Technologist</title><subtitle>Musing about computers, technology, and science</subtitle><entry><title type="html">Bottom Line</title><link href="https://dovidkopel.com/2025/05/bottom-line" rel="alternate" type="text/html" title="Bottom Line" /><published>2025-05-01T23:19:05+00:00</published><updated>2025-05-01T23:19:05+00:00</updated><id>https://dovidkopel.com/2025/05/bottom-line</id><content type="html" xml:base="https://dovidkopel.com/2025/05/bottom-line"><![CDATA[<p>What is OCR? Object Character Recognition. It is the spooky magical technology that lets computers read our documents and images.
I’m not going to discuss the details of OCR, rather where OCR ends</p>]]></content><author><name></name></author><summary type="html"><![CDATA[What is OCR? Object Character Recognition. It is the spooky magical technology that lets computers read our documents and images. I’m not going to discuss the details of OCR, rather where OCR ends]]></summary></entry><entry><title type="html">Interviewing Candidates</title><link href="https://dovidkopel.com/2025/05/interviewing-candidates" rel="alternate" type="text/html" title="Interviewing Candidates" /><published>2025-05-01T23:19:05+00:00</published><updated>2025-05-01T23:19:05+00:00</updated><id>https://dovidkopel.com/2025/05/interviewing-candidates</id><content type="html" xml:base="https://dovidkopel.com/2025/05/interviewing-candidates"><![CDATA[<p>Over my career I’ve participated in probably over a hundred interviews. No matter what the position these are the four things I really look for. A resume is a piece of paper, I can usually gauge in five minutes if the candidate has what is needed for the given role.</p>

<p>The What</p>
<ol>
  <li>
    <p>Humility
I don’t know is not only an acceptable answer, it is almost always preferred to me over trying to BS a question.</p>
  </li>
  <li>
    <p>When to ask? When to search?
Based on my previous item I want to see that the candidate will in fact know when to Google around, and do some trial and error. As opposed to asking a colleague or boss. Time is valuable. That means spending several hours of their time researching and trying is preferable at times. At other times its a complete waste. Having the sense when to inquire and when not to is extremely important.</p>
  </li>
  <li>
    <p>Self-Starter
I’m a person that never really needed someone to stand over my shoulder. I don’t expect my employees to do the same. I don’t expect to babysit. For more junior employees I expect a manager will be involved ensuring they are where they need to be.</p>
  </li>
  <li>
    <p>Skills
The last thing I look for is the actual skills. Depending on the timeline I would often prefer the better overall candidate who may have similar but not the exact skills. Learning new skills takes time, but intelligence, knowledge, and experience are more valuable.</p>
  </li>
</ol>

<p>The How
There are some specific questions I ask and subjects I mention to attempt to verify these items. A big thing I will always do is ask questions in a domain or specific discipline that the candidate does not have experience in. I tell them they can ask me questions and I will help them where I can. If they just give up on the spot, next! If they try to BS their way through it, next! I want to see them take their existing experience and try to investigate the problem</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Over my career I’ve participated in probably over a hundred interviews. No matter what the position these are the four things I really look for. A resume is a piece of paper, I can usually gauge in five minutes if the candidate has what is needed for the given role.]]></summary></entry><entry><title type="html">Living Data</title><link href="https://dovidkopel.com/2025/05/living-data" rel="alternate" type="text/html" title="Living Data" /><published>2025-05-01T23:19:05+00:00</published><updated>2025-05-01T23:19:05+00:00</updated><id>https://dovidkopel.com/2025/05/living-data</id><content type="html" xml:base="https://dovidkopel.com/2025/05/living-data"><![CDATA[<p>This is a novel approach to a database design that is sorely needed. 
Evolution in data storage has been significant but in many ways fairly the same general approach. 
Flat files was one of the first ways data was stored. A database was the next evolution.
Being able to take advantage of indexing data providing a means to quickly access data without having to seek through its entirety.
The purpose of this article is not to take a tour through the history of the database, but please bare with me I assure you its worth its while.
There was a time when the DBA was the all powerful ruler of the database and analysts as well as engineers had little control over the schema and the data at all.
One major issue when dealing with big data is handling data locality. 
There are two different types of databases that are often mutually exclusive: OLTP (Online Transaction Processing) and OLAP (Online Analytical Processing).</p>

<p>Let’s say you had a database of books and their respective contents. 
Now let’s imagine there is a store/library thing maybe somewhere in between Gartner and Safari Online. 
You have access to millions of resources but there are different packages what you have access to depending on your plan and what resources you have purchased.
To access an individual item is fairly simple, the application layer just needs to ensure that you have access to that single resource. 
However, if you wanted to perform a fulltext search throughout all of the resources you have access to this can be a very complex process.
No matter how you perform it there is waste with pagination and caching or time to reprocess the data-set. 
Theoretically you could write stored procedures for a SQL database and attempt with a single query to access the exact results for the exact page requested. 
Suffice to say such a store procedure would be awful to engineer, test, and maintain. 
It is without question that at times creating stored procedures may be the most efficient way to extract data.
Very few companies will do this anymore at all. They will move towards large caches and application layers.
With the gradual push to doing more and more computation in a serverless manner the latency and processing time grows exponentially.
The pros and cons of serverless architecture are outside of the scope of this article, however it is clear that if the serverless process is connecting directly to a database (something I generally advise against) the overhead involved in openning the sockets and connecting to the database puts additional burdens on the database and the network infrastructure.
Let’s instead adjust our approach and use a very unconventional approach to truly blur the lines where application and database exist.</p>

<p><a href="https://tada.github.io/pljava/">PL/Java</a> is a free open-source extension for PostgreSQL that allows stored procedures, triggers, and functions to be written in the Java language and executed in the backend.
I’m not suggesting that this is novel or going to solve big problems. 
This extension will allow engineers to create code that interacts directly with the database that is a great deal more comprehensive and accessible than what any SQL variant will offer. 
This may have a tad of a performance gain, but ultimately it would minimize the network traffic.</p>

<p>Without knowing the internals of databases as I have spent a nice amount of time understanding how several of the major databases are written and function end-to-end. 
The one thing you need to know is that the query inputted at some point in time is parsed and that helps the database determine what data needs to be accessed and ultimately what that query plan is. 
If you are somewhat familiar with the interpreted languages like Python everytime you run an application written in Python the code is converted into the low-level machine code appropriate for the current system. 
The runtime environment may be able to cache and optimize this overtime and improve performance. A database is similar in many ways as it is really an application (of course). 
Now imagine that in addition to understanding the query language, like SQL that the database also understood the actual Python of Java code. 
I don’t just mean that it executes the Python or Java code like in the PL/Java extension where the database has no idea what the extension is doing. 
Rather, in this case the database would be able to compile the application code down into something that the database can understand just as much as a query.</p>

<p><a href="https://archive.org/details/TheLordOfTheRing1TheFellowshipOfTheRing">Here</a> is a free online archive of the LOTR series text.
This is an example database schema for handling our sophisticated library system.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Book
* id: bigint
* author: bigint 
* pages: int
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Author
* id: bigint
* name: varchar(100)
* locationId: bigint
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Page
* id: bigint
* bookId: bigint
* chapterId: bigint
* page: int
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Chapter
* id: bigint
* bookId: bigint
* index: int
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Word
* id: bigint
* word: varchar
* root: bigint
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>WordRoot
* id: bigint
* text: varchat
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>WordPage
* id: bigint
* wordId: bigint
* pageId: bigint
* index: int
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>WordChapter
* id: bigint
* wordId: bigint // Word's Id
* chapterId: bigint // Chapter's Id
* index: bigint // Word's order from beginning of Chapter as origin
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Location
* id: bigint
* name: text
* latitude: double
* longitude: double
</code></pre></div></div>

<p>With the schema present one could find words or their root within a given proximity to each other.
I’m going to use the classical fantasy series The Lord of the Rings by J.R.R. Tolkien.
Maybe we want to find a conversation with Saruman and Gandalf.
Perhaps we hope to accomplish this by looking for the words “Saruman” and “Gandalf” with a maximum number of words distance. 
For this first example let’s say that the user may choose purchase each chapter of the book on its own, each book of the series on its own, or the entire series at one time.
The task of finding the words within the specified proximity isn’t too complex. Keep in mind that the end of sections like with series of asterisks, or a separate chapter should be disqualified from the distance search.
Meaning that if the word “Saruman” is found close to the end of chapter 1, and “Gandalf” is at the beginning of chapter 2, even the distance between the two words may be within the specified threshold the result must be excluded because the chapter break clearly separates the context.
Let’s look at the simple steps involved here:</p>

<ol>
  <li>Find all instances of word “Saruman” and “Gandalf” within X words.</li>
  <li>Take all results from #1 and ensure that there are no breaks between the two words.</li>
  <li>Obtain what access the user has granted.</li>
  <li>Filter out any results that the user does not have access to.</li>
  <li>Sort the results by relevance.</li>
  <li>Paginate the results.</li>
</ol>

<p>Now to write this as a single query will be incredibly complex and very likely subject to errors.
Not to add to the complexity, but very often services like this will still like you to know how many results may have been found from items that you may not yet own. 
This provides an incentive to sell you those items.
The type of queries needed here are complex and demanding.</p>

<p>If this task was limited only to the Lord of the Rings series and was a tool for the incredible geek that wants to search through Middle Earth with great preicision, this is not that bad.
Truthfully, if this was limited to a three books you might say drop the database and just store the text in memory. 
Let’s approach it from that perspective for the moment.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[This is a novel approach to a database design that is sorely needed. Evolution in data storage has been significant but in many ways fairly the same general approach. Flat files was one of the first ways data was stored. A database was the next evolution. Being able to take advantage of indexing data providing a means to quickly access data without having to seek through its entirety. The purpose of this article is not to take a tour through the history of the database, but please bare with me I assure you its worth its while. There was a time when the DBA was the all powerful ruler of the database and analysts as well as engineers had little control over the schema and the data at all. One major issue when dealing with big data is handling data locality. There are two different types of databases that are often mutually exclusive: OLTP (Online Transaction Processing) and OLAP (Online Analytical Processing).]]></summary></entry><entry><title type="html">Scheduling Service</title><link href="https://dovidkopel.com/2025/05/scheduling-service" rel="alternate" type="text/html" title="Scheduling Service" /><published>2025-05-01T23:19:05+00:00</published><updated>2025-05-01T23:19:05+00:00</updated><id>https://dovidkopel.com/2025/05/scheduling-service</id><content type="html" xml:base="https://dovidkopel.com/2025/05/scheduling-service"><![CDATA[<h1 id="creating-a-serverless-scheduling-service-in-golang">Creating a serverless scheduling service in Golang</h1>
<p>I’ve had a nice amount of exposure to the Golang language when I first started playing around with docker and its environment. At one time I actually had to go through the docker source code and the accompanying kernel source code for namespaces, cgroups and some other stuff. I had done some simple code execution and modifications but not a large scale system design.</p>

<p>I wanted to design a serverless system to emulate the <a href="https://calendly.com">calendaly</a> service functionality. I’m all for paying for services, but not something that I could whip up myself quickly. I am still in the middle of my post how I eliminated Wordpress and managed to avoid paying for <a href="https://siteleaf.com">siteleaf</a>. I usually use these use cases as oppurtunities to play around with something new and different, as opposed to just using some tool I could pay for…what fun is there in that?</p>

<p>I have a nice amount of meetings with people from consulting to networking and like the idea of having a simple url to easily allow a perspective meeting to be booked without exposing my calendar. Since this was more of an experiment with Golang and to see if I can pull this off as a serverless model with minimal fuss I had a fairly generic set of requirements. My initial requirements were:</p>

<ol>
  <li>Have a url where anonymous users may requests a meeting with me of several pre-defined durations (event types).</li>
  <li>The system should be able to at a minimum find available time slots for the requests events.</li>
  <li>Assuming the user found an appointment slot the system should be able to insert the event into my calendar as well as send the user a calendar invite.</li>
</ol>

<p>I had another challenge for myself and that was to see if I could do this without needing any additional storage mechanisms beyond the Google calendar.</p>

<p>I decided to extend this initial MVP and start with a schedule model first. The idea of this schedule model would be able to define general boundaries that guide your daily and weekly calendar. I came up with this approach:</p>

<ol>
  <li>Define a set of days that are either <code class="language-plaintext highlighter-rouge">enabled</code> or <code class="language-plaintext highlighter-rouge">disabled</code>. A <code class="language-plaintext highlighter-rouge">disabled</code> day is not even taken into consideration for any scheduling</li>
  <li>Define time spans for single, multiple, or all days of the week that should be considered as <code class="language-plaintext highlighter-rouge">busy</code>.</li>
</ol>

<p>I realized that the state of <code class="language-plaintext highlighter-rouge">Availability</code> can be one of three:</p>

<ol>
  <li><code class="language-plaintext highlighter-rouge">Busy</code> - A known event</li>
  <li><code class="language-plaintext highlighter-rouge">Available</code>- A known free slot</li>
  <li><code class="language-plaintext highlighter-rouge">Unknown</code>- There is no rule which indicates that the time is busy or free</li>
</ol>

<p>You may ask yourself…what’s with the unknown…if you don’t have anything on the calendar don’t you just assume you are free? The answer is that it depends on what type of calendar this is.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Creating a serverless scheduling service in Golang I’ve had a nice amount of exposure to the Golang language when I first started playing around with docker and its environment. At one time I actually had to go through the docker source code and the accompanying kernel source code for namespaces, cgroups and some other stuff. I had done some simple code execution and modifications but not a large scale system design.]]></summary></entry><entry><title type="html">Macro Services</title><link href="https://dovidkopel.com/2025/05/macro-services" rel="alternate" type="text/html" title="Macro Services" /><published>2025-05-01T23:19:05+00:00</published><updated>2025-05-01T23:19:05+00:00</updated><id>https://dovidkopel.com/2025/05/macro-services</id><content type="html" xml:base="https://dovidkopel.com/2025/05/macro-services"><![CDATA[<p>Let’s start with a simple tic tac toe game that I forked. https://codepen.io/dovidkopel-the-bold/pen/zLvWbz. 
<a href="https://github.com/vasanthk/tic-tac-toe-js">This</a> is the original repository.</p>

<p>This article is not about the actual language you use as much as it is about the architecture you use. 
This example is in fact a web-based game. Generally JavaScript is the language used for scripting in the browser. 
I’m not going to deal with that at all right now. 
In fact I’m going to create a very simple Java version of the same game that has a Java backend. 
The first version will be ascii based and</p>

<p>I recently read <a href="https://segment.com/blog/goodbye-microservices/">this</a> post and believe that many companies who jumped quickly on the microservices wagon may have many similar challenges.</p>

<p>As always I am going to be very direct and to the point. 
The businesses I have in mind in this article are growth oriented. 
If you are a small business unit that only has small goals please recognize that best practices need to be adjusted for each organization.</p>

<p>This is going to center around the general architecture for a complex system for an enterprise organization. 
I have recently noticed an increase in clothing labels using the phrase “one size fits most”, I just wonder if someone sued and they stopped saying “all”. 
I use this quip regarding #software #architecture.<br />
There is simply no “one size fits all”.</p>

<p>A great deal has been covered on the topic of microservices, containerization, and serverless by many very smart people. 
I’m hoping to provide some direction and specific techniques.</p>

<p>I’m a big fan of the Spring Framework and their design patterns. 
Even if I’m not using the Java language I try to best follow many of their approaches. 
To begin with some very simple items that cannot be overstated
Less is more, keeping things simple, isolated, and not repeating yourself are all really one.</p>
<ul>
  <li>Eliminate code duplication.</li>
  <li>Keep code bodies simple and to a very exact purpose.</li>
  <li>Use interfaces.</li>
  <li>Use inheritance.</li>
  <li>Code should be self-documented with variable names, class names, and function names. Anything more complex should have explicit documentation.</li>
  <li>Functions or methods should not exceed a few lines (5 ideally).</li>
</ul>

<p>Now without talking about SOA…whatever that is. Let’s focus on simply interfaces. 
If we create our code with strongly typed interfaces anything and everything we talk about after this point should be simple. I’m going to restate that. If we properly design our code with strongly typed interfaces and focus each interface on a very select set of capabilities. You will always be in a pretty good position.</p>

<p>What I’m trying to tell you is that before you even look at the monolithic or microservices discussion, you <strong>must</strong> be at this point. I haven’t mentioned infrastructure, DevOps, testing, or anything else. Those are important, but ultimately your code having proper modular (keyword) architecture is paramount.</p>

<p>Utilizing modules, packages, or namespaces you can modularize your code. Again, nothing new here at all. 
I’m a big fan of object oriented programming, despite its recent bad reputation. 
Let’s say I have an enterprise system that connects event-driven applications.
I want to allow the user to be able to upload a new <code class="language-plaintext highlighter-rouge">jar</code> file to s3. 
From that <code class="language-plaintext highlighter-rouge">jar</code> the system may dynamically load and unload modules and subscribe/unsubscribe to specific events. <br />
With java I can dynamically pull the <code class="language-plaintext highlighter-rouge">jar</code> object.</p>

<p>Then I would read through the <code class="language-plaintext highlighter-rouge">jar</code> and look for any classes the implement the established interfaces.
Let’s say that we have an interface called <code class="language-plaintext highlighter-rouge">MessageConsumer</code>:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">MessageConsumer</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="kd">extends</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">function</span><span class="o">.</span><span class="na">Consumer</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="o">{</span>
	<span class="c1">// Returns an array of strings </span>
	<span class="c1">// that are used to subscribe this</span>
	<span class="c1">// consumer to the topic.</span>
	<span class="nc">String</span><span class="o">[]</span> <span class="nf">getSubscriptionTopics</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Let’s say that we have a <code class="language-plaintext highlighter-rouge">jar</code> with a few implementations of that interface in it. 
The system would automatically load those classes and subscribe them to their respective topics. 
Now this <code class="language-plaintext highlighter-rouge">jar</code> was added dynamically at runtime by using a <code class="language-plaintext highlighter-rouge">ClassLoader</code>.</p>

<p>With the same sort of <code class="language-plaintext highlighter-rouge">jar</code> isolation you can simply have various <code class="language-plaintext highlighter-rouge">jar</code>s loaded like <code class="language-plaintext highlighter-rouge">dependency</code> in a maven project.</p>

<h1 id="resources">Resources</h1>
<h2 id="martin-fowler-my-architectural-mentor">Martin Fowler (My architectural mentor)</h2>
<ul>
  <li>https://www.martinfowler.com/microservices/</li>
  <li>https://www.martinfowler.com/articles/microservices.html</li>
  <li>https://martinfowler.com/articles/break-monolith-into-microservices.html</li>
  <li>https://www.martinfowler.com/articles/microservice-trade-offs.html</li>
  <li>
    <p>https://www.martinfowler.com/bliki/MicroservicePremium.html</p>
  </li>
  <li>https://adamdrake.com/enough-with-the-microservices.html</li>
</ul>

<h2 id="others">Others</h2>
<ul>
  <li>http://blog.shippable.com/our-journey-to-microservices-and-a-mono-repository</li>
  <li>https://medium.com/@maoberlehner/monorepos-in-the-wild-33c6eb246cb9</li>
  <li>https://medium.com/@pavanbelagatti/microservices-mono-repo-vs-multiple-repositories-6e139b5ca44a</li>
  <li>https://medium.com/@somakdas/code-repository-for-micro-services-mono-repository-or-multiple-repositories-d9ad6a8f6e0e</li>
  <li>https://dzone.com/articles/concerns-around-managing-many-microservice-reposit</li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[Let’s start with a simple tic tac toe game that I forked. https://codepen.io/dovidkopel-the-bold/pen/zLvWbz. This is the original repository.]]></summary></entry><entry><title type="html">Intro To Writing Code</title><link href="https://dovidkopel.com/2025/05/intro-to-writing-code" rel="alternate" type="text/html" title="Intro To Writing Code" /><published>2025-05-01T23:19:05+00:00</published><updated>2025-05-01T23:19:05+00:00</updated><id>https://dovidkopel.com/2025/05/intro-to-writing-code</id><content type="html" xml:base="https://dovidkopel.com/2025/05/intro-to-writing-code"><![CDATA[]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Chess</title><link href="https://dovidkopel.com/2025/05/chess" rel="alternate" type="text/html" title="Chess" /><published>2025-05-01T23:19:05+00:00</published><updated>2025-05-01T23:19:05+00:00</updated><id>https://dovidkopel.com/2025/05/chess</id><content type="html" xml:base="https://dovidkopel.com/2025/05/chess"><![CDATA[<p>The challenge to designing any architecture is to strike the balance between long term and short term goals.
I’m not interested in discussing agile and the project management related matters.
The general rule of thumb is to keep things simple and don’t do more than you need to.
Generally, I’m not involved in a project unless it needs my unique viewpoint and very careful eye.
I always say that the closer to real life your system is, the better.
The more structurally accurate the modularity and isolation the fewer concerns you will have.
A very decoupled architecture will have a great deal more moving pieces. 
For those who are unfamiliar with that type of system, it can be overwhelming and quite simply wrong.
The interfaces for those isolated perspectives are important, not attempting to implement every possible contingency and scenario.</p>

<p>The need to refactor isn’t a sign of weakness or lack of foresight. 
However, iderally refactoring should really only be needed when an actual business case <em>changes</em>. 
Let’s look at the classical board game of chess for a moment. 
I’m not the best player around but I have a strong appreciation for the game. 
I have used this as an interviewing technique. I’d ask the candidate to begin to design a chess game. 
How would they start? What would the general system look like? 
Now I would never expect the candidate to anticipate what if we want to change the chess board to three dimensions. 
What if we added additional players? What if we created new pieces? 
Some of these items may be so intrinsic to chess that the thought of considering one way or another was simply not considered. 
Functional programming is very populuar now. Much like agile, functional can be a crutch for poor architecture. 
That should not be the case. Even a functional approach should have strong isolation of concerns. 
The terminology of your approach is not as important as the approach itself. 
Whether its a callback, observer, factory, facade, etc.. it’s not the name but what the approach provides you. 
You don’t need an object oriented language to write good clean code, but it helps. 
A statically typed language for enterprise application isn’t an option, it isn’t a debate, it is simply the law. 
Luckily the compilers today have evolved and are quite advanced. 
They are able to follow inferences and eliminate a great deal of extraneous boilerplate code.</p>

<p>So what is the trick to always start off with the best architecture and limit the number of times you need to refactor? 
It is quite simple. Design reality.</p>

<p>Let’s start with chess. If you look at some chess boards they have letters and numbers. 
These are used to accurately depict a position without having to use your fingers to point. 
In general with computers and engineering if you need to point or make a gesture for a reference, the resolution of detail is lacking. 
Hopefully you are familiar with the cartesian coordinate system that you learned in grade school. 
Even if you aren’t familiar with it, even without a formal definition of the system you are most likely acquinted with it already. 
Simply enough, you have a range of numeric values each associated with a given axis. 
There is a great deal more to it, and if you take the time you will appreciate a lot of what probably put you to sleep at one time. 
Sadly, most of the math that I learned in school was memorization and whatever was needed to pass state exams. 
I’m not really a math guy, so be warned I’m out of my element, and welcome any <em>useful</em> comments.</p>

<p>The standard chess board has axises. Each with eight positions. Totalling sixty-four total positions. 
A unique position is defined at the intersection of a point within each axis. 
There are several pieces, each with their own rules. 
I always start off by trying to establish the <em>objective</em> of the system. 
Chess is a game, an amusement…but let’s talk about the objective of playing the game and not to have fun. 
The objective of chess is to prevail either by your opponents resignation or putting them into checkmate. 
Chess is a turn based game. That means that each player must move a piece each sucessive turn. 
In some turn-based games a player can “pass”, that is not an option in chess. 
Without even getting into specifics the important thing to establish is that the game of chess can be represented as a state machine. 
Chess has absolutely no random component associated with it such as a rolling a dice. 
Why is a state machine significant? 
A state machine means that you can represent the exact moment in time of the game in a way such that you can replay the game from its inception and recover the exact state. 
For our purposes the information you would need to retain to replay the game to its current state will help you establish the essential data. 
Now you can assess what each state and its transition looks like. 
If you are smart enough you will realize that once you have a given state of chess at that point you can technically calculate all the possible variations that will yield checkmate. 
This is not realistic as far as computation as this would be in polynomial time. 
When you look at an application or a system from a state machine perspective it is a very simple way to capture its essence.</p>

<p>The important detail is where the major logic should be defined. 
Each piece should have the ability in a given board return a list of all valid moves. 
Most of the information may be interpreted from the current state of the board and its pieces. 
Certain things like if you moved the king or not would not be evident since the king may be moved away and then returned to its inital location. 
We need to assume that a board may have rules and state. Like was the king moved or not, or is there a piece here or not. 
The game and its players have some rules and state. The color pieces of each player. 
Most importantly is the rules of each individual piece type.</p>

<p>For some of the attributes you may find yourself creating lots of <code class="language-plaintext highlighter-rouge">boolean</code> attributes to represent what appears to be property. 
Don’t do the equivalency of creating a ton of columns in a single table. That is the opportunity to create proper and fitting classifications.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[The challenge to designing any architecture is to strike the balance between long term and short term goals. I’m not interested in discussing agile and the project management related matters. The general rule of thumb is to keep things simple and don’t do more than you need to. Generally, I’m not involved in a project unless it needs my unique viewpoint and very careful eye. I always say that the closer to real life your system is, the better. The more structurally accurate the modularity and isolation the fewer concerns you will have. A very decoupled architecture will have a great deal more moving pieces. For those who are unfamiliar with that type of system, it can be overwhelming and quite simply wrong. The interfaces for those isolated perspectives are important, not attempting to implement every possible contingency and scenario.]]></summary></entry><entry><title type="html">Flyway Database Migration</title><link href="https://dovidkopel.com/2025/05/flyway-database-migration" rel="alternate" type="text/html" title="Flyway Database Migration" /><published>2025-05-01T23:19:05+00:00</published><updated>2025-05-01T23:19:05+00:00</updated><id>https://dovidkopel.com/2025/05/flyway-database-migration</id><content type="html" xml:base="https://dovidkopel.com/2025/05/flyway-database-migration"><![CDATA[<h1 id="flyway-a-real-solution-to-database-migrations">Flyway: A real solution to database migrations</h1>

<p>When I started working at a company they had a production database. They had no database schema defined.
They didn’t even have a normal development environment. They would attempt to clean production data and populate the development database.
One of the biggest issues was they would make database schema changes in development and then have no idea what they were missing in production.
They were so far away from a modern day CI/CD engineering process. I looked around for different ways to solve this issue.</p>

<p>At one point in time I was contemplating building a solution from the ground up. 
The first approach I had been taking was to simply have a git repository that held the database DDL files.
The challenge was dealing with possibly dirty systems that had been manually changed.
Identifying the current state of the DB in question and if/how to update it to the newest version.</p>

<p>Typically I would have a production environment, a development environment, and a build/test environment.
Depending on the size of the engineering team I would like each engineer to have their own development environment.
The build/test environment is used when a build is occurring. 
I need to be able to update an existing environment, as well as create a new DB on the fly.
Sometimes I will need to not only create or alter the database structure.
At times fairly complex migrations are needed to adapt older data to the new structure.
This can be a fickle and tricky process that cannot allow for error.
Flyway has its community (free as in speech &amp; beer) edition, as well as its professional edition which has a modest price tag attached to it.
Two of the most appealing paid features are “undo” and “dry-run”.
The undo feature does exactly what it sounds like. It can undo one or more steps of a migration.
Generally if a migration will fail during a transaction the flyway can simply rollback the transaction.
However, I’ve had many circumstances where the migration was successful but something else was not functioning as expected.
Now I need to revert the code as well as the database.</p>

<p>I am most likely using ECS Fargate, or Elastic Container Service on AWS.
With a CloudFormation template describing the environment and infrastructure.
Whenever I would have an update of my Spring Boot application I would use the Git hash from the commit and tag my Docker container with it.
This provides an easy way to directly link a commit with its built image. 
I would push the Docker images to ECR (Elastic Container Registry) which houses the Docker images.
The CloudFormation stack would be updated with the new image hash.
ECS is designed to ensure that the new version of the service is stable and healthy prior to standing down the previous version and directing traffic to the new instance.
One big issue that I have yet to effectively deal with, and have a number of very simple ways to handle.
In my SDLC there are no releases, when code has been fully tested it goes out to production.
That often means that it may be rolled out during business hours. 
In many instances the product I would be dealing with is not limited to business hours, rather an all time expectation.
You of course can have maintenance periods but that is less than ideal.
What do you do with an updated database which corresponds to an updated POJO that maps the database schema to a object.
With statically typed languages and preferred enterprise approach you are using type-safe domain objects.
Now during this grace period of a few minutes you should have the old version functional that will gracefully switch over to the new version.
What may end up happening is that the old or former version becomes invalid due to the database migration.
Now you essentially need to</p>

<p>This has become especially important</p>

<p>I believe a reference to both Flyway and Liquibase
I found <a href="https://flywaydb.org">Flyway</a> and was extremely impressed. 
The other major contender was <a href="https://www.liquibase.org/">Liquibase</a>.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Flyway: A real solution to database migrations]]></summary></entry><entry><title type="html">Dynamic Programming Modules</title><link href="https://dovidkopel.com/2025/05/dynamic-programming-modules" rel="alternate" type="text/html" title="Dynamic Programming Modules" /><published>2025-05-01T23:19:05+00:00</published><updated>2025-05-01T23:19:05+00:00</updated><id>https://dovidkopel.com/2025/05/dynamic-programming-modules</id><content type="html" xml:base="https://dovidkopel.com/2025/05/dynamic-programming-modules"><![CDATA[<p>I’m a big fan of object-oriented programming and also like <a href="https://dovidkopel.com/2016/09/functional-programming-in-the-enterprise-world">functional programming</a>. 
Take a look at <a href="https://dzone.com/articles/nodejs-for-enterprise-applications-are-you-kidding">this</a> article on NodeJS in the enterprise. 
I am strong advocate of polyglot systems and that you want to design a system for the various roles and you need to consider technologies often associated with those roles.</p>

<p>A truly modular system will enable you to “shove together” modules and the system will appropriately handle them. 
This was left quite ambiguous because depending on the type of components it is possible that in any given system you only may have a single instance. 
Like for instance a logger. If you have some experience with Java logging libraries you may find seen issues when more than one implementation is found on the classpath. 
Similarly, you may have issues with regular packages that don’t interact well together because they have conflicting dependency versions. 
Having the ability to have the system determine at runtime based on a whole bunch of priority parameters that impact the functionality. 
If you are familiar with Spring Boot you should be extremely familiar with this sort of flexibility. 
When you get used to that customization you get this feeling that you can do anything with your code. 
This functional capacity is an extension of traditional polymorphism. 
Having the ability to assume multiple traits of an interface is fairly limited when you pin down the code that is available. 
Creating your modules to be truly self contained is the basis of good enterprise architecture and the key to most problems you run into. 
The recent version of <a href="https://dzone.com/articles/java-9-modules-introduction-part-1">Java 9</a> takes this approach and improves some of the challenges. 
Providing clear definitions as to what the module requires and what it contains is what the new modularity functionality provides. 
It’s very nice, but you can accomplish a lot without that.</p>

<p>A <code class="language-plaintext highlighter-rouge">jar</code> is just a compressed archive with whatever content you put into it.<br />
Traditionally utilizing a manifest was the way you had to specify if you want to directly invoke a <code class="language-plaintext highlighter-rouge">jar</code> what class should be invoked. 
That is still of course the case. However, you can have a <code class="language-plaintext highlighter-rouge">jar</code> that only holds classes without any main class.</p>

<p>There is a great <a href="https://github.com/lukehutch/fast-classpath-scanner">library</a> that can facilitates scanning the classpath in addition to many other things like a <code class="language-plaintext highlighter-rouge">jar</code> sitting on a local or remote file-system. 
This library is extremely fast because it reads the java class files interpreting the bytecode without actually loading the files.</p>

<p>Let’s say I have an enterprise system that connects event-driven applications.
I want to allow the user to be able to upload a new <code class="language-plaintext highlighter-rouge">jar</code> file to s3. 
From that <code class="language-plaintext highlighter-rouge">jar</code> the system may dynamically load and unload modules and subscribe/unsubscribe to specific events. <br />
With java I can dynamically pull the <code class="language-plaintext highlighter-rouge">jar</code> object.</p>

<p>While not everyone loves the ins and outs of the JVM classpath, the ability to dynamically load modules or executable code is an extremely valuable capability.</p>

<p>I’ve created a tic-tac-toe application that is available <a href="https://github.com/dovidkopel/tic-tac-toe">here</a>. 
I specifically wrote this code to be as functional and procedural as possible. 
I wanted to make the design very “simple” and only focused on the simplest tic-tac-toe game. 
You can say there isn’t anything wrong with this code, it is well documented.</p>

<p>This is the board of a 3×3. This is how the indicies are numbered.
They are zero index based.</p>

<h3 id="33">3×3</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0 1 2
3 4 5
6 7 8
</code></pre></div></div>

<h3 id="44">4×4</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0  1  2  3
4  5  6  7
8  9  10 11
12 13 14 15 
</code></pre></div></div>

<h3 id="55">5×5</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0  1  2  3  4
5  6  7  8  9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
</code></pre></div></div>

<p>The only configurable option is the size of the board. It defaults to a 3×3 board, but you can create the board with a different size. 
The approach used for calculating if their is a win or a draw is not the most efficient method. 
I decided to favor cleaner more readable code over efficiency that would be negligible.
In fact, unless the board were to be several thousands larger than a traditional board the difference would be minuscule. Let’s look at the <code class="language-plaintext highlighter-rouge">getWinner()</code> function:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kt">char</span> <span class="nf">getWinner</span><span class="o">()</span> <span class="o">{</span>
    <span class="c1">// Iterate through each winning algorithm</span>
    <span class="c1">// For most of them then iterate for each row</span>
    <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">x</span><span class="o">=</span><span class="mi">0</span><span class="o">;</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="n">size</span><span class="o">;</span> <span class="n">x</span><span class="o">++)</span> <span class="o">{</span>
        <span class="kt">char</span><span class="o">[]</span> <span class="n">chars</span> <span class="o">=</span> <span class="n">getCells</span><span class="o">(</span><span class="nc">WinningPath</span><span class="o">.</span><span class="na">HORIZONTAL</span><span class="o">,</span> <span class="n">x</span><span class="o">);</span>
        <span class="kt">char</span> <span class="n">c</span> <span class="o">=</span> <span class="n">getCharIfAllSame</span><span class="o">(</span><span class="n">chars</span><span class="o">);</span>

        <span class="k">if</span><span class="o">(</span><span class="n">c</span> <span class="o">!=</span> <span class="n">empty</span><span class="o">)</span> <span class="o">{</span>
            <span class="k">return</span> <span class="n">c</span><span class="o">;</span>
        <span class="o">}</span>

        <span class="n">chars</span> <span class="o">=</span> <span class="n">getCells</span><span class="o">(</span><span class="nc">WinningPath</span><span class="o">.</span><span class="na">VERTICAL</span><span class="o">,</span> <span class="n">x</span><span class="o">);</span>
        <span class="n">c</span> <span class="o">=</span> <span class="n">getCharIfAllSame</span><span class="o">(</span><span class="n">chars</span><span class="o">);</span>

        <span class="k">if</span><span class="o">(</span><span class="n">c</span> <span class="o">!=</span> <span class="n">empty</span><span class="o">)</span> <span class="o">{</span>
            <span class="k">return</span> <span class="n">c</span><span class="o">;</span>
        <span class="o">}</span>
    <span class="o">}</span>

    <span class="kt">char</span><span class="o">[]</span> <span class="n">chars</span> <span class="o">=</span> <span class="n">getDiagonal1</span><span class="o">();</span>
    <span class="kt">char</span> <span class="n">c</span> <span class="o">=</span> <span class="n">getCharIfAllSame</span><span class="o">(</span><span class="n">chars</span><span class="o">);</span>
    <span class="k">if</span><span class="o">(</span><span class="n">c</span> <span class="o">!=</span> <span class="n">empty</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">c</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="n">chars</span> <span class="o">=</span> <span class="n">getDiagonal2</span><span class="o">();</span>
    <span class="n">c</span> <span class="o">=</span> <span class="n">getCharIfAllSame</span><span class="o">(</span><span class="n">chars</span><span class="o">);</span>
    <span class="k">if</span><span class="o">(</span><span class="n">c</span> <span class="o">!=</span> <span class="n">empty</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">c</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="k">return</span> <span class="n">empty</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<p>For both horizontal and vertical we iterate through each algorithm one time per dimension. 
The other two calls are for the two diagonals. 
The <code class="language-plaintext highlighter-rouge">getCells(WinningPath path, Integer offset)</code> call returns back an array of <code class="language-plaintext highlighter-rouge">char</code>s according to the specified algorithm. 
Following that call the <code class="language-plaintext highlighter-rouge">getCharIfAllSame(char[] chars)</code> function is invoked to evaluate whether or not the returns chars are all the same or not. 
These two steps make the code longer but much more flexible and easier to understand. 
Here is the <code class="language-plaintext highlighter-rouge">getCells()</code> call. It’s a very simple dispatcher pattern.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kt">char</span><span class="o">[]</span> <span class="nf">getCells</span><span class="o">(</span><span class="nc">WinningPath</span> <span class="n">wp</span><span class="o">,</span> <span class="kt">int</span><span class="o">...</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="kt">char</span><span class="o">[]</span> <span class="n">t</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">char</span><span class="o">[</span><span class="n">size</span><span class="o">];</span>
    <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">x</span><span class="o">=</span><span class="mi">0</span><span class="o">;</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="n">size</span><span class="o">;</span> <span class="n">x</span><span class="o">++)</span> <span class="o">{</span>
        <span class="kt">int</span> <span class="n">c</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span>
        <span class="k">switch</span><span class="o">(</span><span class="n">wp</span><span class="o">)</span> <span class="o">{</span>
            <span class="k">case</span> <span class="nl">HORIZONTAL:</span>
                <span class="n">c</span> <span class="o">=</span> <span class="n">getRow</span><span class="o">(</span><span class="n">args</span><span class="o">[</span><span class="mi">0</span><span class="o">],</span> <span class="n">x</span><span class="o">);</span>
                <span class="k">break</span><span class="o">;</span>
            <span class="k">case</span> <span class="nl">VERTICAL:</span>
                <span class="n">c</span> <span class="o">=</span> <span class="n">getColumn</span><span class="o">(</span><span class="n">args</span><span class="o">[</span><span class="mi">0</span><span class="o">],</span> <span class="n">x</span><span class="o">);</span>
                <span class="k">break</span><span class="o">;</span>
            <span class="k">case</span> <span class="nl">DIAGONAL:</span>
                <span class="n">c</span> <span class="o">=</span> <span class="n">getDiagonal</span><span class="o">(</span><span class="n">args</span><span class="o">[</span><span class="mi">0</span><span class="o">],</span> <span class="n">x</span><span class="o">);</span>
                <span class="k">break</span><span class="o">;</span>
        <span class="o">}</span>
        <span class="n">t</span><span class="o">[</span><span class="n">x</span><span class="o">]</span> <span class="o">=</span> <span class="n">board</span><span class="o">[</span><span class="n">c</span><span class="o">];</span>
    <span class="o">}</span>
    <span class="k">return</span> <span class="n">t</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<p>The actual individual algorithm is broken down based on the strategy.</p>

<p>The <code class="language-plaintext highlighter-rouge">getRow()</code> function looks like this:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Row 0 -&gt; 0 1 2</span>
<span class="c1">// Row 1 -&gt; 3 4 5</span>
<span class="c1">// Row 2 -&gt; 6 7 8</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="nf">getRow</span><span class="o">(</span><span class="kt">int</span> <span class="n">row</span><span class="o">,</span> <span class="kt">int</span> <span class="n">offset</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">return</span> <span class="n">offset</span> <span class="o">+</span> <span class="o">(</span><span class="n">row</span> <span class="o">*</span> <span class="n">size</span><span class="o">);</span>
<span class="o">}</span>

<span class="c1">// Column 0 -&gt; 0 3 6</span>
<span class="c1">// Column 1 -&gt; 1 4 7</span>
<span class="c1">// Column 2 -&gt; 2 5 8</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="nf">getColumn</span><span class="o">(</span><span class="kt">int</span> <span class="n">column</span><span class="o">,</span> <span class="kt">int</span> <span class="n">offset</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">return</span> <span class="n">column</span> <span class="o">+</span> <span class="o">(</span><span class="n">size</span> <span class="o">*</span> <span class="n">offset</span><span class="o">);</span>
<span class="o">}</span>

<span class="kd">public</span> <span class="kt">int</span> <span class="nf">getDiagonal</span><span class="o">(</span><span class="kt">int</span> <span class="n">diag</span><span class="o">,</span> <span class="kt">int</span> <span class="n">offset</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">if</span><span class="o">(</span><span class="n">diag</span> <span class="o">==</span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">if</span><span class="o">(</span><span class="n">offset</span> <span class="o">==</span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
            <span class="k">return</span> <span class="mi">0</span><span class="o">;</span>
        <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
            <span class="k">return</span> <span class="o">(</span><span class="n">size</span><span class="o">+</span><span class="mi">1</span><span class="o">)</span> <span class="o">*</span> <span class="n">offset</span><span class="o">;</span>
        <span class="o">}</span>
    <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
        <span class="k">if</span><span class="o">(</span><span class="n">offset</span> <span class="o">==</span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
            <span class="k">return</span> <span class="n">size</span> <span class="o">-</span> <span class="mi">1</span><span class="o">;</span>
        <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
            <span class="k">return</span> <span class="o">(</span><span class="n">size</span> <span class="o">-</span> <span class="mi">1</span><span class="o">)</span> <span class="o">*</span> <span class="o">(</span><span class="n">offset</span> <span class="o">+</span> <span class="mi">1</span><span class="o">);</span>
        <span class="o">}</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>This quite simply is a function that will return the index of the row cells for the inputted row and offset. 
This function will handle different sized boards, not just the standard 3×3.</p>

<p>I haven’t made the time to continue the more advanced version of this. I began working on a very generalized architecture. 
Even-though the implementation is not complete, I am very happy with the architecture thus far and know when the time is there to complete it, it will be very modular and powerful.</p>

<p>Let’s start looking at the major packages and their interfaces and classes of the <a href="https://github.com/dovidkopel/tic-tac-toe/tree/master/oop/src/main/java/com/dovidkopel/tictactoe/oop"><code class="language-plaintext highlighter-rouge">oop</code></a> package:</p>
<ul>
  <li>oop
    <ul>
      <li>class <strong>Main</strong></li>
      <li>class <strong>TicTacToe</strong> extends SequentialTurnBasedBoardGameImpl<TicTacToeBoard></TicTacToeBoard></li>
    </ul>
  </li>
  <li>oop/board - Relating to the physical board
    <ul>
      <li>interface <strong>Board</strong></li>
      <li>interface <strong>TicTacToeBoard</strong> extends Board</li>
      <li>class <strong>TwoDimensionalTicTacToeBoard</strong> implements TicTacToeBoard</li>
    </ul>
  </li>
  <li>oop/game - Relating to the game state
    <ul>
      <li>status
        <ul>
          <li>enum <strong>GameStatus</strong></li>
          <li>interface <strong>GameEvent</strong> extends GameStatusDetails</li>
        </ul>
      </li>
      <li>turn</li>
      <li>interface <strong>Game</strong> extends Serializable, TurnHistory, GameOutcome</li>
      <li>interface <strong>SequentialTurnBasedBoardGame</strong> extends BoardGame - Adds the notion of a single player for the <code class="language-plaintext highlighter-rouge">Turn</code>.</li>
    </ul>
  </li>
  <li>oop/player
    <ul>
      <li>interface <strong>Player</strong> extends Serializable</li>
      <li>interface <strong>PlaySelector</strong> - Essentially a <code class="language-plaintext highlighter-rouge">Iterator&lt;Player&gt;</code>. Determines the initial <code class="language-plaintext highlighter-rouge">Player</code> and subsequent <code class="language-plaintext highlighter-rouge">Player</code>. Allows for games where the players would rotate who goes first.</li>
    </ul>
  </li>
  <li>oop/position</li>
  <li>oop/strategy - Relates to different ways to evaluate a winner or loser or other game state
    <ul>
      <li>interface <strong>WinningStrategy</strong> extends Comparable<WinningStrategy></WinningStrategy></li>
      <li>class <strong>DiagonalStrategy</strong> implements WinningStrategy</li>
      <li>class <strong>DrawStrategy</strong> implements WinningStrategy</li>
      <li>class <strong>HorizontalStrategy</strong> implements WinningStrategy</li>
      <li>class <strong>VerticalStrategy</strong> implements WinningStrategy</li>
      <li>interface <strong>StrategyScanner</strong> - Used to find and handle the strategies</li>
    </ul>
  </li>
</ul>

<p>The first thing that was clear to me was that I wanted to define a <a href="https://github.com/dovidkopel/tic-tac-toe/blob/master/oop/src/main/java/com/dovidkopel/tictactoe/oop/game/Game.java"><code class="language-plaintext highlighter-rouge">Game</code></a>.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Game</span> <span class="kd">extends</span>
	<span class="nc">Serializable</span><span class="o">,</span>
	<span class="nc">TurnHistory</span><span class="o">,</span>
	<span class="nc">GameOutcome</span> <span class="o">{</span>

	<span class="no">UUID</span> <span class="nf">getId</span><span class="o">();</span>

	<span class="nc">LocalDateTime</span> <span class="nf">getCreated</span><span class="o">();</span>

	<span class="nc">LocalDateTime</span> <span class="nf">getUpdated</span><span class="o">();</span>

	<span class="nc">Turn</span> <span class="nf">start</span><span class="o">();</span>

	<span class="kt">void</span> <span class="nf">stop</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>

<p>I thought about games and wanted to separate the game play from the rules and the state of the game.
Most games are turn-based. Meaning that one player goes and then another, etc. What defined the order of the turns or who goes first is something entirely different.
The <a href="https://github.com/dovidkopel/tic-tac-toe/blob/master/oop/src/main/java/com/dovidkopel/tictactoe/oop/game/turn/TurnHistory.java"><code class="language-plaintext highlighter-rouge">TurnHistory</code></a> interface is quite simple:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">TurnHistory</span> <span class="o">{</span>
	<span class="nc">List</span><span class="o">&lt;</span><span class="nc">Turn</span><span class="o">&gt;</span> <span class="nf">getTurns</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>

<p>It is a container to hold all references to a <code class="language-plaintext highlighter-rouge">Game</code>’s <a href="https://github.com/dovidkopel/tic-tac-toe/blob/master/oop/src/main/java/com/dovidkopel/tictactoe/oop/game/turn/Turn.java"><code class="language-plaintext highlighter-rouge">Turn</code></a>.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Turn</span><span class="o">&lt;</span><span class="no">T</span> <span class="kd">extends</span> <span class="nc">Action</span><span class="o">&gt;</span> <span class="kd">extends</span> <span class="nc">Serializable</span><span class="o">,</span> <span class="nc">Comparable</span><span class="o">&lt;</span><span class="nc">Turn</span><span class="o">&gt;</span> <span class="o">{</span>
	<span class="no">UUID</span> <span class="nf">getId</span><span class="o">();</span>

	<span class="nc">LocalDateTime</span> <span class="nf">getCreated</span><span class="o">();</span>

	<span class="nc">LocalDateTime</span> <span class="nf">getUpdated</span><span class="o">();</span>

	<span class="nc">Optional</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="nf">getAction</span><span class="o">();</span>

	<span class="nc">Player</span> <span class="nf">getPlayer</span><span class="o">();</span>

	<span class="k">default</span> <span class="kt">boolean</span> <span class="nf">turnCompleted</span><span class="o">()</span> <span class="o">{</span>
		<span class="k">return</span> <span class="nf">getAction</span><span class="o">().</span><span class="na">isPresent</span><span class="o">();</span>
	<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>A <code class="language-plaintext highlighter-rouge">Turn</code> is created and updated when the <code class="language-plaintext highlighter-rouge">Turn</code> is acted or updated. A <code class="language-plaintext highlighter-rouge">Turn</code> has a reference to its defined <a href="https://github.com/dovidkopel/tic-tac-toe/blob/master/oop/src/main/java/com/dovidkopel/tictactoe/oop/player/Player.java"><code class="language-plaintext highlighter-rouge">Player</code></a> and the <a href="https://github.com/dovidkopel/tic-tac-toe/blob/master/oop/src/main/java/com/dovidkopel/tictactoe/oop/game/turn/Action.java"><code class="language-plaintext highlighter-rouge">Action</code></a> if it has been invoked or not.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Action</span><span class="o">&lt;</span><span class="no">T</span> <span class="kd">extends</span> <span class="nc">Action</span><span class="o">&gt;</span> <span class="kd">extends</span> <span class="nc">Serializable</span><span class="o">,</span> <span class="nc">Comparable</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="o">{</span>
	<span class="no">UUID</span> <span class="nf">getId</span><span class="o">();</span>

	<span class="nc">LocalDateTime</span> <span class="nf">getCreated</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>
<p>An <code class="language-plaintext highlighter-rouge">Action</code> is simply a defined entity that is created and uniquely defined. 
With Tic-Tac-Toe or many <code class="language-plaintext highlighter-rouge">BoardGame</code> in mind I created a <code class="language-plaintext highlighter-rouge">Move</code> which is a type of <code class="language-plaintext highlighter-rouge">Action</code>.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Move</span><span class="o">&lt;</span><span class="no">T</span> <span class="kd">extends</span> <span class="nc">Move</span><span class="o">&gt;</span> <span class="kd">extends</span> <span class="nc">Action</span><span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="o">{</span>
	<span class="no">UUID</span> <span class="nf">getId</span><span class="o">();</span>

	<span class="nc">Position</span> <span class="nf">getPosition</span><span class="o">();</span>

	<span class="nc">Player</span> <span class="nf">getPlayer</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>

<p>The <a href="https://github.com/dovidkopel/tic-tac-toe/blob/master/oop/src/main/java/com/dovidkopel/tictactoe/oop/game/turn/Move.java"><code class="language-plaintext highlighter-rouge">Move</code></a> interface adds the <a href="https://github.com/dovidkopel/tic-tac-toe/blob/master/oop/src/main/java/com/dovidkopel/tictactoe/oop/position/Position.java"><code class="language-plaintext highlighter-rouge">Position</code></a> that the <code class="language-plaintext highlighter-rouge">Player</code> moved. 
A general <code class="language-plaintext highlighter-rouge">Position</code> interface is:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Position</span> <span class="kd">extends</span> <span class="nc">Serializable</span> <span class="o">{</span>
	<span class="kt">boolean</span> <span class="nf">isEmpty</span><span class="o">();</span>

	<span class="kt">boolean</span> <span class="nf">isOccupied</span><span class="o">();</span>

	<span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="no">T</span> <span class="nf">getOccupant</span><span class="o">();</span>

	<span class="o">&lt;</span><span class="no">T</span><span class="o">&gt;</span> <span class="kt">void</span> <span class="nf">setOccupant</span><span class="o">(</span><span class="no">T</span> <span class="n">occupant</span><span class="o">);</span>

	<span class="kt">void</span> <span class="nf">clearOccupant</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>

<p>This is built on the premise that only a single occupant may occupy a <code class="language-plaintext highlighter-rouge">Position</code> at any given moment.
For Tic-Tac-Toe I have created a concrete class called <a href="https://github.com/dovidkopel/tic-tac-toe/blob/master/oop/src/main/java/com/dovidkopel/tictactoe/oop/position/TwoDimensionalPosition.java"><code class="language-plaintext highlighter-rouge">TwoDimensionalPosition</code></a> which is based on a traditional euclidian coordinate system.</p>

<p>The <a href="https://github.com/dovidkopel/tic-tac-toe/blob/master/oop/src/main/java/com/dovidkopel/tictactoe/oop/game/BoardGame.java"><code class="language-plaintext highlighter-rouge">BoardGame</code></a> interface extends the <code class="language-plaintext highlighter-rouge">Game</code> interface.
Of course the <code class="language-plaintext highlighter-rouge">BoardGame</code> interface also extends the <a href="https://github.com/dovidkopel/tic-tac-toe/blob/master/oop/src/main/java/com/dovidkopel/tictactoe/oop/board/Board.java"><code class="language-plaintext highlighter-rouge">Board</code></a> interface which is actually a marker or empty interface.
I decided that a <code class="language-plaintext highlighter-rouge">Board</code> would be a generic entity on its own outside of the context of the <code class="language-plaintext highlighter-rouge">Game</code>. 
Also, the <code class="language-plaintext highlighter-rouge">Board</code> doesn’t actually define its coordinates or game. 
The <code class="language-plaintext highlighter-rouge">TicTacToeBoard</code> extends the <code class="language-plaintext highlighter-rouge">BoardGame</code> interface. The concrete class <code class="language-plaintext highlighter-rouge">TwoDimensionalTicTacToeBoard</code> extends the <code class="language-plaintext highlighter-rouge">TicTacToeBoard</code>.
This was specifically designed to handle a typical game of Tic-Tac-Toe.</p>

<p>Now let’s look at the <a href="https://github.com/dovidkopel/tic-tac-toe/blob/master/oop/src/main/java/com/dovidkopel/tictactoe/oop/TicTacToe.java"><code class="language-plaintext highlighter-rouge">TicTacToe</code></a> class.
It extends the <strong>SequentialTurnBasedGame</strong> interface. Quite simply the <code class="language-plaintext highlighter-rouge">TicTacToe</code> implementation binds together the rules dictated by the <code class="language-plaintext highlighter-rouge">WinningStrategy</code> implementations.
The rest of the system functions with a publish/subscribe event model.
The idea is to generalize the system to enable listening for certain event types and react to them.
This approach makes it very easy to create custom rules.
I ran into the classic overthinking problem. I was making this project for instructional purposes and therefore had very flimsy requirements.
I wanted to allow for even complex games like realtime strategy games and the like.
I could easily “finish” this if I set some concrete restrictions, but it was challenging to correctly identify the exact nature of the interfaces.</p>

<p>The sequential part ensures that every turn occurs in order one after the other.
Traditional rules of Tic-Tac-Toe as far as I know doesn’t have a time limit on a turn.
I wanted it to be possible that a <code class="language-plaintext highlighter-rouge">Turn</code> should be capable of having a time limitation.
How would the game handle? It should be possible to say that the <code class="language-plaintext highlighter-rouge">Turn</code> was either forfeited or timed-out. 
Ideally the model shouldn’t require changes to the base classes. Proper design should allow for the <code class="language-plaintext highlighter-rouge">Turn</code> to be modular enough.
Certain turn based games like card games or Catan have entire sets of logic that are subject to that turn. 
We need a way to have nested turns that would separate the actions in the turn from the turn itself.
You see this can get very complex. My rule of thumb has been and always been if you are accurate enough to the reality you are almost never wrong.
This logic forced me to rethink a <code class="language-plaintext highlighter-rouge">Turn</code> and separate it from an <code class="language-plaintext highlighter-rouge">Action</code>. A <code class="language-plaintext highlighter-rouge">Turn</code> was a container for the current player.
I even forgot after some time why did the <code class="language-plaintext highlighter-rouge">Action</code> also have a <code class="language-plaintext highlighter-rouge">Player getPlayer()</code> method on its interface.
The idea is that the <code class="language-plaintext highlighter-rouge">Action</code> may be invoked by a different <code class="language-plaintext highlighter-rouge">Player</code> than the parent <code class="language-plaintext highlighter-rouge">Turn</code>.
Suffice to say this can get very complex. The major thing that is well designed is the pub/sub approach.</p>

<p>http://blog.cleancoder.com/uncle-bob/2018/04/13/FPvsOO.html</p>]]></content><author><name></name></author><summary type="html"><![CDATA[I’m a big fan of object-oriented programming and also like functional programming. Take a look at this article on NodeJS in the enterprise. I am strong advocate of polyglot systems and that you want to design a system for the various roles and you need to consider technologies often associated with those roles.]]></summary></entry><entry><title type="html">The Frugal Architect Explained</title><link href="https://dovidkopel.com/2023/12/cost-architecture" rel="alternate" type="text/html" title="The Frugal Architect Explained" /><published>2023-12-01T00:00:00+00:00</published><updated>2023-12-01T00:00:00+00:00</updated><id>https://dovidkopel.com/2023/12/cost-architecture</id><content type="html" xml:base="https://dovidkopel.com/2023/12/cost-architecture"><![CDATA[<p>After combing through the words of the brilliant Werner Vogels regarding <a href="https://thefrugalarchitect.com">cost-based architecture</a>, I felt I wanted to elaborate on his concise and precise words.
Here the word <strong>product</strong> is interchangeable for product, service, component, module, application, system, etc.</p>

<h2 id="law-i-make-cost-a-non-functional-requirement"><a href="https://thefrugalarchitect.com/laws/make-cost-a-non-functional-requirement.html">Law I: Make Cost a Non-functional Requirement.</a></h2>
<p>Cost is more than a number. It’s a mantra. Cost savings cannot be an afterthought. It must be designed and accounted for from the beginning. 
The nuance of this first law is that cost is not usually mentioned with requirements. The discussion of cost usually is only after things are design and deployed.
I’ve heard of asking projects of how much will this cost. But I’ve never thought of making cost an actual requirement. In other words, it is not enough to be cost conscious. 
It is needed to go a step further and actually establish how much or little the product in question will cost to operate. 
This means we design around the cost not exceeding this value. Now we will need to factor this against the performance, scalability and resilience that we are expecting for this product.</p>

<h2 id="law-ii-systems-that-last-align-cost-to-business"><a href="https://thefrugalarchitect.com/laws/systems-that-last-align-cost-to-business.html">Law II: Systems that Last Align Cost to Business.</a></h2>
<p>The emphasis here is that there must be a clear and defined relationship between cost and business. That means that as the business grows your costs may grow. That is to be expected and should align properly.
Cost is not expected in all circumstances to be fixed (unless it is). It is usually understood that costs will rise as different dimensions of usage increase.
The word performance is very vague when we are dealing with the specifics of a system. If we are talking about the throughput, even that is too vague. 
The throughput must be discussed within the context of a volume of requests at one time. That means when we are talking about “how long it takes to process a request”, we need to factor in how many requests we are processing at a given time.
The other important factor is how much “stuff” do we have in our data stores that might affect how long things take. 
If our request involves checking against the correlation of other existing transactions the sheer volume of existing transactions will heavily influence the duration of the call.
So too, if we are expecting up to 100 simultaneous calls, or 100,000 simultaneous calls this will greatly affect the request duration. 
All of this is relevant when you are considering cost. In today’s “serverless” world, the ability to <em>infinitely</em> scale without having much or any provisioned resources can take the burden of upfront costs away.
However, depending on what solution you are using for your data storage will deeply affect your ability to scale.</p>

<p>The business model might necessitate a certain SLA for requests. Ideally as your company and business grows the demand on resources and complexity will increase and ideally costs per unit will decrease.
Obviously the overall cost will rise, but as you hit new cost thresholds you will ideally merit volume discounts on computing services.</p>

<p>The engineering cost is another that needs to factored in. As the complexity of a product grows the development costs and maintenance costs will rise. A simple system is cheap to develop.
A complex one can be costly. So sometimes focusing on cutting costs for computing ends up costing a great deal more money for personnel and isn’t worth the expenditure.
In my opinion nothing beats clean simple code. If you can hit your SLAs, don’t be greedy thinking that you will save big with pennies here and there. The sheer cost of engineering and maintenance on a complex system may not be worth it.</p>

<h2 id="law-iii-architecting-is-a-series-of-trade-offs"><a href="https://thefrugalarchitect.com/laws/architecting-is-a-series-of-trade-offs.html">Law III: Architecting is a Series of Trade-offs.</a></h2>
<p>It is well known that there are no perfect systems or solutions. Every system has a balancing act of a myriad of factors. Cost comes in two flavors in the computer world. Cost is money and cost is time.
In reality, they are one because computing costs ends up being all about money. If you are dealing with an algorithm like for compression or machine learning your approach often favors time over quality of the outputted result.
Let’s look at compression its very simple. Today you can have a song that is encoded with a very high quality lossless encoding that is very large in size. Here you are preferring quality over size. 
Or you can have the humble MP3 that is decent quality and notably small in with respect to filesize. When MP3s came out in the early 90’s internet connection speeds were often dial-up and notoriously slow. 
The MP3 was a game changed because the sound quality was good and the file was easily to deliver.</p>

<p>Today, where everyone has a high speed internet connection, we don’t really need MP3s anymore. In architecture, we will make decisions like the MP3 often for well intended reasons. 
Only to soon find out that reason no longer applicable. A new technology comes out, or the nature of the request rate or data schema change in such a way making the architectural choices stale and outdated.
You will always need to choose between several factors when designing a solution, and that rationale may not stand the test of time.
With that said, the cost should adjust with those factors. The trade-offs for using MP3 over a lossless format is the time to transfer and the storage size. It needs to be understood what you are paying for and why.
As times will change and your music streaming service updates, it might charge slightly more to accommodate for the higher operating costs of storing and streaming the lossless files.</p>

<h2 id="law-iv-unobserved-systems-lead-to-unknown-costs"><a href="https://thefrugalarchitect.com/laws/unobserved-systems-lead-to-unknown-costs.html">Law IV: Unobserved Systems Lead to Unknown Costs.</a></h2>
<p>No matter how much planning goes into a system there will always be unforeseen costs. The traffic is higher than expected, the runtime is longer than expected, the file size is larger than expected.
Without visibility into the system it is impossible to be aware of how on target you may or may not be with respect to expected costs. Let us not forget the costs of management and personnel.
Amazon is well known for having the ability to <em>tag</em> almost every resource out there so that you may effectively and easily known your costs. Knowing the costs of resources without their proper context is more or less useless.
If you know your system costs $1,000 last month, and $1,500 the month prior, what is the rationale for that $500 difference is key. Seeing the correlation between your resource and personnel costs against the business is key.
Let’s say that you have metrics that you can see how many incident tickets you have for a given component. Being able to detect that really the lower month of $1,000 was due to downtime because of several critical failures, would greatly inform your cost analysis.
The more you know and the more dots you can connect the more you can nail down waste and over or under utilization.</p>

<h2 id="law-v-cost-aware-architectures-implement-cost-controls"><a href="https://thefrugalarchitect.com/laws/cost-aware-architectures-implement-cost-controls.html">Law V: Cost Aware Architectures Implement Cost Controls.</a></h2>
<p>Beyond merely monitoring components, the ability to easily tune and configure the cost versus <em>power</em> of a given component becomes a surefire way to save money.
Having components separated into tiers of priority is an easy way to isolate what components may be tweaked with over time for cost savings.
A component in a lower priority may be reduced in <em>power</em> when its need is lower. Such that you don’t need 100 nodes to process data if you are only using 2 at the time. 
The question of startup time comes in to play. What if a customer suddenly needs to run a large payload that will overwhelm our pool of nodes. Do we always run 100 nodes to accommodate for those occasions?
You can be sure that AWS thinks about those questions. We all know that AWS Lambda is not actually infinitely scalable, despite us using the term. AWS must spend a lot of money and time coming up with proper projections on how many nodes to dedicate to handle bursts or surges in usage.</p>

<p>The idea that costs and cost-cutting must be justified via business impact is key. Cost-cutting can go too far when you find yourselves without the number of nodes needed to run your request in a given SLA. 
This is a juggling act that must allow for risk. A backup process that runs in a scheduled fashion. Running the process is integral, but running the process hourly versus twice daily may have drastic cost savings that may not be integral to the business needs.</p>

<p>The idea of <em>tuning</em> a product at small levels enables you to tweak parameters easily that may affect costs. Everyone knows a key in good software design is as much as possible parameterize your configuration enabling configuration without requiring a rebuild.
To be able to tune your product in real time, see the effects and persist that configuration is a game changer.
Being able to do that easily without rebuilding a product opens up your application to new modern possibilities.
Especially today where you might be able to use an ML/AI model to attempt to tweak parameters and find a sweet spot where performance and cost are in perfect harmony.</p>

<h2 id="law-vi-cost-optimization-is-incremental"><a href="https://thefrugalarchitect.com/laws/cost-optimization-is-incremental.html">Law VI: Cost Optimization is Incremental.</a></h2>
<p>If you are trying to optimize your costs and doing it properly it doesn’t happen in one day. Even the best designed systems may be improved over time as factors change or expected utilization differs from expected.
This is built on Laws IV and V. You cannot cut costs without proper metrics, and beginning the process of reducing costs starts with tunable or configurable components that you may be able to adjust that affect performance and costs.
Taking property <em>x</em> and turning it from 10 to 1 is not only ill-advised but wrong. The proper way of tweaking parameters is with a dummy environment where you can run controlled tests with varied parameters and evaluate the performance with those new settings.
As mentioned earlier, today there are automated ways of doing this that might find harmony with ML/AI solutions that can help with these adjustments. When tweaking things manually don’t expect to go from spending $1,000 to $50 without breaking things.
You may never be able to get under a certain cost and that may be the reality. Rewrites of certain components might be necessary beyond just tweaking the known configurable options. Breaking out components into smaller bite sized pieces that further determine if this function is run under the given circumstances are all minor ways to reduce milliseconds from task execution.</p>

<h2 id="law-vii-unchallenged-success-leads-to-assumptions"><a href="https://thefrugalarchitect.com/laws/unchallenged-success-leads-to-assumptions.html">Law VII: Unchallenged Success Leads to Assumptions.</a></h2>
<p>Variety is the spice of life. With technology the “tried and true” spirit can lead only too often to complacency and a lack of growth. As Werner concludes the idea of saying we are a “Java shop” is often the cause of a lack of innovation.
Cost optimization, stems from both cutting down and trimming the fat as well as making the core product more powerful and robust with less. 
Let me give an example. Java is notorious for being a technology that is slow on cold starts. That means to get things going to need to wait until more usage where the application is properly loaded, and the system has tuned itself for optimizations.
A recent new feature enables you to warm up the application and save it in that state, so you may be able to restart the application already nice toasty and warm. This dramatically changes the ability to use Java in a serverless capacity.
This now takes a technology that was more or less unusable in serverless ecosystems and would require complete rewrites to take advantage of this new platform called serverless into a reality.
The status quo is the enemy of innovation. The more innovation yields to better performance, and ultimately better cost savings. When you see the lifecycle of R&amp;D to innovation and cost savings that goes back into R&amp;D it’s a beautiful thing.</p>]]></content><author><name>{&quot;login&quot;=&gt;&quot;dovidkopel&quot;, &quot;email&quot;=&gt;&quot;dovid@dovidkopel.com&quot;, &quot;display_name&quot;=&gt;&quot;Dovid Kopel&quot;, &quot;first_name&quot;=&gt;&quot;Dovid&quot;, &quot;last_name&quot;=&gt;&quot;Kopel&quot;}</name><email>dovid@dovidkopel.com</email></author><category term="architecture" /><summary type="html"><![CDATA[After combing through the words of the brilliant Werner Vogels regarding cost-based architecture, I felt I wanted to elaborate on his concise and precise words. Here the word product is interchangeable for product, service, component, module, application, system, etc.]]></summary></entry></feed>