<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>moehrenzahn.de</title>
    <description>Weblog von Max Melzer</description>
    <link>https://www.moehrenzahn.de/</link>
    <atom:link href="https://www.moehrenzahn.de/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sun, 14 Jun 2026 13:46:46 +0000</pubDate>
    <lastBuildDate>Sun, 14 Jun 2026 13:46:46 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      
      <item>
        <title>Stillleben mit Büste und Steinente</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2026-05-20-stilleben-mit-b%C3%BCste-und-steinente.jpg&quot;&gt; &lt;p&gt;Meine liebe Schwiegermutter hat dieses erstaunliche Talent zur Dekoration, sodass ich mir nie meine eigenen Stillleben zusammenstellen muss, ich muss sie nur besuchen kommen und es gibt jedes mal was neues zu entdecken.&lt;/p&gt;

&lt;p&gt;Vor ein paar Jahren hatte ich auf dem gleichen Fenstersims &lt;a href=&quot;/paintings/2023-04-29-stillleben-mit-b%C3%BCste-und-k%C3%A4seschuh/&quot;&gt;einen coolen Käseschuh entdeckt&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Diesmal hat es mir diese knuffige Ente (oder was das für ein Tier sein soll) aus schwarzem Stein angetan.&lt;/p&gt;
</description>
        <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2026-05-20-stilleben-mit-b%C3%BCste-und-steinente/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2026-05-20-stilleben-mit-b%C3%BCste-und-steinente/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acryl auf canvas board, 30×40cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>Oma</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2026-03-08-oma.jpg&quot;&gt; &lt;p&gt;Dieses Bild habe ich als Geschenk für meine liebe Mutter gemalt, die obendrein eine tolle Oma ist.&lt;/p&gt;

&lt;p&gt;Ich bin insgesamt sehr glücklich mit dem Bild. Es hat einen guten Kontrast zwischen locker und präzise gemalten Bereichen, und das Licht ist … “malerisch”, halt.&lt;/p&gt;
</description>
        <pubDate>Sun, 08 Mar 2026 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2026-03-08-oma/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2026-03-08-oma/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acryl auf canvas board, 30×40cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>Lichtstrahl auf dem Dachboden</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2026-02-28-lichtstrahl-auf-dem-dachboden.jpg&quot;&gt; &lt;p&gt;Diese kleine Szene stand bei mir ein Dreivierteljahr unvollendet herum, bevor ich sie jetzt endlich abgeschlossen habe.&lt;/p&gt;

&lt;p&gt;Ich kam in unserem neuen Haus auf den Dachboden, und die Nachmittagssonne fiel so intensiv auf einen Putzeimer und ein paar Besen, dass diese so mundane Szene extrem episch wirkte. Ich habe ein Foto gemacht, dass diesen Effekt aber überhaupt nicht einfangen konnte.&lt;/p&gt;

&lt;p&gt;Es war eine interessante Herausforderung, diesen Effekt stattdessen in einer Gemäldeskizze einzufangen, und ich denke es ist mir gelungen.&lt;/p&gt;
</description>
        <pubDate>Sat, 28 Feb 2026 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2026-02-28-lichtstrahl-auf-dem-dachboden/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2026-02-28-lichtstrahl-auf-dem-dachboden/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acrylics on canvas board, 40×30cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>Flyleaf 2.5 – Finally adding Widgets, and better ways to fix content issues</title>
        <description>
</description>
        <pubDate>Thu, 27 Nov 2025 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/flyleaf-2-5/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/flyleaf-2-5/</guid>
        
        
        <category>Technologie</category>
        
        <category>Flyleaf</category>
        
        <category>en</category>
        
      </item>
    
      
      <item>
        <title>Portrait eines Jungen</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2025-10-16-portrait-eines-jungen.jpg&quot;&gt; &lt;p&gt;Ich freue mich sehr, dass ich diese kleine Porträtskizze trotz einer langen Malpause in nur anderthalb Sitzungen fertigstellen konnte. Mir fallen zwar schon einige Probleme auf, aber ich habe erreicht, dass man die Person wiedererkennen kann und bin zufrieden.&lt;/p&gt;

&lt;p&gt;Das Originalfoto hatte einen leichte Weitwinkel-Verzerrung, die zu einem etwas eigenartigen Perspektiv-Effekt führt. Bei einem Gemälde, wo Perspektive ja meist naturalistischer gewählt ist, finde ich das aber eigentlich ganz witzig.&lt;/p&gt;
</description>
        <pubDate>Thu, 16 Oct 2025 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2025-10-16-portrait-eines-jungen/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2025-10-16-portrait-eines-jungen/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acrylics on canvas board, 20×20cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>Flyleaf Update 2.4 – The one with Liquid Glass</title>
        <description>
</description>
        <pubDate>Wed, 10 Sep 2025 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/flyleaf-2-4/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/flyleaf-2-4/</guid>
        
        
        <category>Technologie</category>
        
        <category>Flyleaf</category>
        
        <category>en</category>
        
      </item>
    
      
      <item>
        <title>Flyleaf Update 2.3.3 – Wish Fulfillment ahead of iOS 26</title>
        <description>&lt;p&gt;Like many app developers, I have been living the last couple of weeks in the iOS and iPadOS 26 betas, to get a feel for the new “Liquid Glass” design.&lt;/p&gt;

&lt;p&gt;But in terms of Flyleaf development, I have been living in current-OS land and working on an update which I just released today.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/flyleaf-233-collage.png&quot; alt=&quot;Flyleaf 2.3.3 screenshots&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The headline of this update is “wish fulfillment”, because I have taken care of some items frequently-requested by Pocket refugees:&lt;/p&gt;

&lt;p&gt;Firstly, you can now &lt;strong&gt;assign tags directly in the share extension&lt;/strong&gt; of Flyleaf. If you have some complicated tagging system, this might come in handy.&lt;/p&gt;

&lt;p&gt;Secondly, it is now just as &lt;strong&gt;quick to delete articles&lt;/strong&gt; as archiving them. I’ve gotten rid of the “Are you sure?” confirmation dialog. Instead, there now is a “Recently deleted” section in the app settings where you can restore accidentally deleted articles. I think this solution strikes a better balance between convenience and safety.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/flyleaf-233-recently-deleted.png&quot; alt=&quot;The &amp;quot;Recently deleted&amp;quot; list in Flyleaf 2.3.3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I know that there are two other big wishes which are &lt;strong&gt;Highlights&lt;/strong&gt; and &lt;strong&gt;Notes&lt;/strong&gt;. I’ve been working on those features as well, but I’ll release them in a future update when they are fully baked.&lt;/p&gt;

&lt;p&gt;Apart from those new features, I also tweaked the design of some parts of the app a little to better match the new direction that Apple is going towards with iOS and macOS 26. But these are just some minor changes to prepare for my next update which will bring a proper “Liquid Glass” facelift (make sure to &lt;a href=&quot;https://mastodon.social/@flyleafapp&quot;&gt;follow Flyleaf on Mastodon&lt;/a&gt; for updates on how that is going).&lt;/p&gt;

&lt;p&gt;If you appreciate what I’m doing with Flyleaf, please consider &lt;a href=&quot;https://apps.apple.com/app/flyleaf-read-later/id6475200381?action=write-review&quot;&gt;leaving a written review in the App Store&lt;/a&gt;, it really helps a lot!&lt;/p&gt;

&lt;style&gt;
  .flyleaf-download {
    display: flex;
    justify-content: center;
    margin: 2rem auto;
  }

  .flyleaf-download a {
    text-align: center;
    display: flex;
    justify-content: center;
    gap: 1em;
    border: none;
    align-items: center;
    text-align: left;
    font-size: 1.5rem;
    line-height: 1.2;
    transition: transform .2s;
  }
  .flyleaf-download a:hover {
    transform: scale(1.03);
  } 
  .flyleaf-download img {
    flex-grow: 0;
    width: auto;
    margin-left: 0 !important;
    margin-right: 0 !important;
  }
  .flyleaf-download .list {
    display: flex;
    flex-direction: column;
    font-size: 0.8em;
    align-items: flex-start;
    gap: 0.5rem;
  }
  .flyleaf-download a,
  .flyleaf-download a:hover,
  .flyleaf-download a:active,
  .flyleaf-download a:visited {
    border: none;
  }
  .flyleaf-download a:hover {
    border: none;
  }
&lt;/style&gt;

&lt;section class=&quot;flyleaf-download&quot;&gt;
  &lt;a href=&quot;https://apps.apple.com/app/flyleaf-read-later/id6475200381&quot;&gt;
    &lt;img src=&quot;/images/projects/flyleaf-mac-icon-small.png&quot; height=&quot;125&quot; width=&quot;125&quot; class=&quot;icon&quot; /&gt;
    &lt;div class=&quot;list&quot;&gt;
      
        &lt;div&gt;Free Download for &lt;br /&gt;iPhone, iPad and Mac&lt;/div&gt;
        &lt;img class=&quot;a-button&quot; src=&quot;/images/Download_on_the_App_Store_Badge_US-UK_RGB_blk_092917.svg&quot; alt=&quot;Download on the App Store&quot; /&gt;
      
        
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/section&gt;

&lt;h2 id=&quot;flyleaf-233-change-log&quot;&gt;Flyleaf 2.3.3 Change Log&lt;/h2&gt;

&lt;h3 id=&quot;new-features&quot;&gt;New Features&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Assign tags to newly added articles right from the share sheet&lt;/li&gt;
  &lt;li&gt;Drag links onto the app icon in the dock or the home screen to quickly add them to your list&lt;/li&gt;
  &lt;li&gt;Deleting articles is now faster and you can restore recently deleted articles in settings&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;improvements&quot;&gt;Improvements&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Modernized some pieces of UI in anticipation of future OS updates&lt;/li&gt;
  &lt;li&gt;Tag lists are now always sorted alphabetically&lt;/li&gt;
  &lt;li&gt;Added a separate “Search” view&lt;/li&gt;
  &lt;li&gt;Replaced the clunky ‘Add New Tag’ button in the article context menu with a more helpful ‘Manage Tags’ button&lt;/li&gt;
  &lt;li&gt;Moved the search bar to the bottom on iPhone and into the toolbar on iPad&lt;/li&gt;
  &lt;li&gt;The article parser now preserves more kinds of embedded videos&lt;/li&gt;
  &lt;li&gt;Added more visual indicators when an article was loaded via archive.today&lt;/li&gt;
  &lt;li&gt;Added ability to reset app preferences through the Settings app in case of issues&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;bug-fixes&quot;&gt;Bug fixes&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Article images in lists are again updated properly&lt;/li&gt;
  &lt;li&gt;Removed occasional empty gray boxes at the bottom of article pages&lt;/li&gt;
  &lt;li&gt;Removed the “System inverted” color scheme option because it was not very useful and caused terrible crashes&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 08 Jul 2025 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/flyleaf-2-3-3/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/flyleaf-2-3-3/</guid>
        
        
        <category>Technologie</category>
        
        <category>Flyleaf</category>
        
        <category>en</category>
        
      </item>
    
      
      <item>
        <title>Flyleaf 2.3 Feature Overview</title>
        <description>&lt;p&gt;Flyleaf 2.3 is a big update, it probably includes the most new features since &lt;a href=&quot;/flyleaf-2-0/&quot;&gt;the 2.0 update from last year&lt;/a&gt;. In this post, I want to showcase some of the new features.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you’re coming from &lt;a href=&quot;https://support.mozilla.org/de/kb/future-of-pocket&quot;&gt;Pocket&lt;/a&gt;, the most important news first: This update includes a Pocket archive import option, so you can get your whole reading list into Flyleaf with just a few taps.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/flyleaf-2-3-hero.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;overhauled-search-interface&quot;&gt;Overhauled search interface&lt;/h2&gt;

&lt;p&gt;Flyleaf now includes full-text search. It also now highlights your search terms in articles, which makes searching a lot more useful. In terms of filtering, I added an option to toggle between only searching for the exact search string (which used to be the default behavior) and the new default where Flyleaf searches for individual words instead. And you can now either search everywhere or only in the current list.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/flyleaf-2-3-search-options.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As before, all searches in Flyleaf don’t require an internet connection and your search terms never leave your device. Apart from protecting your privacy, this also makes Flyleaf robust against outages and makes sure that features of the app will not stop working if some server component is shut down.&lt;/p&gt;

&lt;h2 id=&quot;completely-configurable-discover-view&quot;&gt;Completely configurable Discover view&lt;/h2&gt;

&lt;p&gt;The second big feature is that the Discover view is now fully customizable. The point of Discover is to help you find something suitable to read from your reading list. It’s not a recommendation engine that will suggest new articles to you, it will only show items that you already added to Flyleaf.&lt;/p&gt;

&lt;p&gt;It lists out brief groups of articles selected by a common factor like short articles, long-reads, videos or items that you have almost finished. The defaults here are generally useful and I like them.&lt;/p&gt;

&lt;p&gt;With Flyleaf 2.3, subscribers can now remove, modify, reorder, and add sections in the Discover view. This also includes changing the look and feel of individual sections. To give you more options, I also added several completely new article preview styles.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/flyleaf-2-3-discover-customization.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is a very flexible system that allows hundreds of different combinations, and I can’t wait to see what you are going to come up with!&lt;/p&gt;

&lt;p&gt;I also made these new preview styles available to choose for other lists.&lt;/p&gt;

&lt;figure&gt;
    &lt;img src=&quot;/images/flyleaf-2-3-card-styles.png&quot; /&gt;
    &lt;figcaption&gt;
    One of the new article preview styles in Flyleaf 2.3
    &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;A small but very effective design tweak is that Flyleaf now analyzes article images for their brightness and chooses the appearance of preview cards accordingly to offer the best readability.&lt;/p&gt;

&lt;h2 id=&quot;use-any-installed-font-as-your-reading-font&quot;&gt;Use any installed font as your reading font&lt;/h2&gt;

&lt;p&gt;Another new subscriber-only feature is that you can now choose any installed font as your reading font. I am currently not able to include many fonts in Flyleaf because their licensing fees are not in proportion to the small amount of revenue that Flyleaf generates, but this should give maximum flexibility for those who want it. (As a side note, the process of adding custom fonts is absolutely awful and confusing on iOS. I’m sorry, but this is something that Apple needs to fix, there’s nothing I can do about it.)&lt;/p&gt;

&lt;figure&gt;
    &lt;img alt=&quot;Flyleaf reading view on iPad using the &apos;Chalkduster&apos; system font&quot; src=&quot;/images/flyleaf-2-3-custom-font.png&quot; /&gt;
    &lt;figcaption&gt;
    Please don&apos;t do this!
    &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;hr /&gt;

&lt;p&gt;This Flyleaf update is the first one where substantial new features are only available to subscribers. But I made sure that those are about advanced usage and customization, not about the core experience of using Flyleaf. It’s important to me that Flyleaf continues to make sense as a free app and is not a compromised experience when you decide not to pay for it. (In fact, I myself still spend much of my time in Flyleaf in an unsubscribed state, because I feel that experience is often good enough.)&lt;/p&gt;

&lt;p&gt;If you haven’t yet, please give Flyleaf a try!&lt;/p&gt;

&lt;style&gt;
  .flyleaf-download {
    display: flex;
    justify-content: center;
    margin: 2rem auto;
  }

  .flyleaf-download a {
    text-align: center;
    display: flex;
    justify-content: center;
    gap: 1em;
    border: none;
    align-items: center;
    text-align: left;
    font-size: 1.5rem;
    line-height: 1.2;
    transition: transform .2s;
  }
  .flyleaf-download a:hover {
    transform: scale(1.03);
  } 
  .flyleaf-download img {
    flex-grow: 0;
    width: auto;
    margin-left: 0 !important;
    margin-right: 0 !important;
  }
  .flyleaf-download .list {
    display: flex;
    flex-direction: column;
    font-size: 0.8em;
    align-items: flex-start;
    gap: 0.5rem;
  }
  .flyleaf-download a,
  .flyleaf-download a:hover,
  .flyleaf-download a:active,
  .flyleaf-download a:visited {
    border: none;
  }
  .flyleaf-download a:hover {
    border: none;
  }
&lt;/style&gt;

&lt;section class=&quot;flyleaf-download&quot;&gt;
  &lt;a href=&quot;https://apps.apple.com/app/flyleaf-read-later/id6475200381&quot;&gt;
    &lt;img src=&quot;/images/projects/flyleaf-mac-icon-small.png&quot; height=&quot;125&quot; width=&quot;125&quot; class=&quot;icon&quot; /&gt;
    &lt;div class=&quot;list&quot;&gt;
      
        &lt;div&gt;Free Download for &lt;br /&gt;iPhone, iPad and Mac&lt;/div&gt;
        &lt;img class=&quot;a-button&quot; src=&quot;/images/Download_on_the_App_Store_Badge_US-UK_RGB_blk_092917.svg&quot; alt=&quot;Download on the App Store&quot; /&gt;
      
        
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/section&gt;

&lt;h2 id=&quot;full-release-notes&quot;&gt;Full release notes&lt;/h2&gt;

&lt;p&gt;For reference, here are the full release notes:&lt;/p&gt;

&lt;h3 id=&quot;new-features&quot;&gt;New Features&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Overhauled search interface with additional options and results highlighting&lt;/li&gt;
  &lt;li&gt;Full-text search (subscription-only)&lt;/li&gt;
  &lt;li&gt;Completely configurable Discover view (subscription-only)&lt;/li&gt;
  &lt;li&gt;Use any installed font as reading font (subscription-only)&lt;/li&gt;
  &lt;li&gt;Allow changing article preview styles in lists (subscription-only)&lt;/li&gt;
  &lt;li&gt;Pocket archive import&lt;/li&gt;
  &lt;li&gt;Optionally disable the page turn animation&lt;/li&gt;
  &lt;li&gt;New “System Inverted” color scheme option&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;improvements&quot;&gt;Improvements&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;More robust handling of PDF and YouTube links&lt;/li&gt;
  &lt;li&gt;Improve PDF parsing line break handling&lt;/li&gt;
  &lt;li&gt;Respect the ‘Reduced motion’ system accessibility setting&lt;/li&gt;
  &lt;li&gt;Allow sorting article lists by “last opened”&lt;/li&gt;
  &lt;li&gt;Remove tracking codes from URLs&lt;/li&gt;
  &lt;li&gt;Improved performance and stability of article lists&lt;/li&gt;
  &lt;li&gt;RSS feeds are now copied to the clipboard instead of opened directly&lt;/li&gt;
  &lt;li&gt;Website parser improvements&lt;/li&gt;
  &lt;li&gt;Design tweaks and fixes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;bug-fixes&quot;&gt;Bug fixes&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Fix article list sometimes staying empty when sorting by publication&lt;/li&gt;
  &lt;li&gt;Don’t dismiss the current article when unarchiving it&lt;/li&gt;
  &lt;li&gt;Fix some cases of missing or duplicated images in articles&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Wed, 28 May 2025 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/flyleaf-2-3/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/flyleaf-2-3/</guid>
        
        
        <category>Flyleaf</category>
        
        <category>Technologie</category>
        
        <category>en</category>
        
      </item>
    
      
      <item>
        <title>One year of Flyleaf</title>
        <description>&lt;p&gt;Exactly one year ago, I launched the first version of &lt;a href=&quot;/project/flyleaf&quot;&gt;Flyleaf&lt;/a&gt; on the iOS and Mac App Store. I built Flyleaf because I wanted a read-later app that offers book-like pagination that isn’t just an afterthought and that also works great on macOS. Back then, I wrote &lt;a href=&quot;/about-flyleaf/&quot;&gt;a short blog post&lt;/a&gt; which went into more detail.&lt;/p&gt;

&lt;style&gt;
  .flyleaf-download {
    display: flex;
    justify-content: center;
    margin: 2rem auto;
  }

  .flyleaf-download a {
    text-align: center;
    display: flex;
    justify-content: center;
    gap: 1em;
    border: none;
    align-items: center;
    text-align: left;
    font-size: 1.5rem;
    line-height: 1.2;
    transition: transform .2s;
  }
  .flyleaf-download a:hover {
    transform: scale(1.03);
  } 
  .flyleaf-download img {
    flex-grow: 0;
    width: auto;
    margin-left: 0 !important;
    margin-right: 0 !important;
  }
  .flyleaf-download .list {
    display: flex;
    flex-direction: column;
    font-size: 0.8em;
    align-items: flex-start;
    gap: 0.5rem;
  }
  .flyleaf-download a,
  .flyleaf-download a:hover,
  .flyleaf-download a:active,
  .flyleaf-download a:visited {
    border: none;
  }
  .flyleaf-download a:hover {
    border: none;
  }
&lt;/style&gt;

&lt;section class=&quot;flyleaf-download&quot;&gt;
  &lt;a href=&quot;https://apps.apple.com/app/flyleaf-read-later/id6475200381&quot;&gt;
    &lt;img src=&quot;/images/projects/flyleaf-mac-icon-small.png&quot; height=&quot;125&quot; width=&quot;125&quot; class=&quot;icon&quot; /&gt;
    &lt;div class=&quot;list&quot;&gt;
      
        &lt;div&gt;Free Download for &lt;br /&gt;iPhone, iPad and Mac&lt;/div&gt;
        &lt;img class=&quot;a-button&quot; src=&quot;/images/Download_on_the_App_Store_Badge_US-UK_RGB_blk_092917.svg&quot; alt=&quot;Download on the App Store&quot; /&gt;
      
        
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/section&gt;

&lt;p&gt;Now, it’s been a year. Time for a small retrospective.&lt;/p&gt;

&lt;p&gt;Over the last year, I managed to publish 12 updates, at a steady pace of about one update per month. Most of these were essentially bug fixing and fine-tuning, but I also shipped some substantial feature additions, like the Discover view and the gesture-driven reading interface.&lt;/p&gt;

&lt;p&gt;The worst time developing Flyleaf was undoubtedly shortly before the release of iOS 18. There were many bugs in the iOS 18 betas which caused crashes and issues in Flyleaf. It was a &lt;em&gt;lot&lt;/em&gt; of work to find workarounds as I was scrambling to get Flyleaf running more or less stable on iOS 18. I found it very stressful to be at the mercy of Apple’s development cycle like that. I hope that I will manage this better this year.&lt;/p&gt;

&lt;p&gt;What &lt;em&gt;has&lt;/em&gt; been awesome is the feedback from users. I get about one email a week from someone who uses and loves Flyleaf and wants to report a bug or ask for some feature. I know this will not be sustainable forever, but for now I have been enjoying these emails a lot and reply to all of them. It’s nice to know that I did not only build Flyleaf for myself, but to hear that other people enjoy and care about it, too.&lt;/p&gt;

&lt;p&gt;Another way this enjoyment manifests is, of course, subscriptions. Over the last year, I managed to convince over 130 people to support Flyleaf with their hard-earned money. Thats not a life-changing, cancel-your-day-job amount, but it greatly surpassed my expectations and it’s a big motivation to continue working on Flyleaf.&lt;/p&gt;

&lt;p&gt;Overall, I’m glad I decided to go with a subscription model with Flyleaf, even though I know many people are annoyed by subscription apps. With a pay-once model, I constantly would have to think about ways to acquire new customers. Thanks to the subscriptions, I can think of ways to make the app better for existing users instead, which is much less stressful for me. It also makes the app easier to sustain with it’s small user-base.&lt;/p&gt;

&lt;p&gt;In general, it’s difficult to get a small-time indie app noticed on the App Store. I now get between 5 and 10 organic downloads per day, which is not a lot. I only saw brief changes in the download numbers when someone recommended Flyleaf. By far my biggest bump in downloads came when &lt;a href=&quot;https://lifehacker.com/tech/flyleaf-is-the-best-read-it-later-app-for-apple-users&quot;&gt;Justin Pot wrote a generous article about Flyleaf on LifeHacker&lt;/a&gt; in September, which made a huge difference.&lt;/p&gt;

&lt;p&gt;My only piece of advice here is to actually get in touch with individual journalists and bloggers. Sending press releases to big outlets is pretty much pointless; contacting individual authors and editors is a little more effective in my experience.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;So, what are my plans for the future?&lt;/p&gt;

&lt;p&gt;Now that the first year is over, it will be time for my yearly subscribers to renew their subscriptions. This is a little bit scary. I really hope I managed to convince people that Flyleaf is a project which makes sense to support in the long term, but time will tell how my subscriber numbers will develop.&lt;/p&gt;

&lt;p&gt;But for now, Flyleaf remains a hobby I work on in the evenings once the kids are asleep. I still use the app myself every day, so I’m motivated to keep improving it. I hope to continue the pace of updates and actually ship some substantial features people have been asking for. But more about that later.&lt;/p&gt;

&lt;p&gt;To keep up with the latest developments, you can &lt;a href=&quot;https://mastodon.social/@flyleafapp/&quot;&gt;follow my very occasional posts on Mastodon&lt;/a&gt;. If you are interested in joining the TestFlight, feel free to &lt;a href=&quot;mailto:flyleaf@moehrenzahn.de&quot;&gt;get in touch&lt;/a&gt;. Thanks for reading and thanks for your continued support!&lt;/p&gt;
</description>
        <pubDate>Thu, 27 Mar 2025 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/one-year-of-flyleaf/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/one-year-of-flyleaf/</guid>
        
        
        <category>Flyleaf</category>
        
        <category>Technologie</category>
        
        <category>en</category>
        
      </item>
    
      
      <item>
        <title>Flyleaf Update 2.2</title>
        <description>&lt;style&gt;
  .flyleaf-download {
    display: flex;
    justify-content: center;
    margin: 2rem auto;
  }

  .flyleaf-download a {
    text-align: center;
    display: flex;
    justify-content: center;
    gap: 1em;
    border: none;
    align-items: center;
    text-align: left;
    font-size: 1.5rem;
    line-height: 1.2;
    transition: transform .2s;
  }
  .flyleaf-download a:hover {
    transform: scale(1.03);
  } 
  .flyleaf-download img {
    flex-grow: 0;
    width: auto;
    margin-left: 0 !important;
    margin-right: 0 !important;
  }
  .flyleaf-download .list {
    display: flex;
    flex-direction: column;
    font-size: 0.8em;
    align-items: flex-start;
    gap: 0.5rem;
  }
  .flyleaf-download a,
  .flyleaf-download a:hover,
  .flyleaf-download a:active,
  .flyleaf-download a:visited {
    border: none;
  }
  .flyleaf-download a:hover {
    border: none;
  }
&lt;/style&gt;

&lt;section class=&quot;flyleaf-download&quot;&gt;
  &lt;a href=&quot;https://apps.apple.com/app/flyleaf-read-later/id6475200381&quot;&gt;
    &lt;img src=&quot;/images/projects/flyleaf-mac-icon-small.png&quot; height=&quot;125&quot; width=&quot;125&quot; class=&quot;icon&quot; /&gt;
    &lt;div class=&quot;list&quot;&gt;
      
        &lt;div&gt;Free Download for &lt;br /&gt;iPhone, iPad and Mac&lt;/div&gt;
        &lt;img class=&quot;a-button&quot; src=&quot;/images/Download_on_the_App_Store_Badge_US-UK_RGB_blk_092917.svg&quot; alt=&quot;Download on the App Store&quot; /&gt;
      
        
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/section&gt;

&lt;p&gt;While preparing the just-released 2.2.2 update for Flyleaf, &lt;a href=&quot;/project/flyleaf&quot;&gt;my read-later app for iOS and macOS&lt;/a&gt;, I was reminded that I didn’t write anything here about any of the 2.2 patches. So let’s do that now.&lt;/p&gt;

&lt;h2 id=&quot;flyleaf-220&quot;&gt;Flyleaf 2.2.0&lt;/h2&gt;

&lt;p&gt;The main reason I pushed out the 2.2.0 update when I did was that a change in the HTML markup of the New York Times website triggered a fatal bug in Flyleaf which would send the app into a continuous crash-on-launch loop. Suffice it to say I heard about this issues from a lot of my users. Apart from that, Flyleaf 2.2.0 introduced a completely overhauled font picker along with some new premium fonts.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/flyleaf-macos-fontpicker.png&quot; alt=&quot;The new Flyleaf 2.2 font picker in the macOS version.&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;flyleaf-221&quot;&gt;Flyleaf 2.2.1&lt;/h2&gt;

&lt;p&gt;2.2.1 was a very small update which merely fixed an issue with the new font selector and was released just a day or two later.&lt;/p&gt;

&lt;h2 id=&quot;flyleaf-222&quot;&gt;Flyleaf 2.2.2&lt;/h2&gt;

&lt;p&gt;Today, Flyleaf 2.2.2 (hopefully) concludes this series of updates by finalizing the new font picker, adding even more fonts, and sanding off even more rough edges in the app’s UI and website parser.&lt;/p&gt;

&lt;h2 id=&quot;migrating-the-flyleaf-app-group-name-on-macos&quot;&gt;Migrating the Flyleaf App Group name on macOS&lt;/h2&gt;

&lt;p&gt;I would have released 2.2.2 quite a bit earlier if I wasn’t forced by Apple to change the name of the App Group on macOS. Let me explain: Up until now, Flyleaf on macOS followed the iOS convention of starting the App Group name with “group”. With the release of Sequoia, Apple decided that it would prefer if App Group names on macOS started with the “team ID” of the app’s publisher. And since a couple of weeks ago, App Store Connect would no longer accept macOS builds using an iOS-style App Group name at all. So I had to do something.&lt;/p&gt;

&lt;p&gt;The problem is that the App Group contains the app’s list of user preferences as well as the local database holding all added articles and tags. When I change the name of the App Group, Flyleaf loses access to this data. This is not a huge deal since the articles and tags can be re-synched from iCloud (as long as synching is enabled and up to date). But I wanted a more seamless transition.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/flyleaf-macos-appgroupmigration.png&quot; alt=&quot;The new Flyleaf 2.2.2 App Group migration flow. The dialog says: &amp;quot;Because of a change in macOS, Flyleaf needs to perform a quick data migration. In the next step, you need to grant Flyleaf permission to access the previous data directory. If you don&apos;t migrate, Flyleaf will try to restore your articles and tags from iCloud instead. Your settings will be reset to the defaults.&amp;quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So I built a little migration flow for the macOS version which uses the system file picker to circumvent the app sandbox to temporarily access the previous App Group directory and move over all the files. This is a little bit scary because it’s difficult to make sure this works as expected in production, but I’m confident I found a good solution. Let’s hope everything goes smoothly and we can forget about this whole thing soon.&lt;/p&gt;

&lt;h2 id=&quot;frequently-asked-questions&quot;&gt;Frequently Asked Questions&lt;/h2&gt;

&lt;p&gt;I have also taken the time to compile a little &lt;a href=&quot;/project/flyleaf/faq&quot;&gt;FAQ page for Flyleaf&lt;/a&gt;. I pretty much just went through my emails and put together a list of my generally-applicable answers.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Overall, I feel like Flyleaf is now in a pretty good place in terms of stability and feature offerings. But I still have lots of cool stuff on my roadmap, which I will talk more about at a later time.&lt;/p&gt;

&lt;p&gt;If you haven’t yet, you can grab Flyleaf 2.2.2 from the App Store right now. If you appreciate what I’m doing, you can help me a lot by &lt;a href=&quot;https://apps.apple.com/app/flyleaf-read-later/id6475200381?action=write-review&quot;&gt;leaving a review on the App Store&lt;/a&gt;.&lt;/p&gt;

&lt;style&gt;
  .flyleaf-download {
    display: flex;
    justify-content: center;
    margin: 2rem auto;
  }

  .flyleaf-download a {
    text-align: center;
    display: flex;
    justify-content: center;
    gap: 1em;
    border: none;
    align-items: center;
    text-align: left;
    font-size: 1.5rem;
    line-height: 1.2;
    transition: transform .2s;
  }
  .flyleaf-download a:hover {
    transform: scale(1.03);
  } 
  .flyleaf-download img {
    flex-grow: 0;
    width: auto;
    margin-left: 0 !important;
    margin-right: 0 !important;
  }
  .flyleaf-download .list {
    display: flex;
    flex-direction: column;
    font-size: 0.8em;
    align-items: flex-start;
    gap: 0.5rem;
  }
  .flyleaf-download a,
  .flyleaf-download a:hover,
  .flyleaf-download a:active,
  .flyleaf-download a:visited {
    border: none;
  }
  .flyleaf-download a:hover {
    border: none;
  }
&lt;/style&gt;

&lt;section class=&quot;flyleaf-download&quot;&gt;
  &lt;a href=&quot;https://apps.apple.com/app/flyleaf-read-later/id6475200381&quot;&gt;
    &lt;img src=&quot;/images/projects/flyleaf-mac-icon-small.png&quot; height=&quot;125&quot; width=&quot;125&quot; class=&quot;icon&quot; /&gt;
    &lt;div class=&quot;list&quot;&gt;
      
        &lt;div&gt;Free Download for &lt;br /&gt;iPhone, iPad and Mac&lt;/div&gt;
        &lt;img class=&quot;a-button&quot; src=&quot;/images/Download_on_the_App_Store_Badge_US-UK_RGB_blk_092917.svg&quot; alt=&quot;Download on the App Store&quot; /&gt;
      
        
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/section&gt;
</description>
        <pubDate>Thu, 20 Mar 2025 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/flyleaf-2-2/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/flyleaf-2-2/</guid>
        
        
        <category>Flyleaf</category>
        
        <category>Technologie</category>
        
        <category>en</category>
        
      </item>
    
      
      <item>
        <title>Mein Nachbar Totoro</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2025-03-09-my-neighbor-totoro.jpg&quot;&gt; &lt;p&gt;Dieses Gemälde ist eine Studie dieser berühmten Szene aus dem fantastischen &lt;a href=&quot;https://de.wikipedia.org/wiki/Mein_Nachbar_Totoro&quot;&gt;Studio-Ghibli-Film “Mein Nachbar Totoro”&lt;/a&gt;. Da die Vorlage selbst eine Art Gemälde ist, konnte hier nicht viel schief gehen.&lt;/p&gt;
</description>
        <pubDate>Sun, 09 Mar 2025 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2025-03-09-my-neighbor-totoro/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2025-03-09-my-neighbor-totoro/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acryl auf Leinwand, 40×40cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>Nordseestrand #1</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2024-10-04-nordseestrand-1.jpg&quot;&gt; &lt;p&gt;Ich habe es geschafft, &lt;a href=&quot;/flyleaf-2-1/&quot;&gt;zwischen Flyleaf-Releases&lt;/a&gt; noch ein Bild zu malen! Vorlage war diesmal ein Urlaubsfoto von der holländischen Nordsee. Von Callantsoog, um genau zu sein.&lt;/p&gt;

&lt;p&gt;Die Zeichnung ist ein bisschen schräg geraten, aber die Farben sind ganz gut getroffen, wie ich finde. Und ich bin echt froh, dass ich dieses Bild in einer einzigen dreistündigen Sitzung zu Ende bringen konnte. Es ist nett, sich nicht mehrere Tage lang mit demselben Bild herumzuschlagen.&lt;/p&gt;
</description>
        <pubDate>Fri, 04 Oct 2024 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2024-10-04-nordseestrand-1/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2024-10-04-nordseestrand-1/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acrylics on canvas board, 30×40cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>Flyleaf Update 2.1</title>
        <description>&lt;p&gt;Hot off the presses, today I pushed the button to release Flyleaf 2.1.&lt;/p&gt;

&lt;p&gt;This release gave me a lot of headaches, mostly caused by haphazard changes and bugs introduced by Apple with iOS 18 and macOS 15. With 2.1, I think I am at a point where Flyleaf is as stable on the new Apple OS’s as on the previous ones.&lt;/p&gt;

&lt;p&gt;Since I apparently have no self-control, I also added some new features. On iPad, I removed the ability to show a sidebar, in favor of having your library in full-screen. I’m convinced that that is the better way to use Flyleaf (and it also happens to circumvent a crash in iPadOS 15). On the Mac, Flyleaf also uses this new full-screen view when the sidebar is hidden.&lt;/p&gt;

&lt;p&gt;Flyleaf 2.1 introduces a new responsive layout where your articles are displayed in a grid on wider displays. This is a nice improvement, but I had to sacrifice the swipe actions in the article lists to make it work. There still is the long-press context-menu to quickly access article actions from the list view.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/flyleaf-2-1-grid-view.png&quot; alt=&quot;The new full screen article library in Flyleaf 2.1 on macOS&quot; /&gt;&lt;/p&gt;

&lt;style&gt;
  .flyleaf-download {
    display: flex;
    justify-content: center;
    margin: 2rem auto;
  }

  .flyleaf-download a {
    text-align: center;
    display: flex;
    justify-content: center;
    gap: 1em;
    border: none;
    align-items: center;
    text-align: left;
    font-size: 1.5rem;
    line-height: 1.2;
    transition: transform .2s;
  }
  .flyleaf-download a:hover {
    transform: scale(1.03);
  } 
  .flyleaf-download img {
    flex-grow: 0;
    width: auto;
    margin-left: 0 !important;
    margin-right: 0 !important;
  }
  .flyleaf-download .list {
    display: flex;
    flex-direction: column;
    font-size: 0.8em;
    align-items: flex-start;
    gap: 0.5rem;
  }
  .flyleaf-download a,
  .flyleaf-download a:hover,
  .flyleaf-download a:active,
  .flyleaf-download a:visited {
    border: none;
  }
  .flyleaf-download a:hover {
    border: none;
  }
&lt;/style&gt;

&lt;section class=&quot;flyleaf-download&quot;&gt;
  &lt;a href=&quot;https://apps.apple.com/app/flyleaf-read-later/id6475200381&quot;&gt;
    &lt;img src=&quot;/images/projects/flyleaf-mac-icon-small.png&quot; height=&quot;125&quot; width=&quot;125&quot; class=&quot;icon&quot; /&gt;
    &lt;div class=&quot;list&quot;&gt;
      
        &lt;div&gt;Free Download for &lt;br /&gt;iPhone, iPad and Mac&lt;/div&gt;
        &lt;img class=&quot;a-button&quot; src=&quot;/images/Download_on_the_App_Store_Badge_US-UK_RGB_blk_092917.svg&quot; alt=&quot;Download on the App Store&quot; /&gt;
      
        
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/section&gt;

&lt;p&gt;Here comes the full change log:&lt;/p&gt;

&lt;h2 id=&quot;flyleaf-210-change-log&quot;&gt;Flyleaf 2.1.0 Change Log&lt;/h2&gt;

&lt;h3 id=&quot;features&quot;&gt;Features&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Responsive multi-column design for Discover view and article lists on larger screens&lt;/li&gt;
  &lt;li&gt;Single column navigation mode for macOS and iPadOS&lt;/li&gt;
  &lt;li&gt;Manually prioritize articles in the download queue&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;improvements&quot;&gt;Improvements&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;The parser is better at finding the main text of some webpages&lt;/li&gt;
  &lt;li&gt;Temporarily show the status bar when swiping up while in fullscreen mode&lt;/li&gt;
  &lt;li&gt;Various smaller UI tweaks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;bug-fixes&quot;&gt;Bug Fixes&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Re-enable the “Read now” button in the share sheet on iOS 18&lt;/li&gt;
  &lt;li&gt;Fix reading position lost when rotating the device or resizing the window&lt;/li&gt;
  &lt;li&gt;Fix crash when opening certain context menus on macOS 15&lt;/li&gt;
  &lt;li&gt;Fix settings window layout on macOS 15&lt;/li&gt;
  &lt;li&gt;Fix crash on Discover view when archiving or deleting the last article on your list&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 04 Oct 2024 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/flyleaf-2-1/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/flyleaf-2-1/</guid>
        
        
        <category>Flyleaf</category>
        
        <category>Technologie</category>
        
        <category>en</category>
        
      </item>
    
      
      <item>
        <title>Gedanken zur Landtagswahl 2024 in Sachsen</title>
        <description>&lt;p&gt;Ich habe eigentlich überhaupt keine Lust, diesen Text zu schreiben. Ich habe keine Lust, mich zu ärgern. Und ich habe keine Lust auf den Ärger, den ich mir damit einhandele. Aber es drückt mich doch zu sehr ein Gefühl von Verantwortung, sowohl als Deutscher, als auch als Familienvater.&lt;/p&gt;

&lt;p&gt;Am Sonntag ist in meinem Heimatbundesland Sachsen Landtagswahl. Es wäre echt schön, wenn ich jetzt vor der Wahl den Luxus hätte, über Politik zu fachsimpeln und darüber nachzudenken, was unser Land voranbringen könnte. Stattdessen muss ich mir Sorgen darum machen, ob die Demokratie selbst in meiner Heimat Schaden nehmen wird.&lt;/p&gt;

&lt;p&gt;Die Wahlumfragen stellen in Aussicht, dass die AfD in Sachsen stärkste Kraft werden könnte. Das würde bedeuten, dass etwa ein Drittel der Stimmen in meiner Heimat an eine Partei gehen, die vom sächsischen Verfassungsschutz als &lt;a href=&quot;https://www.tagesschau.de/inland/innenpolitik/verfassungsschutz-afd-sachsen-rechtsextremistisch-100.html&quot;&gt;“gesichert rechtsextremistisch”&lt;/a&gt; eingestuft wird, weil sie sich inhaltlich gegen die “im Grundgesetz verankerte Garantie der Menschenwürde” richtet und völkisch-nationalistische, judenfeindliche und verschwörungsideologische Positionen vertritt. Eine Partei, die noch immer gegen jeden wissenschaftlichen Konsens &lt;a href=&quot;https://www.mdr.de/wissen/uni-leipzig-green-deal-rechte-parteien-100.html&quot;&gt;die menschengemachte Klimakatastrophe leugnet&lt;/a&gt;. Eine Partei, deren ranghohe Vertreter &lt;a href=&quot;https://correctiv.org/aktuelles/neue-rechte/2024/01/10/geheimplan-remigration-vertreibung-afd-rechtsextreme-november-treffen/&quot;&gt;von der Ausweisung von Millionen Menschen aus Deutschland, die nicht “assimiliert” genug sind, träumen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ich habe Angst davor, dass diese Menschenfeindlichen Ideen hierzulande zur Normalität werden. Dass meine Steuergelder zur Umsetzung dieser Pläne zweckentfremdet werden. Dass meine Kinder sie in der Schule gelehrt bekommen. Dass wir uns in Gefahr begeben, wenn wir uns für Vielfalt oder die Benachteiligten in unserer Gesellschaft einsetzen.&lt;/p&gt;

&lt;p&gt;Der Grund für diesen Text sind aber nicht die Faschisten aus AfD und anderen Parteien, die diese Pläne schmieden. Vielmehr sind es Menschen aus meinem Umfeld, Menschen die ich gut kenne, sogar gern habe – die “Anständigen”.&lt;/p&gt;

&lt;p&gt;Manche von diesen “Anständigen” sehen sich vielleicht als “Protestwähler”, die “denen da oben” mal einen ordentlichen Denkzettel verpassen möchten. Dafür habe ich Sympathie, ich bin ja selber oft genug unzufrieden mit der Politik in unserem Land. Aber wenn ein Politiker im Fernsehen etwas Dummes gesagt hat, und ihr deshalb eine Partei an die Macht bringt, die unsere freiheitlich-demokratische Grundordnung kaputtmachen will, dann habe ich dafür Null Verständnis.&lt;/p&gt;

&lt;p&gt;Manche dieser “Anständigen” gehen sogar Sonntags in die Kirche und beten dort “dein Reich komme”, und wählen die AfD, weil sie sich vom Islam oder generell von Einwanderer:innen bedroht fühlen.&lt;/p&gt;

&lt;p&gt;In meiner Bibel &lt;a href=&quot;https://www.bibleserver.com/LUT/2.Mose22,20&quot;&gt;steht dazu&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Einen Fremdling sollst du nicht bedrücken und bedrängen; denn ihr seid auch Fremdlinge in Ägyptenland gewesen.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Und &lt;a href=&quot;https://www.bibleserver.com/LUT/Matth%C3%A4us25%2C43&quot;&gt;Jesus Christus spricht&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Ich bin ein Fremder gewesen und ihr habt mich nicht aufgenommen. Ich bin nackt gewesen und ihr habt mich nicht gekleidet. Ich bin krank und im Gefängnis gewesen und ihr habt mich nicht besucht.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Wie passt das zusammen mit einer Partei, deren Chef meint &lt;a href=&quot;https://www.merkur.de/politik/vor-landtagswahl-afd-fuehrung-aeussert-sachsen-unattraktiv-machen-zr-93254954.html&quot;&gt;“wir wollen Sachsen unattraktiv machen, für Menschen, die nur hierher kommen, um in unser Sozialsystem einzuwandern”&lt;/a&gt;? Könnt ihr das echt nicht als die plumpe, ausländerfeindliche Hetze erkennen, die das ist?&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Jetzt höre ich schon die Rufe, “du kannst uns doch nicht vorschreiben, was wir zu wählen haben, das ist undemokratisch!” Natürlich, ich kann niemandem etwas vorschreiben. Ich allein kann überhaupt keinen messbaren Einfluss auf das Ergebnis der Wahl ausüben (wohl auch ganz gut so). Aber es soll hinterher niemand sagen können: “Hab’ ich ja nicht gewusst.” Es ist nicht “normal” oder “okay”, Rechtsextreme zu wählen. Auch nicht, wenn es Viele tun. Es ist zutiefst &lt;em&gt;unanständig&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Und sollte sich am Ende doch jemand dafür interessieren, was ich mir wünsche: Bitte geht und wählt am Sonntag eine demokratische Partei, am Besten eine, die sich auch um das Schicksal derer im Land schert, die nicht unbedingt so aussehen, glauben oder lieben wie die Mehrheitsgesellschaft! &amp;lt;3&lt;/p&gt;
</description>
        <pubDate>Fri, 30 Aug 2024 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/landtagswahl-sachsen-2024/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/landtagswahl-sachsen-2024/</guid>
        
        
        <category>Politik</category>
        
        <category>de</category>
        
      </item>
    
      
      <item>
        <title>Flyleaf Update 2.0</title>
        <description>&lt;p&gt;Today I finally published the big Flyleaf 2.0 update! Pretty much every part of the app has been touched in some way, so there is lots of new stuff. Flyleaf is my “read-later” app that displays saved articles from the web in a meticulously designed reading view, without popups, ads or other distractions.&lt;/p&gt;

&lt;p&gt;The most important addition is certainly the new &lt;strong&gt;Discover view&lt;/strong&gt;. This view is not meant to add new articles to your list, but instead to resurface articles that are &lt;em&gt;already in&lt;/em&gt; your list. I think this is a really useful addition for the way most people use read-later apps. It also looks pretty.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/projects/flyleaf-discover-ios.png&quot; alt=&quot;Flyleaf 2.0 Discover screen&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Another big item is the new &lt;strong&gt;full screen reading mode&lt;/strong&gt; on iOS. It sounds like a simple feature – you just hide the bottom toolbar and that’s it. But I had to invent a whole new gesture interface to make the toolbar still intuitively accessible while in fullscreen.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/projects/flyleaf-fullscreen-ipad.png&quot; alt=&quot;Flyleaf in full screen on an iPad&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I’m very happy with the way the new slide-away details view work. I even managed to include a little reference to the good old iOS 6 days with the “stretched linen” background texture.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/projects/flyleaf-belowview-ios.png&quot; alt=&quot;Flyleaf article details view with gray linen background texture&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Because Flyleaf is very much focused on the book-like pagination mode, full screen reading is only available in that mode (for now).&lt;/p&gt;

&lt;p&gt;I am also very proud of the new &lt;strong&gt;support for right-to-left-script articles&lt;/strong&gt;. This was quite involved to get working with Flyleaf’s book-like pagination. It’s no wonder that no other read-later app supports this feature as completely as Flyleaf does.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/projects/flyleaf-mac-rtl-dark.png&quot; alt=&quot;An article in Hebrew in Flyleaf on macOS&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;I’m pretty relieved that this huge update is now finished.&lt;/p&gt;

&lt;p&gt;I owe big thanks to my beta testers who were actively sending me feedback and helped me to investigate and fix some hard-to-track-down bugs. Especially the RTL mode would not have happened without your support!&lt;/p&gt;

&lt;style&gt;
  .flyleaf-download {
    display: flex;
    justify-content: center;
    margin: 2rem auto;
  }

  .flyleaf-download a {
    text-align: center;
    display: flex;
    justify-content: center;
    gap: 1em;
    border: none;
    align-items: center;
    text-align: left;
    font-size: 1.5rem;
    line-height: 1.2;
    transition: transform .2s;
  }
  .flyleaf-download a:hover {
    transform: scale(1.03);
  } 
  .flyleaf-download img {
    flex-grow: 0;
    width: auto;
    margin-left: 0 !important;
    margin-right: 0 !important;
  }
  .flyleaf-download .list {
    display: flex;
    flex-direction: column;
    font-size: 0.8em;
    align-items: flex-start;
    gap: 0.5rem;
  }
  .flyleaf-download a,
  .flyleaf-download a:hover,
  .flyleaf-download a:active,
  .flyleaf-download a:visited {
    border: none;
  }
  .flyleaf-download a:hover {
    border: none;
  }
&lt;/style&gt;

&lt;section class=&quot;flyleaf-download&quot;&gt;
  &lt;a href=&quot;https://apps.apple.com/app/flyleaf-read-later/id6475200381&quot;&gt;
    &lt;img src=&quot;/images/projects/flyleaf-mac-icon-small.png&quot; height=&quot;125&quot; width=&quot;125&quot; class=&quot;icon&quot; /&gt;
    &lt;div class=&quot;list&quot;&gt;
      
        &lt;div&gt;Free Download for &lt;br /&gt;iPhone, iPad and Mac&lt;/div&gt;
        &lt;img class=&quot;a-button&quot; src=&quot;/images/Download_on_the_App_Store_Badge_US-UK_RGB_blk_092917.svg&quot; alt=&quot;Download on the App Store&quot; /&gt;
      
        
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/section&gt;

&lt;p&gt;For completeness sake, here comes the full list of all significant changes in Flyleaf 2.0:&lt;/p&gt;

&lt;h3 id=&quot;new-features&quot;&gt;New Features&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;New “Discover” view for finding things to read from your article list&lt;/li&gt;
  &lt;li&gt;Fullscreen reading view&lt;/li&gt;
  &lt;li&gt;Swipe up in reading view to discover additional info and actions for the current article&lt;/li&gt;
  &lt;li&gt;Support for articles in Arabic, Hebrew and other right-to-left languages&lt;/li&gt;
  &lt;li&gt;Tap images and videos to see them in full screen&lt;/li&gt;
  &lt;li&gt;Customizable page margins&lt;/li&gt;
  &lt;li&gt;Archive.today integration (experimental)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;improvements&quot;&gt;Improvements&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Refreshed design&lt;/li&gt;
  &lt;li&gt;Reorganized app settings&lt;/li&gt;
  &lt;li&gt;Share extension improvements&lt;/li&gt;
  &lt;li&gt;Better feedback when downloading or processing articles&lt;/li&gt;
  &lt;li&gt;Tweaks to theme colors&lt;/li&gt;
  &lt;li&gt;Layout improvements for big iPhones in landscape mode&lt;/li&gt;
  &lt;li&gt;Toolbar buttons are now easier to tap&lt;/li&gt;
  &lt;li&gt;Many improvements to the article text parser&lt;/li&gt;
  &lt;li&gt;Include video and audio attachments from Mastodon threads&lt;/li&gt;
  &lt;li&gt;Search is now faster and more reliable&lt;/li&gt;
  &lt;li&gt;Many more small tweaks and improvements&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 26 Aug 2024 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/flyleaf-2-0/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/flyleaf-2-0/</guid>
        
        
        <category>Flyleaf</category>
        
        <category>Technologie</category>
        
        <category>en</category>
        
      </item>
    
      
      <item>
        <title>Schlendern in Stralsund</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2024-06-23-schlendern-in-stralsund.jpg&quot;&gt; &lt;p&gt;Ich habe dieses Bild hauptsächlich gemalt, um aus einer mehrmonatigen Phase  herauszukommen, in der ich gar nicht gemalt habe.&lt;/p&gt;

&lt;p&gt;Es ist eine kleine Szene aus der Altstadt von Stralsund – ein weiteres Urlaubsfoto, das ich in ein Gemälde verwandelt habe.&lt;/p&gt;

&lt;p&gt;Was mich an dieser Szene inspiriert hat, sind die interessanten Farbkontraste zwischen den verschiedenen Teilen des Bildes. Außerdem gibt es eine ganze Reihe interessanter Linien, die den Betrachter in die Mitte des Bildes führen.&lt;/p&gt;
</description>
        <pubDate>Sun, 23 Jun 2024 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2024-06-23-schlendern-in-stralsund/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2024-06-23-schlendern-in-stralsund/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acrylics on canvas board, 40×30cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>Apptisan #015: Flyleaf</title>
        <description>&lt;p&gt;I was graciously invited to write about &lt;a href=&quot;/projects/flyleaf&quot;&gt;my read-it-later app Flyleaf&lt;/a&gt; on &lt;a href=&quot;https://apptisan.substack.com/p/apptisan-015-flyleaf&quot;&gt;Apptisan, a chinese newsletter about indie software:&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I originally studied theology at university in Germany. But I shifted to software development when I figured out that this is a more reliable way to feed a family. By day, I currently work as a Java developer for a small product company in Germany. My first small iOS side project was Devotionalium, an app for reading holy scriptures of different world religions. Flyleaf is my first iOS app that will hopefully have broader appeal (and success)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;style&gt;
  .flyleaf-download {
    display: flex;
    justify-content: center;
    margin: 2rem auto;
  }

  .flyleaf-download a {
    text-align: center;
    display: flex;
    justify-content: center;
    gap: 1em;
    border: none;
    align-items: center;
    text-align: left;
    font-size: 1.5rem;
    line-height: 1.2;
    transition: transform .2s;
  }
  .flyleaf-download a:hover {
    transform: scale(1.03);
  } 
  .flyleaf-download img {
    flex-grow: 0;
    width: auto;
    margin-left: 0 !important;
    margin-right: 0 !important;
  }
  .flyleaf-download .list {
    display: flex;
    flex-direction: column;
    font-size: 0.8em;
    align-items: flex-start;
    gap: 0.5rem;
  }
  .flyleaf-download a,
  .flyleaf-download a:hover,
  .flyleaf-download a:active,
  .flyleaf-download a:visited {
    border: none;
  }
  .flyleaf-download a:hover {
    border: none;
  }
&lt;/style&gt;

&lt;section class=&quot;flyleaf-download&quot;&gt;
  &lt;a href=&quot;https://apps.apple.com/app/flyleaf-read-later/id6475200381&quot;&gt;
    &lt;img src=&quot;/images/projects/flyleaf-mac-icon-small.png&quot; height=&quot;125&quot; width=&quot;125&quot; class=&quot;icon&quot; /&gt;
    &lt;div class=&quot;list&quot;&gt;
      
        &lt;div&gt;Free Download for &lt;br /&gt;iPhone, iPad and Mac&lt;/div&gt;
        &lt;img class=&quot;a-button&quot; src=&quot;/images/Download_on_the_App_Store_Badge_US-UK_RGB_blk_092917.svg&quot; alt=&quot;Download on the App Store&quot; /&gt;
      
        
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/section&gt;
</description>
        <pubDate>Thu, 30 May 2024 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/flyleaf-apptisan/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/flyleaf-apptisan/</guid>
        
        
        <category>Flyleaf</category>
        
        <category>Technologie</category>
        
        <category>en</category>
        
      </item>
    
      
      <item>
        <title>Flyleaf Update 1.1</title>
        <description>&lt;p&gt;The 1.1 update of my &lt;a href=&quot;/project/flyleaf/&quot;&gt;read-later app Flyleaf&lt;/a&gt; is now live on the &lt;a href=&quot;https://apps.apple.com/app/flyleaf-read-later/id6475200381&quot;&gt;iOS and macOS AppStore&lt;/a&gt;. It includes some nice quality-of-life improvements, so make sure to grab it!&lt;/p&gt;

&lt;h3 id=&quot;new-stuff&quot;&gt;New Stuff&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Add PDFs to parse the contents and show them in the Flyleaf reading view&lt;/li&gt;
  &lt;li&gt;An “unread article count” badge – if you are into that sort of thing&lt;/li&gt;
  &lt;li&gt;Drag-and-drop support&lt;/li&gt;
  &lt;li&gt;A new “red” theme&lt;/li&gt;
  &lt;li&gt;Bug fixes and performance improvements (of course!)&lt;/li&gt;
&lt;/ul&gt;

&lt;style&gt;
  .flyleaf-download {
    display: flex;
    justify-content: center;
    margin: 2rem auto;
  }

  .flyleaf-download a {
    text-align: center;
    display: flex;
    justify-content: center;
    gap: 1em;
    border: none;
    align-items: center;
    text-align: left;
    font-size: 1.5rem;
    line-height: 1.2;
    transition: transform .2s;
  }
  .flyleaf-download a:hover {
    transform: scale(1.03);
  } 
  .flyleaf-download img {
    flex-grow: 0;
    width: auto;
    margin-left: 0 !important;
    margin-right: 0 !important;
  }
  .flyleaf-download .list {
    display: flex;
    flex-direction: column;
    font-size: 0.8em;
    align-items: flex-start;
    gap: 0.5rem;
  }
  .flyleaf-download a,
  .flyleaf-download a:hover,
  .flyleaf-download a:active,
  .flyleaf-download a:visited {
    border: none;
  }
  .flyleaf-download a:hover {
    border: none;
  }
&lt;/style&gt;

&lt;section class=&quot;flyleaf-download&quot;&gt;
  &lt;a href=&quot;https://apps.apple.com/app/flyleaf-read-later/id6475200381&quot;&gt;
    &lt;img src=&quot;/images/projects/flyleaf-mac-icon-small.png&quot; height=&quot;125&quot; width=&quot;125&quot; class=&quot;icon&quot; /&gt;
    &lt;div class=&quot;list&quot;&gt;
      
        &lt;div&gt;Free Download for &lt;br /&gt;iPhone, iPad and Mac&lt;/div&gt;
        &lt;img class=&quot;a-button&quot; src=&quot;/images/Download_on_the_App_Store_Badge_US-UK_RGB_blk_092917.svg&quot; alt=&quot;Download on the App Store&quot; /&gt;
      
        
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/section&gt;
</description>
        <pubDate>Thu, 09 May 2024 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/flyleaf-1-1/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/flyleaf-1-1/</guid>
        
        
        <category>Flyleaf</category>
        
        <category>Technologie</category>
        
        <category>en</category>
        
      </item>
    
      
      <item>
        <title>Creativerly: Read articles like books – with Flyleaf</title>
        <description>&lt;p&gt;Thanks to &lt;a href=&quot;https://creativerly.com/read-articles-like-a-book-with-flyleaf/&quot;&gt;Philipp Temmel at &lt;em&gt;creativerly&lt;/em&gt;&lt;/a&gt; for writing up this thorough deep-dive on &lt;a href=&quot;/project/flyleaf/&quot;&gt;my new app Flyleaf&lt;/a&gt;. It’s a very generous summary of the feature set of the initial version of Flyleaf:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Flyleaf is a fully native read-it-later app for iPhone, iPad, and macOS, that gives you the possibility to sync your articles across all your devices through iCloud, features a lovely design and great typography with loads of customization options, does not need an account, and there are no ads or tracking involved.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;No matter if you are reading on your iPhone, iPad, or Mac, the pagination interaction in combination with a lovely interface makes Flyleaf an incredible beautiful read-it-later app.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
        <pubDate>Tue, 09 Apr 2024 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/read-articles-like-books-with-flyleaf/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/read-articles-like-books-with-flyleaf/</guid>
        
        
        <category>Technologie</category>
        
        <category>Flyleaf</category>
        
        <category>en</category>
        
      </item>
    
      
      <item>
        <title>MacGeneration: Une nouvelle app de lecture différée affichant les articles en colonnes</title>
        <description>&lt;p&gt;I was very happy to learn hat the first media appearance of my new app &lt;a href=&quot;/project/flyleaf/&quot;&gt;Flyleaf&lt;/a&gt; was in the french publication &lt;a href=&quot;https://www.macg.co/logiciels/2024/03/flyleaf-une-nouvelle-app-de-lecture-differee-affichant-les-articles-en-colonnes-142949&quot;&gt;MacGeneration&lt;/a&gt;, in a short review by Félix Cattafesta.&lt;/p&gt;

&lt;p&gt;I appreciate that it’s an honest review which also points out some issues. But at the same time they also understood what makes Flyleaf special:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;This first version of Flyleaf is nice, but a little buggy on macOS: I had problems displaying images forcing me to resize my window, or even a few crashes. The interface has not yet been translated into French. This is only V1, and we can imagine that things will improve later. The app seemed more stable to me on iOS, and is very pleasant to use on a touch screen.&lt;/p&gt;

  &lt;p&gt;While there’s still plenty of room for improvement, Flyleaf is an app to try if you’re looking to replace Pocket. It has the advantage of being native and supporting shortcuts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(My french knowledge is very rudimentary, so the above excerpt was machine-translated.)&lt;/p&gt;
</description>
        <pubDate>Tue, 09 Apr 2024 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/flyleaf-une-nouvelle-app-de-lecture-macgeneration/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/flyleaf-une-nouvelle-app-de-lecture-macgeneration/</guid>
        
        
        <category>Technologie</category>
        
        <category>Flyleaf</category>
        
        <category>en</category>
        
      </item>
    
      
      <item>
        <title>Why I built my own read-later app</title>
        <description>&lt;p&gt;The first iOS device I ever owned was an iPod touch, 2. Generation. I absolutely loved that thing.&lt;/p&gt;

&lt;p&gt;The first ever app I remember buying with it was “Instapaper” by indie developer &lt;a href=&quot;https://marco.org/about&quot;&gt;Marco Arment&lt;/a&gt;. Instapaper was an app for saving interesting web pages to read later when offline. Even back then, I loved to read articles and blog posts by interesting people. And since the iPod touch did not have any cell connection, offline access was vital.&lt;/p&gt;

&lt;figure&gt;
  &lt;img src=&quot;/images/instapaper-4-macstories.jpeg&quot; alt=&quot;Instapaper 4.0 screenshot from 2011&quot; /&gt;
  &lt;figcaption&gt;Instapaper 4.0 screenshot from 2011 from &lt;a href=&quot;https://www.macstories.net/news/instapaper-4-0-available-completely-redesigned-ipad-ui-new-features-search-subscription/&quot;&gt;this MacStories review&lt;/a&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;!-- Instapaper also had a very nice minimalistic reading view, which was also important since most websites were not very readable on a tiny 3.5 inch screen. --&gt;

&lt;!--  Today, using such an app is less about offline access, since mobile internet today is ubiquitous and fast. Today they more about avoiding ads and popups and generally user-hostile web design. --&gt;

&lt;p&gt;The one big issue I had with Instapaper was that it had no macOS version. Instapaper was only available on iPhone, iPad and as a website. The website was okay, but it lacked the feature I liked the most about Instapaper: In the iOS app, you could choose to read your articles not as a vertically scrolling page of text, but instead as &lt;strong&gt;a horizontally aligned set of pages, like an ebook&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A couple of years ago, finally, &lt;a href=&quot;https://blog.instapaper.com/post/634511169876557824&quot;&gt;Instapaper for macOS&lt;/a&gt; was announced. But it turned out to be just a relatively shoddy port lacking many features, especially the book-like pagination.&lt;/p&gt;

&lt;h2 id=&quot;scratching-the-itch-myself&quot;&gt;Scratching the itch myself&lt;/h2&gt;

&lt;p&gt;I was and still am convinced that pagination is superior to vertical scrolling for reading longer text on a screen. It must have been around that time that I decided that I would have to scratch that particular itch myself.&lt;/p&gt;

&lt;p&gt;I had been playing around with column based web layouts for some time. I build &lt;a href=&quot;https://eulemagazin.de/happy-birthday-digitaldenkschrift/&quot;&gt;an experimental column layout for “Die Eule”&lt;/a&gt;, an online magazine I co-founded in 2017.&lt;/p&gt;

&lt;p&gt;Later, I experimented with building a JavaScript plugin that turns any website into a horizontally paginated view. That’s where I began to solve some of the technical problems of splitting text into multiple pages. How to detect that a page is “full”? What to do about changing viewport sizes? How to avoid overflows from unexpected or dynamic page contents?&lt;/p&gt;

&lt;p&gt;In early 2023, I temporarily put this plugin into action here on my blog. But I was still not satisfied. After all, I didn’t want to read my own blog, I wanted to read other people’s stuff.&lt;/p&gt;

&lt;p&gt;So, in June 2023, motivated by the recent WWDC, I started writing the first lines of SwiftUI under the code name “PageReader” which over the following months turned into a fully featured app called &lt;a href=&quot;/project/flyleaf/&quot;&gt;Flyleaf&lt;/a&gt;. I adapted the JavaScript logic developed for my blog to power the article pagination in the app.&lt;/p&gt;

&lt;video width=&quot;518&quot; height=&quot;360&quot; class=&quot;ipad&quot; style=&quot;margin: 2rem auto;&quot; controls=&quot;&quot; autoplay=&quot;&quot; loop=&quot;&quot;&gt;
    &lt;source src=&quot;/images/projects/flyleaf-ipad-pagination-small.mp4&quot; type=&quot;video/mp4&quot; /&gt;
    Video not available
&lt;/video&gt;

&lt;p&gt;&lt;strong&gt;Today, I am incredibly happy to announce that Flyleaf is now available as a 1.0 that you can download right now:&lt;/strong&gt;&lt;/p&gt;

&lt;style&gt;
  .flyleaf-download {
    display: flex;
    justify-content: center;
    margin: 2rem auto;
  }

  .flyleaf-download a {
    text-align: center;
    display: flex;
    justify-content: center;
    gap: 1em;
    border: none;
    align-items: center;
    text-align: left;
    font-size: 1.5rem;
    line-height: 1.2;
    transition: transform .2s;
  }
  .flyleaf-download a:hover {
    transform: scale(1.03);
  } 
  .flyleaf-download img {
    flex-grow: 0;
    width: auto;
    margin-left: 0 !important;
    margin-right: 0 !important;
  }
  .flyleaf-download .list {
    display: flex;
    flex-direction: column;
    font-size: 0.8em;
    align-items: flex-start;
    gap: 0.5rem;
  }
  .flyleaf-download a,
  .flyleaf-download a:hover,
  .flyleaf-download a:active,
  .flyleaf-download a:visited {
    border: none;
  }
  .flyleaf-download a:hover {
    border: none;
  }
&lt;/style&gt;

&lt;section class=&quot;flyleaf-download&quot;&gt;
  &lt;a href=&quot;https://apps.apple.com/app/flyleaf-read-later/id6475200381&quot;&gt;
    &lt;img src=&quot;/images/projects/flyleaf-mac-icon-small.png&quot; height=&quot;125&quot; width=&quot;125&quot; class=&quot;icon&quot; /&gt;
    &lt;div class=&quot;list&quot;&gt;
      
        &lt;div&gt;Free Download for &lt;br /&gt;iPhone, iPad and Mac&lt;/div&gt;
        &lt;img class=&quot;a-button&quot; src=&quot;/images/Download_on_the_App_Store_Badge_US-UK_RGB_blk_092917.svg&quot; alt=&quot;Download on the App Store&quot; /&gt;
      
        
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/section&gt;

&lt;p&gt;Flyleaf has – in my opinion – the &lt;strong&gt;best horizontal page scrolling&lt;/strong&gt; of any read-later app that I know of. And it has all the other bells and whistles you would expect from an app in 2024: &lt;strong&gt;macOS and iOS&lt;/strong&gt; versions that &lt;strong&gt;sync via iCloud&lt;/strong&gt;, beautiful and &lt;strong&gt;customizable design and typography&lt;/strong&gt;, tools for sorting, searching and &lt;strong&gt;organizing your articles&lt;/strong&gt;, and much more.&lt;/p&gt;

&lt;p&gt;I’m not yet sure if anyone else will care about this as much as I do. But Flyleaf has been my favorite read-later app since the first prototype.&lt;/p&gt;

&lt;p&gt;If you, too, like this idea and would like to support the future development of Flyleaf, here is what you can do:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://apps.apple.com/app/flyleaf-read-later/id6475200381&quot;&gt;Download Flyleaf from the App Store&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://apps.apple.com/app/flyleaf-read-later/id6475200381?action=write-review&quot;&gt;Post a (nice) review on the store page&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Tell your friends about Flyleaf&lt;/li&gt;
  &lt;li&gt;Consider becoming a Flyleaf subscriber&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thanks for reading, and keep on reading!&lt;/p&gt;
</description>
        <pubDate>Wed, 27 Mar 2024 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/about-flyleaf/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/about-flyleaf/</guid>
        
        
        <category>en</category>
        
      </item>
    
      
      <item>
        <title>Introducing Flyleaf, a &quot;read later&quot; app for iOS and macOS</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://moehrenzahn.de/project/flyleaf/&quot;&gt;&lt;img alt=&quot;Flyleaf macOS icon&quot; src=&quot;/images/projects/flyleaf-mac-icon-small.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I built a new app. I’s called Flyleaf, and it’s a “read later” app for iPhone, iPad and macOS. You can learn more on the &lt;a href=&quot;https://moehrenzahn.de/project/flyleaf&quot;&gt;Flyleaf website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The app is currently in open beta and I would love for you to check it out and give me feedback. The reception to the beta has been more than great, lots of people &lt;a href=&quot;https://mastodon.social/@maxmelzer/111693068487751097&quot;&gt;over on Mastodon&lt;/a&gt; have said some very nice things about the app.&lt;/p&gt;

&lt;p&gt;I’m excited to continue development and get the app into the App Store later this year.&lt;/p&gt;
</description>
        <pubDate>Sat, 06 Jan 2024 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/flyleaf-beta/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/flyleaf-beta/</guid>
        
        
        <category>Technologie</category>
        
        <category>Flyleaf</category>
        
        <category>en</category>
        
      </item>
    
      
      <item>
        <title>Saint-Roman-de-Malegarde #2</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2023-10-01-saint-roman-de-malegarde-2.jpg&quot;&gt; &lt;p&gt;Noch ein Gemälde der Abendstimmung im französischen Dörfchen Saint-Roman-de-Malegarde.&lt;/p&gt;

&lt;p&gt;Ich habe dieses Bild vor Ort &lt;em&gt;en plein air&lt;/em&gt; begonnen, aber ich musste zu Hause noch einige Anpassungen vornehmen, damit es vorzeigbar wird.&lt;/p&gt;
</description>
        <pubDate>Fri, 29 Sep 2023 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2023-09-29-saint-roman-de-malegarde-2/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2023-09-29-saint-roman-de-malegarde-2/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acrylics on canvas board, 30×40cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>An der Eygues</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2023-09-09-an-der-eygues.jpg&quot;&gt; &lt;p&gt;Dieses Bild habe ich “en plein air” vor Ort in Saint-Roman-de-Malegarde, Frankreich gemalt, während ich im Fluss meine Füße kühlte.&lt;/p&gt;
</description>
        <pubDate>Sat, 26 Aug 2023 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2023-08-26-an-der-eygues/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2023-08-26-an-der-eygues/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acrylics on canvas board, 40×30cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>Karl-Heine-Kanal #1</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2023-07-28-karl-heine-kanal-1.jpg&quot;&gt; &lt;p&gt;Die Vorlage für dieses Bild habe ich am Karl-Heine-Kanal in Leipzig-Neulindenau aufgenommen. Eine sehr hübsche Ecke.&lt;/p&gt;
</description>
        <pubDate>Thu, 06 Jul 2023 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2023-07-06-karl-heine-kanal-1/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2023-07-06-karl-heine-kanal-1/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acrylics on canvas board, 30×40cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>Saint-Roman-de-Malegarde #1</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2023-06-30-saint-roman-de-malegarde-1.jpg&quot;&gt; 
</description>
        <pubDate>Fri, 30 Jun 2023 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2023-06-30-saint-roman-de-malegarde-1/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2023-06-30-saint-roman-de-malegarde-1/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acrylics on canvas board, 40×30cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>Fabienne</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2023-05-20-fabienne.jpg&quot;&gt; &lt;p&gt;Ein Portrait der Figur “Fabienne”, gespielt von &lt;a href=&quot;https://de.wikipedia.org/wiki/Maria_de_Medeiros&quot;&gt;Maria de Medeiros&lt;/a&gt; im Filmklassiker &lt;a href=&quot;https://de.wikipedia.org/wiki/Pulp_Fiction&quot;&gt;Pulp Fiction&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Sat, 20 May 2023 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2023-05-20-fabienne/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2023-05-20-fabienne/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acrylics on canvas board, 40×30cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>Blumen vor der Tür</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2023-05-14-blumen-vor-der-tuer.jpg&quot;&gt; &lt;p&gt;Diese Töpfe mit Blumenpflanzen vor der Haustür fielen mir beim Vorbeigehen direkt in die nach Frühling durstenden Augen.&lt;/p&gt;

&lt;p&gt;Stillleben male ich zur Zeit sehr gern, weil Sie weder die Präzision eines Portraits, noch die komplizierte Anpassungsleistung von Foto zu Gemälde einer Landschaft erfordern.&lt;/p&gt;
</description>
        <pubDate>Sun, 14 May 2023 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2023-05-14-blumen-vor-der-tuer/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2023-05-14-blumen-vor-der-tuer/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acrylics on canvas board, 20×20cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>Stillleben mit Büste und Käseschuh</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2023-04-29-stillleben-mit-bueste-und-kaeseschuh.jpg&quot;&gt; &lt;p&gt;Diese witzige kleine Szene habe ich auf dem Fenstersims bei Verwandten entdeckt.&lt;/p&gt;

&lt;p&gt;Es war eine interessante Herausforderung, die Büste nach Metall aussehen zu lassen. Aber der wahre Protagonist dieses Gemäldes ist natürlich dieser fantastische Käseschuh.&lt;/p&gt;
</description>
        <pubDate>Sat, 29 Apr 2023 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2023-04-29-stillleben-mit-b%C3%BCste-und-k%C3%A4seschuh/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2023-04-29-stillleben-mit-b%C3%BCste-und-k%C3%A4seschuh/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acrylics on canvas board, 30×30cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>JavaLand-Vortrag: Level up your code</title>
        <description>&lt;p&gt;Durch eine verrückte Verkettung von Ereignissen arbeite ich seit einiger Zeit als Java-Entwickler. Dank meines Arbeitgebers konnte ich schon letztes Jahr &lt;a href=&quot;https://www.qfs.de/blog/article/javaland-2022.html&quot;&gt;die JavaLand besuchen&lt;/a&gt;, eine der größten Java-Entwicklerkonferenzen Europas.&lt;/p&gt;

&lt;p&gt;Dieses Jahr bot sich mir die Gelegenheit, auf der JavaLand einen Vortrag zu halten. Also hab ich das gemacht.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/javaland2023-vortrag.png&quot; alt=&quot;Max hält in einem gut gefüllten Saal einen Vortrag auf der Entwicklerkonferenz JavaLand&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Es folgt eine etwas gestraffte Textfassung dieses Vortrags.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;level-up-your-code--oop-designtechniken-nicht-nur-für-quereinsteiger&quot;&gt;Level Up Your Code – OOP-Designtechniken (nicht nur) für Quereinsteiger&lt;/h2&gt;

&lt;p&gt;Hallo zusammen,&lt;/p&gt;

&lt;p&gt;Mein Name ist Max. Ich programmiere jetzt seit 12 Jahren, etwa die Hälfte davon hauptberuflich. Angefangen habe ich mit PHP und JavaScript, dann TypeScript, Swift, Ruby, und aktuell Python und Java.&lt;/p&gt;

&lt;p&gt;Ich möchte heute über Designtechniken der objektorientierten Programmierung sprechen. Ich denke, als Quereinsteiger habe ich einen ganz interessanten Zugang zu diesem Thema.&lt;/p&gt;

&lt;p&gt;Wer von von euch hat an der Universität was mit Informatik studiert, meldet euch mal!&lt;/p&gt;

&lt;p&gt;Ich selbst habe nie was Informatisches studiert, ich bin als völliger Quereinsteiger zur Softwareentwicklung gekommen.&lt;/p&gt;

&lt;p&gt;Mir ist es am Anfang schwer gefallen, mit den Designtechniken warm zu werden. Ich habe nicht verstanden, was das mir im echten Leben da draußen helfen soll. Und ich habe auch niemanden gefunden, der mir das so erklären konnte dass ich etwas damit hätte anfangen können. Ich erinnere mich noch deutlich, wie mich damals gebremst und auch frustriert hat.&lt;/p&gt;

&lt;p&gt;Heute möchte ich deshalb versuchen, ein paar Dinge so zu erklären, wie es mir damals geholfen hätte. Vielleicht hilft das auch dem einen oder der anderen von euch, oder ihr bekommt einen frischen Blick auf diese grundlegenden Dinge.&lt;/p&gt;

&lt;h2 id=&quot;der-plan-für-heute&quot;&gt;Der Plan für Heute&lt;/h2&gt;

&lt;p&gt;Ich werde heute zunächst einen Begriff klären, damit wir über die gleiche Sache sprechen wenn es um “Design Patterns” geht.&lt;/p&gt;

&lt;p&gt;Dann werde ich kurz von mir und meiner Programmier-Geschichte als Quereinsteiger erzählen.&lt;/p&gt;

&lt;p&gt;Als Nächstes stelle ich euch ganz kurz meine Philosophie zum “Warum” der Patterns vor.&lt;/p&gt;

&lt;p&gt;Und dann möchte ich zwei ganz unterschiedliche klassische Techniken am Beispiel vorstellen. Ich zeige euch nicht nur, wie diese Techniken ganz praktisch funktionieren, sondern erkläre sie auch aus Sicht eines Quereinsteigers. Und ich erkläre auch die entscheidenden Hintergründe und Haken, die Internet-Tutorials gerne mal auslassen.&lt;/p&gt;

&lt;p&gt;Zum Schluss bekommt ihr von mir noch ein paar warnende Worte darüber, wie diese Designtechniken nicht angewendet werden sollten, und wie Entwicklung mit Patterns aus dem Ruder laufen kann.&lt;/p&gt;

&lt;h2 id=&quot;begriffsklärung-design-patterns&quot;&gt;Begriffsklärung “Design Patterns”&lt;/h2&gt;

&lt;p&gt;Wir fangen mal mit einer kurzen Begriffserklärung an:&lt;/p&gt;

&lt;p&gt;Ich habe mir ja viel Mühe gegeben, das Wort nicht in meinem Vortragstitel zu erwähnen, aber ich nenne die “Designtechniken”, über die ich heute sprechen möchte “Design Patterns”. Ich möchte nur keine falschen Erwartungen wecken.&lt;/p&gt;

&lt;p&gt;Wer von euch denkt bei “Design Patterns” als erstes an die “Gang of Four”? Meldet euch mal!&lt;/p&gt;

&lt;p&gt;Ich werde in diesem Vortrag immer wieder von “Design Patterns” reden. Ich meine damit ausdrücklich nicht nur die “heiligen” GoF-Patterns aus diesem Buch, sondern generell Designtechniken, auch neuere oder solche, die sich mehr um Architektur als um Design drehen.&lt;/p&gt;

&lt;h2 id=&quot;meine-geschichte-mit-design-patterns&quot;&gt;Meine Geschichte mit Design Patterns&lt;/h2&gt;

&lt;p&gt;Ich habe eigentlich etwas völlig un-technisches studiert. Das einzige Computerdingens das ich konnte war, WordPress-Seiten zu installieren und zu pflegen. Aber immerhin, damit war ich unter meinen KommilitonInnen schon ein halber Zauberer und fand allerlei Projekte, an denen ich mich austoben konnte. Dort habe ich mir einige HTML-, CSS- und PHP-Grundkenntnisse angeeignet.&lt;/p&gt;

&lt;p&gt;Nach meinem Studium habe ich mich dann beinahe spaßeshalber hier und da als Web-Entwickler beworben. Und tatsächlich gab es eine kleine Bude, die mich eingestellt hat.&lt;/p&gt;

&lt;p&gt;Dort habe ich dann auch einiges an gräßlich zusammenkopiertem JavaScript geschrieben, zusätzlich noch ein bisschen wildes PHP, StackOverflow sei dank.&lt;/p&gt;

&lt;p&gt;Von Softwaredesign hatte ich überhaupt keine Ahnung, von OOP-Architektur noch viel weniger. Leider waren die meisten Tutorials dazu, die ich im Internet, fand ungefähr so:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/javaland2023-vortrag-owl.jpeg&quot; alt=&quot;How to draw an owl: 1. Draw two circles, 2. Draw the rest of the damn owl.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Ich habe also erst mal so gut wie nichts von objektorientierter Programmierung über die absoluten Basics hinaus verstanden. Ich war einfach froh, wenn durch meinen Code das gewünschte Ergebnis im Browser ankam, egal auf welchem Weg.&lt;/p&gt;

&lt;p&gt;Erst in einem späteren Job musste ich an einem super-durcharchitekturierten PHP-Framework arbeiten, das mich zur Verwendung von allerhand OOP-Patterns gezwungen hat. Da hatte ich keine andere Wahl als zu lernen was ein Singleton, ein Proxy, eine Factory, ein Interface, und dann auch was ein &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SingletonProxyFactoryInterface&lt;/code&gt; ist (und dieses Beispiel ist wirklich nur leicht übertrieben). Ich hatte zum Glück nette und erfahrenere Kollegen, die mir manche meiner Fragen geduldig beantworteten. Die pingeligen Architektur- und Designvorgaben dieses Frameworks waren zwar rückblickend manchmal wirklich übertrieben, die Vorteile haben aber die Nachteile aufgewogen – ich habe “ordentlich” Programmieren gelernt – auf die harte Tour. Das ich von diesem Framework “Design Patterns” gelernt habe, habe ich erst viel später begriffen, als mir einige dieser Konzepte in anderen Anwendungen wieder begegnet sind.&lt;/p&gt;

&lt;p&gt;Und erst dann hat mir ein Kollege von “Design Patterns”, dem GoF-Buch, erzählt, und dann ist mir erst klar geworden, dass ich aus Versehen nicht nur &lt;em&gt;ein bestimmtes&lt;/em&gt; Framework gelernt hatte, sondern weil die sich dort so treu an bekannten Design Patterns orientiert hatten, habe ich allerhand Patterns gelernt, die mir seit dem in meiner Karrierere wieder und wieder begegnet sind.&lt;/p&gt;

&lt;h2 id=&quot;patterns&quot;&gt;Patterns&lt;/h2&gt;

&lt;p&gt;Um (Framework-)Code zu lesen ist es wahnsinnig nützlich, wenn man Patterns kennt und &lt;em&gt;er&lt;/em&gt;kennt, denn dann kann man viel Code-Verständnis abkürzen. Wenn ich eine Klasse mit “Proxy”, “Visitor” oder “Composite” im Namen sehe, habe ich sofort eine Vorstellung, wie die Klasse funktioniert und verwendet wird, ohne gleich die komplette Implementierung der Klasse verstehen zu müssen.&lt;/p&gt;

&lt;p&gt;Dank des großen Einfluss des GoF-Buchs “Design Patterns” haben viele Patterns weit verbreitete Namen, die sich oft in Klassennamen und Code-Kommentaren wiederfinden, so kann man sehr gut auf den ersten Blick erkennen, dass eine Anwendung ein Standard-Pattern verwendet.&lt;/p&gt;

&lt;p&gt;Auch wenn Patterns ihre eigene Komplexität mit sich bringen: Nicht selten spart man eben doch Zeit und Kopfzerbrechen, wenn man ein Pattern anwendet. Dann ist es hilfreich, wenn man weiß was geht.&lt;/p&gt;

&lt;h2 id=&quot;praktischer-exkurs&quot;&gt;Praktischer Exkurs&lt;/h2&gt;

&lt;p&gt;Ich habe für heute zwei der Design Patterns, oder “Designtechniken”, mitgebracht. Die Auswahl scheint vielleicht willkürlich, ist aber pragmatisch: Es sind Techniken, die mir als Quereinsteiger Schwierigkeiten gemacht haben, weil ich sie missverstanden habe, oder sie einfach schlecht erklärt waren. Hoffentlich kriege ich das hier heute besser hin.&lt;/p&gt;

&lt;p&gt;Los geht’s!&lt;/p&gt;

&lt;h3 id=&quot;composition-over-inheritance-delegate-pattern&quot;&gt;Composition over Inheritance (Delegate Pattern)&lt;/h3&gt;

&lt;p&gt;Die erste Designtechnik ist eine fast schon zum Allgemeinplatz gewordene Faustregel: &lt;em&gt;Composition over Inheritance&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Ich habe im Informatikunterricht noch gelernt, dass “Inheritance”, also Vererbung, das tollste Feature der Objektorientierten Programmierung überhaupt ist: Hund erbt von Tier, PKW erbt von Fahrzeug, und so weiter.&lt;/p&gt;

&lt;p&gt;Von Composition wurde uns damals, soweit ich mich erinnern kann, gar nichts erzählt.&lt;/p&gt;

&lt;p&gt;Wenn man sich moderne Tutorials zu “Composition over Inheritance” anschaut, bekommt man schon ein etwas nuancierteres Bild geliefert:&lt;/p&gt;

&lt;p&gt;Da bekommt man oft beigebracht, dass Inheritance am Besten für “is-a”, also “Seins-Verhältnisse” geeignet ist, und Composition für “has-a”, also “Besitzverhältnisse”.&lt;/p&gt;

&lt;p&gt;So soll ich also entscheiden, was für mein Projekt oder meine Objekt-Domäne das richtige Muster ist.&lt;/p&gt;

&lt;p&gt;Stellen wir uns also vor, wir arbeiten an einer wirklich niedlichen Anwendung, und haben den sprichwörtlichen Hund.&lt;/p&gt;

&lt;p&gt;Da greifen wir natürlich zu Vererbung, den was soll man naheliegenderes über einen Hund sagen, als das er ein “Tier” ist.&lt;/p&gt;

&lt;p&gt;Und dieses Muster können wir dann fortführen.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;eat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{...}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Dog&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bark&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{...}&lt;/span&gt; 
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Cat&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Animal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;meow&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{...}&lt;/span&gt; 
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Auch wenn unsere Anwendung erweitert wird und niedliche Roboter dazukommen sollen, leistet unser Vererbungskonzept uns gute Dienste.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Robot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;charge&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{...}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;C3P0&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Robot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{...}&lt;/span&gt; 
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Und selbst wenn wir schlussendlich auch eine Kategorie nicht so niedlicher Roboter einführen, bleibt unsere Objektstruktur hübsch übersichtlich und nachvollziehbar.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;KillerRobot&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Robot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;kill&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{...}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;T1000&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;KillerRobot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; 
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;melt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{...}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Aber das echte Leben ist oft doch komplizierter, und gerade im Detail fallen derartige Kategorien auch schnell auf die Nase.&lt;/p&gt;

&lt;p&gt;Jetzt stellen wir uns mal vor unser Projektmanager kommt vorbei und sagt: “Einer unserer besten Kunden ist old-school Doctor-Who-Fan und verlangt nach einem Roboterhund!”&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;K9RobotDog&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;???&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bark&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{???}&lt;/span&gt; 
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;charge&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{???}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Wir könnten diesen Roboterhund zwar einfach als &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Animal&lt;/code&gt; &lt;em&gt;oder&lt;/em&gt; als &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Robot&lt;/code&gt; abbilden und Methoden entsprechend duplizieren, überschreiben oder ignorieren. Aber damit würden wir jeweils zahlreiche Regeln des guten Code-Geschmacks verletzen. Jedenfalls wäre unsere wunderbar nachvollziehbare Objektstruktur dahin.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Hätte ich das nur vorher gewusst.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Die kollektive Erfahrung aus Jahrzehnten Software-Entwicklung hat gezeigt, dass &lt;em&gt;in der Regel&lt;/em&gt; Composition die nachhaltigere Wahl ist als Inheritance: Also: Objekte “sind” nicht etwas, sondern sie “haben” etwas.&lt;/p&gt;

&lt;p&gt;Aber was sollen wir tun, unser K9 &lt;em&gt;ist&lt;/em&gt; nun mal ein Roboter, und &lt;em&gt;ist&lt;/em&gt; nun mal ein Hund?!&lt;/p&gt;

&lt;p&gt;Nun, um Composition zu verwenden, muss man manchmal Dinge, die man vorher als Seins-Verhältnisse visualisiert hat, etwas kreativ umbiegen:&lt;/p&gt;

&lt;p&gt;Wie in diesem Beispiel. Hier haben wir die Abhängigkeit mit den Seins-Kategorien “Tier” und “Roboter” durch Eigenschaften ersetzt:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;K9RobotDog&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Barking&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Chargeable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BarkingProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;barker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ChargingProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;charger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;K9RobotDog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;barker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BarkingProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;charger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ChargingProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bark&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;barker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bark&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;charge&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;charger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;charge&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Barking&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bark&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Chargeable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;charge&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Das Wichtigste sind hier die Interfaces, die diese Eigenschaften repräsentieren: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Barking&lt;/code&gt; und &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Chargeable&lt;/code&gt;. Ohne die würde uns der &lt;em&gt;Polymorphismus&lt;/em&gt; verloren gehen, also die Fähigkeit, in einer Methode z.B. verschiedene bellende Objekte entgegenzunehmen.&lt;/p&gt;

&lt;p&gt;Das muss natürlich für alle unsere Objekte gemacht werden, oder ich muss zumindest überall die &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Barking&lt;/code&gt; und &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Chargeable&lt;/code&gt;-Interfaces implementieren. Wenn man vermutet, dass eine Objektstruktur über ein absolutes Minimum hinaus kompliziert wird, sollte man sich von Anfang an überlegen, Composition statt Inheritance zu benutzen.&lt;/p&gt;

&lt;p&gt;Hierfür haben wir übrigens “aus versehen” ein weiteres klassisches &lt;em&gt;Design Pattern&lt;/em&gt; benutzt, nämlich das “Delegate” Pattern. Der RobotDog “delegiert” seine Funktionalität an verschiedene Provider (statt an eine oder mehrere Parent-Klassen).&lt;/p&gt;

&lt;p&gt;Mit diesem praktischen Pattern lässt sich so ziemlich alles, was Vererbung kann, auch über Composition lösen.&lt;/p&gt;

&lt;h3 id=&quot;dependency-injection-service-container-pattern&quot;&gt;Dependency Injection (Service Container Pattern)&lt;/h3&gt;

&lt;p&gt;Als zweites möchte ich über “Dependency Injection” sprechen. Da geht es darum, dass man einer Klasse sämtliche anderen Klassen, die sie benutzt über den Konstruktor (oder auch anders) injiziert, statt Sie wie bei &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;this.charger = new ChargingProvider()&lt;/code&gt; direkt zu instanzieren oder gar &lt;em&gt;schauder&lt;/em&gt; Singletons zu nutzen, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ChargingProvider.instance()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Wenn man im Internet nach Tutorials für Dependency Injection sucht, findet man oft solche Beispiele:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;K9RobotDog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;BarkingProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;barker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;ChargingProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;charger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;K9RobotDog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BarkingProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;barker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ChargingProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;charger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;barker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;barker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;charger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;charger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;doStuff&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;barker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bark&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;charger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;charge&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DiExample&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;K9RobotDog&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;K9RobotDog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BarkingProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ChargingProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PowerProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()));&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bark&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;charge&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Manchmal findet sich auch dieses gleiche Beispiel, aber alles wird mit ein paar &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Injector&lt;/code&gt; und &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Consumer&lt;/code&gt;-Klassen noch ein bisschen komplizierter gemacht, aber das Grundprinzip ist immer das gleiche.&lt;/p&gt;

&lt;p&gt;Das hat zahlreiche Vorteile:&lt;/p&gt;

&lt;p&gt;Abhängigkeiten können je nach Situation ausgetauscht werden&lt;/p&gt;

&lt;p&gt;Eine Klasse kann ein Interface als Abhängigkeit angeben, was noch mehr Flexibilität bringt.&lt;/p&gt;

&lt;p&gt;Wie oft hat man das Problem, dass man um ein Model zu testen eigentlich die ganze Anwendung hochfahren müsste, weil man eine Konfiguration, Datenbank, und Verbindungen zu externen Schnittstellen braucht?&lt;/p&gt;

&lt;p&gt;Mittels DI kann man zum Testen der Klasse Dummy-Abhängigkeiten oder sogar Mock-Abhängigkeiten reingeben, und so die Klasse für sich Testen.
Es bringt aber auch einfach eine große Übersichtlichkeit, wenn alle Abhängigkeiten einer Klasse klar aufgelistet sind.&lt;/p&gt;

&lt;p&gt;Ich als unbedarfter Quereinsteiger habe mich bei diesen Beispielen immer gefragt, was das soll. Ich habe zwar meine Service-Klasse hübsch aufgeräumt, das sehe ich schon ein. Aber jetzt muss sich eine Klasse darüber um die Instanzierung des Objekts kümmern. Und irgendwann muss ja jemand mal &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new BarkingProvider()&lt;/code&gt; machen, also was soll dieses Pattern?&lt;/p&gt;

&lt;p&gt;Für mich hat es erst “Klick” gemacht, als ich den folgenden Trick kennengelernt habe, mit dem man die Objektinstanzierung weg-abstrahieren kann.&lt;/p&gt;

&lt;p&gt;Mich hat dieses Pattern so fasziniert, dass ich es mal nur für mich als Prototyp nachgebaut habe. Das hat mir sehr geholfen, das Prinzip dahinter zu verstehen und ein bisschen Framework-“Magie” zu entmystifizieren.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;java.lang.reflect.Constructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;java.util.Arrays&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DiExample&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;ServiceContainer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;serviceContainer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ServiceContainer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;K9RobotDog&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;serviceContainer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;createInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;K9RobotDog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;doStuff&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ServiceContainer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;classObj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Constructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;constrs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Constructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;[])&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;classObj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getConstructors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Constructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;constr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;constrs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&amp;gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argumentTypes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;constr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getParameterTypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;constr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
                    &lt;span class=&quot;nc&quot;&gt;Arrays&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argumentTypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;createInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ignored&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RuntimeException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Dieser &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ServiceContainer&lt;/code&gt; lässt sich natürlich beliebig erweitern.
Und man sollte ihn wohl auch erweitern, weil so skaliert das natürlich nicht. Unser Beispiel ist eher eine Spielerei und kein robustes Fundament für eine Anwendung.&lt;/p&gt;

&lt;p&gt;Was wir hier gebaut haben ist natürlich auch wieder ein &lt;em&gt;Design Pattern&lt;/em&gt;. Es hat nur leider keinen knackigen Namen, weil es in GoF noch nicht vorkam. Es heißt mal “Container”, mal “Assembler”, mal “Manager, und so weiter.&lt;/p&gt;

&lt;p&gt;15 Jahre nach erscheinen des “Design Patterns”-Buchs hat Erich Gamma mal &lt;a href=&quot;https://www.informit.com/articles/article.aspx?p=1404056&quot;&gt;in einem Interview&lt;/a&gt; gemeint, dass er heute Dependency Injection als Pattern mit aufnehmen würde. Dann hätten wir vielleicht auch einen einheitlichen Namen für dieses Sub-Pattern. Aber was soll’s.&lt;/p&gt;

&lt;p&gt;Wie jedes Pattern haben wir auch hier nicht nur Vorteile, sondern auch ein paar Nachteile und Fallstricke:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Performance kann zum Problem werden&lt;/li&gt;
  &lt;li&gt;Debugging nervt&lt;/li&gt;
  &lt;li&gt;IDE nicht mehr so hilfreich&lt;/li&gt;
  &lt;li&gt;Kann unübersichtlich werden&lt;/li&gt;
  &lt;li&gt;Macht erst richtig Spaß, wenn eine ganze Anwendung oder Modul darauf aufbaut&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ihr sollt oder müsst also beim besten Willen nicht überall Service Container verwenden. Ich wollte euch diesen super-simplen Service Container vorführen, weil er mir eine “Aha”-Erlebnis gebracht hat und mir gezeigt hat, wie mächtig Dependency Injection sein kann, wenn man ein bisschen kreativ rangeht.&lt;/p&gt;

&lt;p&gt;Man muss auch das Rad aber trotzdem nicht neu erfinden! Es gibt natürlich Frameworks, die sich Dependency Injection auf die Fahne geschrieben haben und sowas wie unseren Service Container mitbringen, nur unendlich raffinierter, sicherer, und vor allem performanter: &lt;a href=&quot;https://spring.io&quot;&gt;Spring&lt;/a&gt; ist ziemlich bekannt und hat eine DI-Framework-Komponente, es gibt noch die neueren Projekte &lt;a href=&quot;https://github.com/google/guice&quot;&gt;Guice&lt;/a&gt; und &lt;a href=&quot;https://dagger.dev&quot;&gt;Dagger&lt;/a&gt;. Aber das sei nur am Rande erwähnt, wenn euch das interessiert sind das eure Stichworte für weitere Recherche.&lt;/p&gt;

&lt;h2 id=&quot;warnungen--wie-patterns-nicht-benutzt-werden-sollten&quot;&gt;Warnungen – Wie Patterns nicht benutzt werden sollten&lt;/h2&gt;

&lt;p&gt;Jetzt haben wir einige Patterns in Aktion gesehen, und ich habe viele nette Dinge über Patterns gesagt und euch ermutigt, sie zu erkennen und anzuwenden. Aber zum Schluss möchte ich doch die Begeisterung wieder etwas dämpfen.&lt;/p&gt;

&lt;p&gt;Design Patterns sind ein Werkzeug. Damit kann man fantastische Sachen machen. Aber kein Werkzeug ist für alle Fälle geeignet.&lt;/p&gt;

&lt;p&gt;Eine gute Software-Architektur ist immer die für das Projekt passende Architektur, nicht die mit den meisten Patterns, der größten Flexibilität oder gar dem cleversten Code.&lt;/p&gt;

&lt;p&gt;Denn wie &lt;a href=&quot;https://www.goodreads.com/quotes/273375-everyone-knows-that-debugging-is-twice-as-hard-as-writing&quot;&gt;Brian Kernighan gesagt hat&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Everyone knows that debugging is twice as hard as writing a program in the first place. So if you’re as clever as you can be when you write it, how will you ever debug it?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bevor ihr ein Pattern einsetzt und euren Code damit mehrschichtiger und komplizierter macht, stellt euch ein paar Fragen:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Arbeite ich an einem Langfristig angelegten Produkt oder Framework oder baue ich eine Landing-page für ein Startup?&lt;/li&gt;
  &lt;li&gt;Verbessere ich damit wirklich mein Design oder spare ich nur Zeilen? Einfacher langer Code ist oft besser als “cleverer” kurzer Code, und trotz DRY ist nicht jede Wiederholung immer schlecht!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Diese Fragen sollte man sich auch stellen, bevor man einer Kolleg:in in einem Codereview ein “fehlendes” Pattern vorwirft!)&lt;/p&gt;

&lt;p&gt;Und wenn ihr dann immer noch ein hergebrachtes Pattern implementiert, achtet darauf, dass euer Code in etwa den (teils ungeschriebenen) Pattern-Gesetzen folgt, damit andere Entwickler sie z.B. an Klassennamen leicht wieder erkennen können.&lt;/p&gt;

&lt;p&gt;Und zu guter Letzt: Man darf auch neue Sachen erfinden, hört auf euer Bauchgefühl.&lt;/p&gt;

&lt;p&gt;So, genug geredet! Jetzt geht da raus und baut coole Sachen!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/javaland2023-vortrag.jpeg&quot; alt=&quot;Max hält in einem gut gefüllten Saal einen Vortrag auf der Entwicklerkonferenz JavaLand&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Fri, 14 Apr 2023 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/vortrag-javaland-2023/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/vortrag-javaland-2023/</guid>
        
        
        <category>Technologie</category>
        
        <category>de</category>
        
      </item>
    
      
      <item>
        <title>Denkendes Kind</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2023-03-25-denkendes-kind.jpg&quot;&gt; 
</description>
        <pubDate>Fri, 10 Mar 2023 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2023-03-10-denkendes-kind/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2023-03-10-denkendes-kind/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acrylics on canvas board, 20×20cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>Katze im Schnee (Rivo Study)</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2023-02-18-katze-im-schnee.jpg&quot;&gt; 
</description>
        <pubDate>Sun, 19 Feb 2023 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2023-02-19-katze-im-schnee/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2023-02-19-katze-im-schnee/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acrylics on canvas board, 20×20cm</category>
        
      </item>
    
      
        
      
      <item>
        <title>Red One Standing By</title>
        <description>&lt;img src=&quot;https://www.moehrenzahn.de/paintings/2023-02-18-red-one-standing-by.jpg&quot;&gt; 
</description>
        <pubDate>Sat, 18 Feb 2023 00:00:00 +0000</pubDate>
        <link>https://www.moehrenzahn.de/paintings/2023-02-18-red-one-standing-by/</link>
        <guid isPermaLink="true">https://www.moehrenzahn.de/paintings/2023-02-18-red-one-standing-by/</guid>
        
        
        <category>paintings</category>
        
        <category>de</category>
        
        <category>Acrylics on canvas board, 40×30cm</category>
        
      </item>
    
      
        
    
  </channel>
</rss>
