<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[שורת קוד]]></title><description><![CDATA[שורת קוד]]></description><link>https://thecodeline.org</link><generator>RSS for Node</generator><lastBuildDate>Tue, 16 Jun 2026 09:25:45 GMT</lastBuildDate><atom:link href="https://thecodeline.org/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><atom:link rel="first" href="https://thecodeline.org/rss.xml"/><item><title><![CDATA[מ-Context ל-AI Engineering Workflow]]></title><description><![CDATA[<h2 id="heading-mlk">;</h2>
<p>  ,       AI:       ,   ,         .</p>
<p>      -AI  Context.      <strong> </strong>.</p>
<p>   frameworks  :</p>
<p><strong>gstack</strong>  framework     slash commands -skills   AI coding agents.   -AI   , gstack     : product thinking, engineering review, design review, code review, QA, security, -shipping.         AI coding -delivery pipeline.</p>
<p><strong>Lattice</strong>  framework  composable AI skills   engineering discipline   .   -Atoms, Molecules, Guardrails, Refiners , workflows  ,     . , Lattice   <code>.lattice/</code>    -    -design, , , code reviews,   .</p>
<p>     <strong>   </strong>,     <strong>       .</strong></p>
<p> :<br />gstack  -AI    .<br />Lattice  -AI  ,  -guardrails.<br />,    -  AI -AI Engineering Workflow.</p>
<h2 id="heading-rk"></h2>
<p>  AI       :  ,  ,  review, ,  ,        -diff  1,200 .</p>
<p>   -AI   .        .            <strong>  :</strong></p>
<p>       .<br />    domain logic -infrastructure.<br /> APIs    <br />  idempotency.<br />  test  .<br />  -failure modes    .<br />   abstraction     .</p>
<p>   .        compile     -production    incident    - 02:17.</p>
<p>      :   -AI   ,     ,       .     .</p>
<p>         :  , ,  ,  ,  review,  ,    .</p>
<p>   -AI.</p>
<p> gstack -Lattice  .</p>
<h3 id="heading-mh-zh-gstack">  gstack?</h3>
<p>gstack  framework    AI coding agents,    :   -AI     ,      .  -Personas  .</p>
<p>-gstack   :</p>
<pre><code class="lang-plaintext">/office-hours
/plan-ceo-review
/plan-eng-review
/review
/qa
/ship
</code></pre>
<p>      .     .  -        .</p>
<ul>
<li><p><code>/office-hours</code>    </p>
</li>
<li><p><code>/plan-ceo-review</code>     -scope.</p>
</li>
<li><p><code>/plan-eng-review</code>   , data flow, , -test plan.</p>
</li>
<li><p><code>/review</code>     .</p>
</li>
<li><p><code>/qa</code>  .</p>
</li>
<li><p><code>/ship</code>     merge  release.</p>
</li>
</ul>
<p>, gstack       .     -AI  <strong> </strong>.</p>
<p>:</p>
<pre><code class="lang-plaintext">Prompt  Code  Review  Pain
</code></pre>
<p>    :</p>
<pre><code class="lang-plaintext">Think  Plan  Build  Review  Test  Ship  Learn
</code></pre>
<p>  .   -AI   ,     ,    artifacts,  ,        .</p>
<h3 id="heading-mh-zh-lattice">  Lattice?</h3>
<p>Lattice   ,   .</p>
<p> gstack    -AI  ?"<br />Lattice      -AI ?</p>
<p>Lattice  framework  composable AI skills.     :</p>
<ol>
<li><p><strong>Atoms</strong> - guardrails  .  - clean code, architecture, secure-coding, test-quality, design-first -context-anchoring.</p>
</li>
<li><p><strong>Molecules</strong> - workflows   Atoms . , requirement-forge, design-blueprint, code-forge, bug-fix, refactor-safely</p>
</li>
<li><p><strong>Refiners</strong> -     .  architecture standards, review standards,  requirement standards.</p>
</li>
</ol>
<p>   -Lattice        .         ,   <code>.lattice/</code>. :</p>
<pre><code class="lang-plaintext">.lattice/
 config.yaml
 standards/
    architecture.md
    clean-code.md
    secure-coding.md
    test-quality.md
    review-standards.md
 requirements/
 context/
 reviews/
 learnings/
</code></pre>
<p>  :       .   -artifact.<br />-AI      .     ,  ,  ,    .</p>
<p>Lattice     <a target="_blank" href="https://martinfowler.com/articles/reduce-friction-ai/">   Martin Fowler / Thoughtworks</a>      AI-assisted development.    patterns  Knowledge Priming, Design-First Collaboration, Context Anchoring, Encoding Team Standards -Feedback Flywheel.</p>
<p>    : AI coding assistant  , , onboarding,       .    AI,       -   .   .</p>
<p>    -PR     .</p>
<p><img loading="lazy" src="/images/posts/gstack-and-lattice/img-1.webp" class="image--center mx-auto" /></p>
<h2 id="heading-ykh-zh-vvd">  ?</h2>
<p>     gstack -Lattice,       :</p>
<ol>
<li><p><strong></strong> -  -AI   .</p>
</li>
<li><p><strong></strong> -    </p>
</li>
<li><p><strong></strong> -      .</p>
</li>
</ol>
<p>   AI   .   ,   ,   .<br />   .     .     -state  .       .     design .      .</p>
<p>gstack -Lattice      .<br />gstack  <strong></strong>.<br />Lattice  <strong>engineering memory</strong>.</p>
<p>     : refund workflow   .<br /> ,  :</p>
<pre><code class="lang-plaintext">Build a refund workflow for paid invoices.
Include validation, audit log, event publishing, and admin status view.
</code></pre>
<p>  .  ,    :</p>
<ul>
<li><p>    invoice?</p>
</li>
<li><p> refund   ?</p>
</li>
<li><p>   ?</p>
</li>
<li><p>   external payment provider  timeout?</p>
</li>
<li><p>  -queue   -transaction?</p>
</li>
<li><p>   ?</p>
</li>
<li><p>  -audit log?</p>
</li>
<li><p> -UI  projection  source of truth?</p>
</li>
<li><p> -rollback behavior</p>
</li>
<li><p> events   ?</p>
</li>
</ul>
<p>AI     .       .    , , ,  .</p>
<p> gstack  :</p>
<pre><code class="lang-plaintext">/office-hours
    
/plan-ceo-review
    
/plan-eng-review
    
build
    
/review
    
/qa
    
/ship
</code></pre>
<p>, Lattice     standards -context:</p>
<pre><code class="lang-plaintext">/requirement-forge
    
/design-blueprint
    
/code-forge
    
/review
    
learnings saved into .lattice/
</code></pre>
<p>    :<br />gstack =    ?<br />Lattice =       ?</p>
<p> , Lattice   Atoms : architecture, clean-code, secure-coding, test-quality, context-anchoring.<br /> -review, gstack   review role  bugs, scope, -production risk,  -Lattice    -standards -learnings  .</p>
<p>  workflow  -AI     .    :</p>
<pre><code class="lang-plaintext">Unclear request
    
Structured requirement
    
Approved design
    
Constrained implementation
    
Delta review
    
Behavior validation
    
Shipping summary
    
Reusable learning
</code></pre>
<p>    review .  .         .<br />  review      adapter?,     :</p>
<ul>
<li><p>  -design ?</p>
</li>
<li><p> -scope ?</p>
</li>
<li><p>   </p>
</li>
<li><p> -failure modes ?</p>
</li>
<li><p>      ?</p>
</li>
</ul>
<p>    AI       leverage .</p>
<p><img loading="lazy" src="/images/posts/gstack-and-lattice/img-2.webp" class="image--center mx-auto" /></p>
<h2 id="heading-dvgmh-myt"> </h2>
<p>   -workflow    gstack -Lattice.<br />    -TypeScript   billing.         -refund  .   HTTP API,  application, domain logic, postgreSQL, queue publishing -admin UI  refund state.</p>
<p>    -AI  refund.<br />          artifact .</p>
<h3 id="heading-lv-1-hgdrt-lattice-context"> 1:  Lattice context</h3>
<p>    -Lattice  ,     -skill : <code>/lattice-init</code>.   Lattice    ,    ,   .       .     :</p>
<pre><code class="lang-plaintext">.lattice/
 config.yaml
 standards/
    knowledge-base.md
    architecture.md
    clean-code.md
    secure-coding.md
    test-quality.md
    requirement-standards.md
    review-standards.md
 requirements/
 context/
 reviews/
 learnings/
     operational-learnings.md
</code></pre>
<p> <code>.lattice/config.yaml</code>   :</p>
<pre><code class="lang-yaml"><span class="hljs-attr">version:</span> <span class="hljs-number">1</span>

<span class="hljs-attr">paths:</span>
  <span class="hljs-attr">knowledge_base:</span> <span class="hljs-string">.lattice/standards/knowledge-base.md</span>
  <span class="hljs-attr">architecture:</span> <span class="hljs-string">.lattice/standards/architecture.md</span>
  <span class="hljs-attr">clean_code:</span> <span class="hljs-string">.lattice/standards/clean-code.md</span>
  <span class="hljs-attr">secure_coding:</span> <span class="hljs-string">.lattice/standards/secure-coding.md</span>
  <span class="hljs-attr">test_quality:</span> <span class="hljs-string">.lattice/standards/test-quality.md</span>
  <span class="hljs-attr">requirement_standards:</span> <span class="hljs-string">.lattice/standards/requirement-standards.md</span>
  <span class="hljs-attr">review_standards:</span> <span class="hljs-string">.lattice/standards/review-standards.md</span>
  <span class="hljs-attr">operational_learnings:</span> <span class="hljs-string">.lattice/learnings/operational-learnings.md</span>
</code></pre>
<p>      -refiners.    -architecture   :</p>
<pre><code class="lang-markdown">---
<span class="hljs-section">mode: overlay
---</span>

<span class="hljs-section"># Architecture Standards</span>

<span class="hljs-section">## Layering</span>

Allowed dependency direction:

<span class="hljs-bullet">-</span> <span class="hljs-code">`interfaces/http`</span>  <span class="hljs-code">`application`</span>
<span class="hljs-bullet">-</span> <span class="hljs-code">`interfaces/workers`</span>  <span class="hljs-code">`application`</span>
<span class="hljs-bullet">-</span> <span class="hljs-code">`application`</span>  <span class="hljs-code">`domain`</span>
<span class="hljs-bullet">-</span> <span class="hljs-code">`application`</span>  ports
<span class="hljs-bullet">-</span> <span class="hljs-code">`infrastructure`</span>  ports
<span class="hljs-bullet">-</span> <span class="hljs-code">`infrastructure`</span>  external SDKs

Forbidden:

<span class="hljs-bullet">-</span> <span class="hljs-code">`domain`</span> importing <span class="hljs-code">`infrastructure`</span>
<span class="hljs-bullet">-</span> HTTP controllers querying PostgreSQL directly
<span class="hljs-bullet">-</span> queue consumers duplicating business rules
<span class="hljs-bullet">-</span> application services depending directly on vendor SDKs

<span class="hljs-section">## Messaging</span>

Every queue publisher or consumer must define:

<span class="hljs-bullet">-</span> event contract
<span class="hljs-bullet">-</span> idempotency strategy
<span class="hljs-bullet">-</span> retry behavior
<span class="hljs-bullet">-</span> dead-letter behavior
<span class="hljs-bullet">-</span> observability signals
<span class="hljs-bullet">-</span> poison-message ownership

<span class="hljs-section">## External Calls</span>

Every external API call must include:

<span class="hljs-bullet">-</span> timeout
<span class="hljs-bullet">-</span> bounded retry policy
<span class="hljs-bullet">-</span> error classification
<span class="hljs-bullet">-</span> correlation id
<span class="hljs-bullet">-</span> clear fallback or fail-fast behavior

<span class="hljs-section">## Money Movement</span>

Any operation that moves, refunds, captures, reserves, or releases money must define:

<span class="hljs-bullet">-</span> authorization boundary
<span class="hljs-bullet">-</span> audit trail
<span class="hljs-bullet">-</span> idempotency key
<span class="hljs-bullet">-</span> consistency model
<span class="hljs-bullet">-</span> reconciliation strategy
</code></pre>
<p>  .    "style guide".  boundary contract.</p>
<p> AI  ,      .      -PostgreSQL  HTTP controller,  .    queue event  idempotency,  .    -refund  audit trail,  .</p>
<h3 id="heading-lv-2-ftyht-vvdh-m-gstack"> 2:    gstack</h3>
<p>  :  :</p>
<pre><code class="lang-plaintext">/office-hours

We need to add a refund workflow for paid invoices.

Goal:
Allow admins to request a full or partial refund for an already paid invoice.

Initial requirements:
- Validate invoice state.
- Prevent duplicate refunds.
- Write an audit trail.
- Publish RefundRequested event.
- Expose refund status to the admin UI.

Do not propose implementation yet.
Clarify product scope, missing assumptions, and risk areas.
</code></pre>
<p>    .   friction.    -AI   .</p>
<p>       :</p>
<pre><code class="lang-plaintext">- Are partial refunds allowed more than once?
- Who can approve a refund?
- Is refund execution synchronous or asynchronous?
- What happens if the payment provider accepts the refund but event publishing fails?
- Does the admin UI need real-time status or eventual consistency?
- What is the expected audit format?
- Are refunds reversible?
</code></pre>
<p>          ambiguity  .</p>
<h3 id="heading-lv-3-dryvt-m-lattice"> 3:   Lattice</h3>
<p>  -Lattice      :</p>
<pre><code class="lang-plaintext">/requirement-forge

Create a structured requirement for the refund workflow.

Input:
Admins can request a full or partial refund for a paid invoice.
The system must validate invoice state, prevent duplicate refunds,
write an audit trail, publish RefundRequested, and expose refund status.

Use project requirement standards.
Persist the result under .lattice/requirements/refund-workflow.md.

Explicitly include:
- business rules
- authorization rules
- state transitions
- API expectations
- event expectations
- failure modes
- open questions
</code></pre>
<p> :</p>
<pre><code class="lang-plaintext"># Refund Workflow Requirement

## Capability

Admins can request a full or partial refund for a paid invoice.

## Business Rules

- Refund can only be requested for invoices in `PAID` state.
- Total refunded amount must not exceed paid amount.
- Duplicate refund requests must be rejected or deduplicated.
- Every refund request must be auditable.
- Refund execution is asynchronous.

## State Transitions

PAID
   REFUND_REQUESTED
   REFUND_PROCESSING
   REFUNDED

PAID
   REFUND_REQUESTED
   REFUND_FAILED

## Events

- `RefundRequested`
- `RefundCompleted`
- `RefundFailed`

## Failure Modes

- Duplicate request.
- Payment provider timeout.
- Event publish failure.
- Audit write failure.
- Admin UI reads stale status.

## Open Questions

- Are multiple partial refunds allowed?
- Is approval required above a threshold?
- What is the SLA for status visibility?
</code></pre>
<p>    artifact.  .    . .</p>
<h3 id="heading-lv-4-engineering-review-m-gstack"> 4: Engineering review  gstack</h3>
<p> design ,  review .</p>
<pre><code class="lang-plaintext">/plan-eng-review

Review .lattice/requirements/refund-workflow.md.

Focus on:
- data model implications
- transaction boundaries
- event publishing guarantees
- idempotency
- race conditions
- rollback behavior
- observability
- test matrix

Do not write implementation code.
Produce engineering risks and required design decisions.
</code></pre>
<p>     :</p>
<pre><code class="lang-markdown"><span class="hljs-section"># Engineering Review Notes</span>

<span class="hljs-section">## Critical Decisions</span>

<span class="hljs-bullet">1.</span> Refund request creation and audit write must be atomic.
<span class="hljs-bullet">2.</span> Event publishing should use outbox pattern or equivalent reliability mechanism.
<span class="hljs-bullet">3.</span> Refund request must use idempotency key scoped by invoice and request source.
<span class="hljs-bullet">4.</span> Admin status should read from refund state stored internally, not directly from provider.
<span class="hljs-bullet">5.</span> Provider timeout must not imply failure; status reconciliation is required.

<span class="hljs-section">## Race Conditions</span>

<span class="hljs-bullet">-</span> Two admins request refund for same invoice simultaneously.
<span class="hljs-bullet">-</span> Provider callback arrives before local state transition completes.
<span class="hljs-bullet">-</span> Retry publishes duplicate RefundRequested event.

<span class="hljs-section">## Required Tests</span>

<span class="hljs-bullet">-</span> Full refund success.
<span class="hljs-bullet">-</span> Partial refund success.
<span class="hljs-bullet">-</span> Duplicate refund request.
<span class="hljs-bullet">-</span> Refund exceeds paid amount.
<span class="hljs-bullet">-</span> Provider timeout.
<span class="hljs-bullet">-</span> Event publish retry.
<span class="hljs-bullet">-</span> Audit trail write failure.
</code></pre>
<p>    :    ,        feature   .  <br />  -ROI  process.</p>
<h3 id="heading-lv-5-design-blueprint-m-lattice"> 5: Design Blueprint  Lattice.</h3>
<p>   -design:</p>
<pre><code class="lang-plaintext">/design-blueprint

Create a design blueprint for .lattice/requirements/refund-workflow.md.

Use:
- .lattice/standards/architecture.md
- .lattice/standards/secure-coding.md
- .lattice/learnings/operational-learnings.md
- engineering review notes from /plan-eng-review

Do not write implementation code.

The blueprint must include:
- capabilities
- components
- interactions
- contracts
- data model changes
- state machine
- failure handling
- test strategy
</code></pre>
<p> :</p>
<pre><code class="lang-markdown"><span class="hljs-section"># Refund Workflow Design Blueprint</span>

<span class="hljs-section">## Components</span>

<span class="hljs-section">### HTTP Interface</span>

<span class="hljs-code">`POST /admin/invoices/:invoiceId/refunds`</span>

Responsibilities:
<span class="hljs-bullet">-</span> Authenticate admin.
<span class="hljs-bullet">-</span> Validate request shape.
<span class="hljs-bullet">-</span> Delegate to application use-case.
<span class="hljs-bullet">-</span> Return refund request id and initial status.

Must not:
<span class="hljs-bullet">-</span> Query PostgreSQL directly.
<span class="hljs-bullet">-</span> Call payment provider directly.
<span class="hljs-bullet">-</span> Publish events directly.

<span class="hljs-section">### Application Use-Case</span>

<span class="hljs-code">`RequestRefundUseCase`</span>

Responsibilities:
<span class="hljs-bullet">-</span> Load invoice.
<span class="hljs-bullet">-</span> Validate business rules.
<span class="hljs-bullet">-</span> Create refund request.
<span class="hljs-bullet">-</span> Write audit record.
<span class="hljs-bullet">-</span> Persist outbox event.
<span class="hljs-bullet">-</span> Return refund status.

<span class="hljs-section">### Domain</span>

<span class="hljs-code">`InvoiceRefundPolicy`</span>

Responsibilities:
<span class="hljs-bullet">-</span> Validate refund eligibility.
<span class="hljs-bullet">-</span> Validate partial refund limits.
<span class="hljs-bullet">-</span> Prevent invalid state transitions.

<span class="hljs-section">### Infrastructure</span>

<span class="hljs-bullet">-</span> <span class="hljs-code">`RefundRepository`</span>
<span class="hljs-bullet">-</span> <span class="hljs-code">`AuditLogRepository`</span>
<span class="hljs-bullet">-</span> <span class="hljs-code">`OutboxRepository`</span>
<span class="hljs-bullet">-</span> <span class="hljs-code">`PaymentProviderRefundClient`</span>

<span class="hljs-section">## Consistency Model</span>

Refund request creation, audit write, and outbox event creation occur in one database transaction.

Actual provider call is asynchronous and triggered by outbox processing.

<span class="hljs-section">## Idempotency</span>

Idempotency key is required per request.
Scope:
<span class="hljs-code">`adminId + invoiceId + idempotencyKey`</span>

<span class="hljs-section">## Failure Handling</span>

<span class="hljs-bullet">-</span> Provider timeout leaves refund in <span class="hljs-code">`REFUND_PROCESSING`</span>.
<span class="hljs-bullet">-</span> Reconciliation job resolves unknown provider states.
<span class="hljs-bullet">-</span> Outbox retry is safe because event handling is idempotent.
<span class="hljs-bullet">-</span> Duplicate admin requests return existing refund request when idempotency key matches.
</code></pre>
<p>   design-first  .         .    .</p>
<h3 id="heading-lv-6-code-forge-m-lattice"> 6: Code Forge  Lattice</h3>
<p>   :</p>
<pre><code class="lang-plaintext">/code-forge

Implement the approved refund workflow design blueprint.

Use:
- .lattice/context/refund-workflow-design-blueprint.md
- .lattice/standards/architecture.md
- .lattice/standards/clean-code.md
- .lattice/standards/test-quality.md
- .lattice/standards/secure-coding.md

Rules:
- Implement only the approved design.
- Do not modify unrelated modules.
- Do not introduce new architectural patterns.
- Generate tests with the implementation.
- Stop if existing code contradicts the approved design.
</code></pre>
<p>     -"build refund workflow.<br />  -AI:</p>
<ul>
<li><p>   product discovery .</p>
</li>
<li><p>   </p>
</li>
<li><p>   refactor .</p>
</li>
<li><p>   public contracts  </p>
</li>
<li><p>  design .</p>
</li>
</ul>
<p> :    ,   .</p>
<h3 id="heading-lv-7-review-mvlv"> 7: Review </h3>
<p> ,  review  .<br /> gstack:</p>
<pre><code class="lang-plaintext">/review

Review the implementation delta.

Focus on:
- production bugs
- hidden assumptions
- scope creep
- missing tests
- incorrect error handling
- race conditions
- security issues

Classify findings by severity.
</code></pre>
<p> Lattice:</p>
<pre><code class="lang-plaintext">/review

Review the implementation against:
- .lattice/standards/architecture.md
- .lattice/standards/secure-coding.md
- .lattice/standards/test-quality.md
- .lattice/context/refund-workflow-design-blueprint.md

Persist reusable findings into:
.lattice/reviews/refund-workflow-review.md
.lattice/learnings/operational-learnings.md
</code></pre>
<p>   .<br />gstack      shipping.<br />Lattice       .</p>
<p>    :</p>
<pre><code class="lang-markdown"><span class="hljs-section"># Review Findings</span>

<span class="hljs-section">## High Severity</span>

<span class="hljs-section">### Missing idempotency enforcement in worker</span>

The HTTP layer validates idempotency key, but the worker does not enforce
deduplication when consuming RefundRequested.

Impact:
Duplicate event delivery may trigger duplicate provider calls.

Required fix:
Persist provider operation key and enforce uniqueness before calling provider.

<span class="hljs-section">## Medium Severity</span>

<span class="hljs-section">### Audit trail does not include actor role</span>

Refund audit records include admin id but not admin role.

Required fix:
Include role and permission context in audit metadata.

<span class="hljs-section">## Learning</span>

For money movement workflows, idempotency must be enforced both at request
creation and at asynchronous execution boundary.
</code></pre>
<p>-Learning   .     - <code>.lattice/learnings/operational-learnings.md</code>,      .<br />   AI     AI workflow   .</p>
<h2 id="heading-nlyzh"></h2>
<p>   gstack -Lattice       .     .<br />         -AI  .</p>
<p>     AI coding agents:     .   .   ,    .   ,    business logic    -retry.</p>
<p>  ,    .<br />  gstack -Lattice,    ,  -artifacts.</p>
<h3 id="heading-kvntkst-hv-hvmr-glm-l-mrkht">   ,  </h3>
<p>  .  , -AI .      -AI   ,  ,  artifact ,    review.<br />  -AI      design .<br />?                 .</p>
<p>   -ADRs.<br />    .<br />   -review.<br />   .<br />, ,         .</p>
<p>Lattice       .<br />gstack     .<br />  :     ,      .</p>
<h3 id="heading-durable-artifacts-mntshym-yhvt-rvkhvt">Durable artifacts   </h3>
<p>     AI  context erosion.    .   ,    logs,    .<br />     ,     .</p>
<p> artifacts   </p>
<pre><code class="lang-plaintext">requirement.md
design-blueprint.md
architecture.md
review-log.md
operational-learnings.md
</code></pre>
<p>     .   -AI        .<br />   : "         architecture standards    .<br />  ,   </p>
<h3 id="heading-design-first-hv-l-vyrvkrtyh-hv-mngnvn-hgnh">Design first   ;   </h3>
<p>AI    .   .<br />        syntax error.    design      .</p>
<p>Design-First   .       .<br />Lattice     <code>design-blueprint</code>.<br />gstack     planning -engineering review.<br />       :</p>
<blockquote>
<p>      ,  ?</p>
</blockquote>
<p>,    -diff    .<br />        .</p>
<h3 id="heading-role-separation-mfhyt-r">Role separation  </h3>
<p>gstack        mode   .<br />  scope        .<br />        UI.<br /> review       release summary.</p>
<p>     ,  . -AI    product  ,  -test strategy,  -refactor  .   ,     .</p>
<p>gstack :</p>
<blockquote>
<p>Product thinking    ?<br />Engineering planning    ?<br />Implementation      ?<br />Review    ?<br />QA    ?<br />Ship    ?<br />Reflect     ?</p>
</blockquote>
<p>       .       .</p>
<h3 id="heading-stndrtym-tsrykhym-lhyvt-dynmyym-l-msmkh-kfv">   ,   </h3>
<p>Lattice       .<br />    :      legacy policy.   ,                 .</p>
<p> <code>.lattice/standards/architecture.md</code>  , -AI   .      ,      .<br />   <code>.lattice</code>     :</p>
<ul>
<li><p> review .</p>
</li>
<li><p>  refactor </p>
</li>
<li><p>    </p>
</li>
<li><p>    </p>
</li>
<li><p>      .</p>
</li>
</ul>
<p> :  -AI   ,    .</p>
<h3 id="heading-lvlt-fydvk-hy-hytrvn-hmtstvr">    </h3>
<p>   -Lattice    ,  .<br /> , , review           .</p>
<p>,    idempotency -worker,   -operational learning:</p>
<pre><code class="lang-markdown"><span class="hljs-section">## Money Movement Learning</span>

For workflows involving money movement, idempotency must be enforced at every
asynchronous boundary, not only at the initial HTTP request boundary.

Check:
<span class="hljs-bullet">-</span> HTTP request deduplication
<span class="hljs-bullet">-</span> queue consumer deduplication
<span class="hljs-bullet">-</span> provider operation key
<span class="hljs-bullet">-</span> reconciliation behavior
</code></pre>
<p>   flow , -AI   .       -context.</p>
<p>    AI workflow      -      ,    :   ,    .</p>
<h3 id="heading-failure-modes-tsrykh-lkht-vrtsynvt">Failure modes   </h3>
<p>-failure mode   <strong>over trust</strong>.<br />  <code>/review</code>   review .    .   , , , , data migrations -   .<br />          .</p>
<p>-failure mode   <strong>stale context</strong>.<br />   , -AI     .</p>
<p>  <strong>ceremony overload</strong>.<br />    full workflow.  type    ,  , engineering review -QA.      .</p>
<p>  <strong>local optimization</strong>.<br />AI       .  review     ,    diff .</p>
<p>  <strong>ambiguity laundering</strong>.<br />  , AI    . framework     ,  ambiguity  .<br />       AI:</p>
<blockquote>
<p>AI   -  .</p>
<p>AI   -  guardrail.</p>
</blockquote>
<p><img loading="lazy" src="/images/posts/gstack-and-lattice/img-3.webp" class="image--center mx-auto" /></p>
<h2 id="heading-sykhvm"></h2>
<p>gstack -Lattice      AI  .<br />     <br />     .<br /> workflow     -AI        : , , code review, QA, shipping, </p>
<p>gstack    :</p>
<blockquote>
<p>Think  Plan  Build  Review  Test  Ship  Learn</p>
</blockquote>
<p>Lattice     :</p>
<blockquote>
<p>Atoms  Molecules  Refiners  .lattice/ living context</p>
</blockquote>
<p>    : AI-assisted development  chat-based coding process-aware engineering.</p>
<p>  ,        AI   .   .         ,  ,  standards,   ambiguity,       .</p>
<p>    :</p>
<p>AI    .<br />AI   ,  architecture,  learnings,            .</p>
]]></description><link>https://thecodeline.org/gstack-and-lattice</link><guid isPermaLink="true">https://thecodeline.org/gstack-and-lattice</guid><category><![CDATA[Software Architecture]]></category><category><![CDATA[Lattice]]></category><category><![CDATA[Ai Engineering]]></category><category><![CDATA[Ai Assisted Development]]></category><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Sun, 31 May 2026 05:24:43 GMT</pubDate><cover_image/></item><item><title><![CDATA[ניהול רענון דאטה ב-Tableau Cloud עם Airflow]]></title><description><![CDATA[<h1 id="heading-mlk">;</h1>
<p>   Extract -Tableau Cloud  Airflow ( -MWAA),  -Personal Access Tokens (PAT)       (Linear Session).       (Error 401002).      -Airflow Pools    -API,       -JWT Connected Apps,    -Providers -MWAA</p>
<hr />
<h1 id="heading-rk-hyfh-lmkvylyvt-v-bi-orchestration">:   -BI Orchestration</h1>
<p>  ,   <strong>AWS Managed Workflows for Apache Airflow (MWAA)</strong>  2.10.3,   :    BI    4 .</p>
<p>  : DAG  ,   Flow   -dbt cloud    -Datasource -Tableau.          -Flow  ,     .     -API  Tableau.</p>
<h1 id="heading-ykh-zh-vvd-v-lmh-h-pat-vvr-tkhm">   (  -PAT  )</h1>
<p>      <strong>Tableau REST API</strong>.   -PAT, -Site logic    :</p>
<ol>
<li><p><strong> </strong>  <code>sign_in()</code>  <strong>-1</strong></p>
</li>
<li><p><strong> </strong> ( )  <code>sign_in()</code>   PAT  <strong>-2</strong></p>
</li>
<li><p>  <strong>Tableau Cloud</strong>    <strong>-1</strong></p>
</li>
<li><p><strong> </strong>      <code>(Unauthorized Access) 401002</code></p>
</li>
</ol>
<p>   ,              PAT.</p>
<p><img loading="lazy" src="/images/posts/tableau-cloud-airflow/img-1.webp" class="image--center mx-auto" /></p>
<hr />
<h1 id="heading-nytvh-hfrvyvt-mmvvy-stvm-lftrvn"> :   </h1>
<p>       ,   -<strong>MFA Wall</strong>.  2022, Tableau  MFA,             .</p>
<p>   <strong>JWT Connected App</strong>,  Stateless Authentication    .  , -MWAA      :  -Tableau Provider   4.5.0,   -JWT   -5.2.0.     <code>requirements.txt</code>    -Constraints   AWS.</p>
<p><strong>   :</strong></p>
<table><colgroup><col></col><col></col><col></col><col></col><col></col></colgroup><tbody><tr><td><p><strong> </strong></p></td><td><p><strong> </strong></p></td><td><p><strong> MFA?</strong></p></td><td><p><strong> -MWAA (Native)</strong></p></td><td><p><strong></strong></p></td></tr><tr><td><p><strong>PAT</strong></p></td><td><p> /  </p></td><td><p></p></td><td><p> (4.5.0)</p></td><td><p> ( Pool)</p></td></tr><tr><td><p><strong>User/Pass</strong></p></td><td><p>-</p></td><td><p><strong></strong></p></td><td><p></p></td><td><p> " MFA</p></td></tr><tr><td><p><strong>Connected App (JWT)</strong></p></td><td><p>- / Stateless</p></td><td><p></p></td><td><p> 5.2.0 </p></td><td><p>Roadmap</p></td></tr></tbody></table>

<hr />
<h1 id="heading-hftrvn-hmy-airflow-pools-khstvm-lhts"> : Airflow Pools  </h1>
<p>        -DAG,       Airflow     .</p>
<p> <strong>Airflow Pool</strong>  <code>tableau_refresh_pool</code>  Slot  .   -dbt      -Workers,    .     Worker   -Tableau   ,    -Race Condition.</p>
<h2 id="heading-dvgmt-kvd-dag-factory-mvvss-kvnfygvrtsyh"> : DAG Factory  </h2>
<p>      :</p>
<pre><code class="lang-python"><span class="hljs-comment"># Deploy TableauOperator with Pool</span>
<span class="hljs-keyword">for</span> luid <span class="hljs-keyword">in</span> conf[<span class="hljs-string">'tableau_datasource_luids'</span>]:
    TableauOperator(
        task_id=<span class="hljs-string">f"refresh_<span class="hljs-subst">{luid[:<span class="hljs-number">8</span>]}</span>"</span>,
        site_id=<span class="hljs-string">"my_site"</span>,
        resource=<span class="hljs-string">"datasources"</span>,
        method=<span class="hljs-string">"refresh"</span>,
        find=luid,
        pool=<span class="hljs-string">"tableau_refresh_pool"</span> <span class="hljs-comment">#   401002</span>
    ) &gt;&gt; dbt_task
</code></pre>
<hr />
<h1 id="heading-sykhvm"></h1>
<ol>
<li><p><strong>Auth is Architecture</strong>:        ,     -Scaling  .</p>
</li>
<li><p><strong> :</strong>    MWAA,     <code>constraints.txt</code>        provider .</p>
</li>
<li><p><strong>Pools   :</strong>         -DAG     API .</p>
</li>
</ol>
]]></description><link>https://thecodeline.org/tableau-cloud-airflow</link><guid isPermaLink="true">https://thecodeline.org/tableau-cloud-airflow</guid><category><![CDATA[airflow]]></category><category><![CDATA[tableau]]></category><category><![CDATA[dataengineering]]></category><category><![CDATA[Manage Workflow airflow]]></category><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Thu, 09 Apr 2026 11:57:28 GMT</pubDate><cover_image/></item><item><title><![CDATA[Apache Spark למפתחי Backend]]></title><description><![CDATA[<h1 id="heading-mlk">;</h1>
<p>Apache Spark     .  <strong>execution engine </strong>:   pipeline   , -Spark      cluster.    ,   -<strong>RDD</strong>   immutable, partitioned         -DataFrame -Spark SQL,           -optimization.    ,  <code>groupBy</code>,  <code>join</code>,  <code>count()</code>    syntax       : CPU, , ,    <strong>shuffle</strong>.</p>
<hr />
<h1 id="heading-rk-lmh-spark-mvlvl-khl-khkh-vhthlh">:  Spark    ?</h1>
<p>     Backend ,    Spark      .</p>
<p>:    "pandas   .<br />:   "SQL engine .</p>
<p>  ,      . Spark,    , :</p>
<blockquote>
<p>multi-language engine for executing data engineering, data science, and machine learning on single-node machines or clusters</p>
</blockquote>
<p>,     ; -API     .</p>
<p>   -Spark     . . Driver,  Executors,  Resource Allocation,  Parallelism,  Locality,  Failure Recovery,      state  nodes.  -Backend     latency, fan-out, hot-keys -network overhead - -Spark        data flow   request flow.</p>
<p><img loading="lazy" src="/images/posts/apache-spark-backend/img-1.webp" class="image--center mx-auto" /></p>
<hr />
<h1 id="heading-ykh-spark-vvd-lhthyl-mhvsys-vl-mhksm"> Spark :    </h1>
<h2 id="heading-rdd-vn-hvnyyn-hmkvryt">RDD:   </h2>
<p>   Spark  <strong>RDD - Resilient Distributed Dataset</strong>.     :</p>
<blockquote>
<p>collection of elements partitioned across the nodes of the cluster that can be operated on in parallel</p>
</blockquote>
<p>-API    :</p>
<blockquote>
<p>immutable, partitioned collection of elements</p>
</blockquote>
<p>    :</p>
<ul>
<li><p><strong>Dataset</strong> -   </p>
</li>
<li><p><strong>Distributed</strong> -   -partitions   nodes .</p>
</li>
<li><p><strong>Resilient</strong> -    , Spark   .</p>
</li>
</ul>
<p>-"Resilient"     .   -Spark     intermediate result     fault tolerant.  ,    <strong> </strong> -  dataset  -     partitions .    -mental model  Spark    -runtime     .</p>
<h2 id="heading-partitioning-hsvd-hmyty-l-parallelism">Partitioning:    parallelism</h2>
<p>RDD     .   -<strong>partitions</strong>,  partition    .    -Spark    executors. -parallelism   , ,  partitions ,   ,    .</p>
<p>             .  partition     ,  cluster    .  ?   hot shard,   .</p>
<h2 id="heading-transformations-v-actions-lazy-d-khvv">Transformations -Actions: lazy  </h2>
<p>  RDD     operations:</p>
<ul>
<li><p><strong>Transformations:</strong>  <code>flatMap</code>, <code>filter</code>, <code>map</code></p>
</li>
<li><p><strong>Actions</strong>:  <code>save</code>, <code>collect</code>, <code>count</code></p>
</li>
</ul>
<p> : transformations -Spark  <strong>lazy.</strong>   - <code>filter</code>  Spark   .      .   <strong>actions</strong>,   execution .    reactive programming  reactor     publisher  .</p>
<p>    ,       Spark.          <strong></strong>.          .</p>
<h2 id="heading-driver-executors-v-cluster-manager">Driver, Executors, -Cluster Manager</h2>
<p>  Spark     processes  . -<strong>Driver</strong>          -SparkContext.   Spark   -<strong>Cluster Manager</strong> ( Kubernetes)  <strong>Executors</strong>  worker nodes. -Executors  processes    -tasks         .</p>
<p>    :    cluster shared cache"  "database".     -executors , -state      .      ,        external storage,     -executors.</p>
<p><img loading="lazy" src="/images/posts/apache-spark-backend/img-2.webp" class="image--center mx-auto" /></p>
<h2 id="heading-jobs-stages-tasks-mhrmt-yd-llkhlvkh-myty">Jobs, Stages, Tasks:    </h2>
<p>-action ,   <strong>Job</strong>. -job  -<strong>Stages</strong>,  stage  -<strong>Tasks</strong>. -tasks     -executors. ,  tasks   -partitions     .</p>
<p>   . , Spark  execution graph,     pipeline,     redistribution  .         latency : <strong>Shuffle</strong>.</p>
<h1 id="heading-shuffle-hms-hmyty-l-distributed-data">Shuffle:    distributed data</h1>
<p>       ,   RDD  DataFrame.  <strong>Shuffle</strong>.</p>
<p>Shuffle    <strong>     </strong>.       <code>groupBy</code>, <code>join</code>, <code>distinct</code>, <code>orderBy</code>.      shuffle -operation  ,     <strong>data serialization, disk I/O, -network I/O</strong>.</p>
<p>       .  <code>groupBy</code>     .        key   ,  <strong>      </strong>. ,   ,  intermediate data,       .</p>
<p> :    .                   .</p>
<h1 id="heading-z-yfh-nkhnsym-dataframe-v-spark-sql">   DataFrame -Spark SQL?</h1>
<p>  RDD,           <strong>DataFrame/DataSet/SQL</strong>.</p>
<p>  , Spark SQL       <strong>structured data</strong>,  -RDD API,           .   ,     .   Spark SQL    </p>
<blockquote>
<p>columnar storage, cost-based optimizer, and code -generation</p>
</blockquote>
<p>-Quick Start        (  ):   2.0 -main programming interface  -RDD  Dataset,  -RDD         . -RDD API    ,        -workloads structured</p>
<p>     :<br />RDD        . DataFrame         ,      .</p>
<p>   ,               typed protocol -runtime   .</p>
<h1 id="heading-dvgmh-fvth-kvdm-rdd-vz-lhvyn-mh-vmt-kvrh"> :  RDD     </h1>
<pre><code class="lang-python">rdd = spark.sparkContext.textFile(<span class="hljs-string">"s3a://logs/app/"</span>)  
errors = rdd.filter(<span class="hljs-keyword">lambda</span> line: <span class="hljs-string">"ERROR"</span> <span class="hljs-keyword">in</span> line)  
count = errors.count()
</code></pre>
<p>   ?</p>
<ul>
<li><p><code>textFile</code>  RDD  </p>
</li>
<li><p><code>filter</code>   ,   transformation    pipeline</p>
</li>
<li><p><code>count()</code>  ,      job </p>
</li>
</ul>
<p>       ,       .   .         ,  </p>
<h1 id="heading-dvgmh-nyh-lmh-groupby-mrgy-tmym-vl-l-tmym-vkhll"> :  <code>groupBy</code>      </h1>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> pyspark.sql <span class="hljs-keyword">import</span> functions <span class="hljs-keyword">as</span> F  

users = spark.read.parquet(<span class="hljs-string">"s3a://warehouse/users"</span>)  

result = (  
    users  
    .filter(F.col(<span class="hljs-string">"is_active"</span>) == <span class="hljs-literal">True</span>)  
    .groupBy(<span class="hljs-string">"country"</span>)  
    .count()  
)
</code></pre>
<p>     : , , .</p>
<p>,    . <code>filter</code>      .  <code>groupBy("country")</code>             .    shuffle.</p>
<p>    Spark   API         .</p>
<h1 id="heading-join-l-tmyd-svn-vl-svn-khtm-l-yvdym-mh-kvrh">Join:   ,       </h1>
<p>JOIN    Spark    SQL   execution.   -performance tuning, Spark SQL    join ,  <strong>broadcast</strong>,    -<strong>join hints</strong>  <code>BROADCAST</code>, <code>MERGE</code>, <code>SHUFFLE_HASH</code> -<code>SHUFFLE_REPLICATE_NL</code>. ,   Spark 3.5  -<strong>Adaptive Query Execution</strong>      sort-merge join -broadcast join, coalescing  post-shuffle partitions, -skew join optimization.</p>
<p>  -JOIN     shuffle     .     , Spark     -executors  local join   .      execution,    query.</p>
<p><img loading="lazy" src="/images/posts/apache-spark-backend/img-3.webp" class="image--center mx-auto" /></p>
<h1 id="heading-spark-infrastructure-hmnv-hv-rk-hlk-mhsyfvr">Spark Infrastructure:     </h1>
<p>     -Spark   . , Spark  ,        : cluster manager, storage, submission, monitoring, logging   orchestration .    cluster mode overview   applications  -independent sets of processes  cluster, -cluster manager   resources -Spark applications.</p>
<p>      Spark infrastructure,       -Spark binaries.       workloads   :  , runtime, resource isolation, observability, retries,  pipeline scheduler .</p>
<h1 id="heading-mh-backend-engineers-vdrkh-khll-mfsfsym"> Backend engineers   </h1>
<p>    -Spark          .  . partitioning -distribution   -design,   .</p>
<p>    -<code>collect()</code>    .     -driver,      distributed execution.</p>
<p>    -API    .    ,   .</p>
<p> ,   ,    RDD . ,  -production workloads   DataFrames -SQL,        partitions, lazy evaluation, actions -shuffle,          dataset .</p>
<h1 id="heading-sykhvm"></h1>
<p>    Spark   : <strong>RDD   immutable   -partitions   </strong>.   DataFrame -Spark SQL,          optimization.     -API ,      executors, tasks, network, memory -shuffle.</p>
<p>   -Backend,    .   .       boundaries,  hot spots,  fan-out,         . Spark           .</p>
<p>  :<br /><code>groupBy</code>   .<br /><code>groupBy</code>  .</p>
]]></description><link>https://thecodeline.org/apache-spark-backend</link><guid isPermaLink="true">https://thecodeline.org/apache-spark-backend</guid><category><![CDATA[#apache-spark]]></category><category><![CDATA[#rdd]]></category><category><![CDATA[distributed system]]></category><category><![CDATA[data-engineering]]></category><category><![CDATA[backend]]></category><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Sun, 22 Mar 2026 15:46:23 GMT</pubDate><cover_image/></item><item><title><![CDATA[מ-Data Lake אל Data Lakehouse]]></title><description><![CDATA[<h1 id="heading-mlk">;</h1>
<p>-Data Lakehouse     Data Warehouse -Data Lake,     .   <strong>Table Format</strong> ( Apache Iceberg  Delta Lake), -Lakehouse  Optimistic Concurrency Control,  -    Object Storage. :  ACID,  -<em>O(1)</em>, -Decoupling  Compute -Storage -    (open source).</p>
<hr />
<h1 id="heading-rk-hvvlvtsyh-vhvr-l-rkhytktvrt-hntvnym">:     </h1>
<p>   -Lakehouse ,        :</p>
<ol>
<li><p><strong> 1: -Data Warehouse ()</strong><br />  Teradata,     Redshift.     <em>Coupled Storage &amp; Compute</em>  Shared-Nothing MPP.</p>
<ol>
<li><p><strong>:</strong>   -OLAP,   (Schema-on-Write)  ACID .</p>
</li>
<li><p><strong>:</strong>    .      - (Unstructured),    ,         .</p>
</li>
</ol>
</li>
<li><p><strong> 2: -Data Lake (The Swamp)</strong><br />-Big Data ,  -HDFS  -S3/GCS.       <em>Schema-on-Write.</em></p>
<ol>
<li><p><strong>:</strong>   ,    (JSON, CSV, Parquet)</p>
</li>
<li><p><strong>:</strong>   Data Governance.  ACID.   Spark   ,     -Bucket     .     (UPDATE/DELETE),     partition .</p>
</li>
</ol>
</li>
</ol>
<p><strong>-Data Lakehouse (3)</strong>     -ACID   -Warehouse,      -Lake. ?     (Metadata)  .</p>
<p><img loading="lazy" src="/images/posts/data-lake-data-lakehouse/img-1.webp" class="image--center mx-auto" /></p>
<hr />
<h1 id="heading-ykh-zh-vvd-lv-hkhvvt-l-h-lakehouse">  ?    -Lakehouse</h1>
<p>  -Lakehouse      :</p>
<p><img loading="lazy" src="/images/posts/data-lake-data-lakehouse/img-2.webp" class="image--center mx-auto" /></p>
<p>   ( Trino)   -S3          (   <em>O(n)</em>   )    -Table Format.</p>
<hr />
<h1 id="heading-kvd-vdvgmh-myt-ftrvn-vyyt-h-update-vgm-ntvnym">  :   -UPDATE  </h1>
<p>  ,    upsert (  )      ETL . -Lakehouse,   ,          <code>merge-on-read</code>  <code>copy-on-write</code></p>
<p>     PySpark  Apache Iceberg</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> pyspark.sql <span class="hljs-keyword">import</span> SparkSession

<span class="hljs-comment"># Config session with Iceberg Catalog configuration</span>
spark = SparkSession.builder \
    .config(<span class="hljs-string">"spark.sql.extensions"</span>, <span class="hljs-string">"org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions"</span>) \
    .config(<span class="hljs-string">"spark.sql.catalog.my_catalog"</span>, <span class="hljs-string">"org.apache.iceberg.spark.SparkCatalog"</span>) \
    .config(<span class="hljs-string">"spark.sql.catalog.my_catalog.type"</span>, <span class="hljs-string">"hadoop"</span>) \
    .config(<span class="hljs-string">"spark.sql.catalog.my_catalog.warehouse"</span>, <span class="hljs-string">"s3a://my-lakehouse-bucket/"</span>) \
    .getOrCreate()

<span class="hljs-comment"># The MERGE INTO was available only on Data Warehouse</span>
spark.sql(<span class="hljs-string">"""
MERGE INTO my_catalog.db.users t
USING (SELECT * FROM staging_users) s
ON t.user_id = s.user_id
WHEN MATCHED THEN 
  UPDATE SET t.email = s.email, t.last_login = s.last_login
WHEN NOT MATCHED THEN 
  INSERT *
"""</span>)
</code></pre>
<p> , Iceberg     .   Snapshot        ,   Parquet  (),  -    .</p>
<hr />
<h1 id="heading-nytvh-vmk-hhvdlym-htkhnvlvgym-l-h-lakehouse"> :     Lakehouse</h1>
<h2 id="heading-hyrrkhyyt-mt-dth-v-query-planning-v-o1"> - -Query Planning -O(1)</h2>
<p>   Hive,   -Directory Structure. -Iceberg, -  :</p>
<p><code>Catalog -&gt; Metadata file (current snapshot) -&gt; Manifest List -&gt; Manifest Files -&gt; Data Files (Parquet)</code></p>
<p>   ,    -Manifests  <em>Min/Max Filtering</em>          -S3.     .</p>
<h2 id="heading-optimistic-concurrency-control-occ">Optimistic Concurrency Control (OCC)</h2>
<p> -Lakehouse   (Writer A  Writer B)?<br />  -OCC:           .  -Commit,  A   Swap   -Metadata Pointer.   B  ,  A   -Metadata ,       B   .   -     Commit .   Throughput      .</p>
<h2 id="heading-vvlvtsyyt-skhymh-mytyt">  </h2>
<p> ,      (Named-Based)    (Position-Based). -Lakehouse,       (ID).   ?  ?  ? -ID    -.    Backfill   .</p>
<h2 id="heading-decoupling-compute-amp-storage-ll-vendor-lock-in">Decoupling Compute &amp; Storage  Vendor Lock-in</h2>
<p>   Snowflake     ,        . -Lakehouse,    -Bucket ,  Parquet .       Spark (-ETL ),     Trino ( BI ),    -Amazon Athena -      .</p>
<hr />
<h1 id="heading-sykhvm"></h1>
<p>-Data Lakehouse    ,     -Big Data.      (State),  (ACID) -   -Compute ()        -    ,  ,     Data Science, Data Engineer, -Data Analysts   .</p>
]]></description><link>https://thecodeline.org/data-lake-data-lakehouse</link><guid isPermaLink="true">https://thecodeline.org/data-lake-data-lakehouse</guid><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Sun, 15 Mar 2026 11:15:06 GMT</pubDate><cover_image/></item><item><title><![CDATA[מביצות נתונים למכרות זהב]]></title><description><![CDATA[<h1 id="heading-mlk">;</h1>
<p>  (Medalion Architecture)  Framework    Data Lake,      : <strong>Bronze</strong> ( ), <strong>Silver</strong> (  ), <strong>Gold</strong> (   ).       -ETL   ,       ML -AI.</p>
<h1 id="heading-rk-mvt-h-etl-hklsy">:  -ETL </h1>
<p> ,     -ETL (Extract, Transform, Load) .  ,          .      ,    Big Data    ,      -Silos   .       (Data Swamps)      .          -Data Estate     .</p>
<hr />
<h1 id="heading-ykh-zh-vvd-mvnh-hkhvvt">  :  </h1>
<p><img loading="lazy" src="/images/posts/from-data-swamp-to-gold-mine/img-1.webp" alt="   Medallion         Bronze, Silver -Gold" class="image--center mx-auto" /></p>
<h2 id="heading-khvt-h-bronze-fvlyst-hvytvh-lkhm"> -Bronze:   </h2>
<p>  -Landing .       (Raw data),  .</p>
<ul>
<li><p><strong>:</strong> Single Source of Truth.       (Full Fidelity),   .</p>
</li>
<li><p><strong> </strong>:    -Ingestion  Schema Drift (  ),      -Bronze -<code>Binary</code>, <code>VARIANT</code>  <code>String</code></p>
</li>
<li><p><strong></strong>:        ,  -Bronze    -Time Travel (   Delta Lake)  Reprocessing     .</p>
</li>
</ul>
<h2 id="heading-khvt-h-silver-khn-hmd-kvrh"> -Silver:   </h2>
<p>  -Integrity.        .    ,   -Type Casting.</p>
<ul>
<li><p><strong>   -Data Science</strong>:     .        (Non-aggregated),            .</p>
</li>
<li><p><strong></strong>:       Z-Ordering  Liquid Clustering      (Low Latency).</p>
</li>
</ul>
<h2 id="heading-khvt-h-gold-mnv-kvlt-hhltvt"> -Gold:   </h2>
<p>  (Consumer-Facing).      (  Star Schema  Kimball)          Power BI,   AI.</p>
<ul>
<li><strong>Semantic Backbone:</strong>       -Gold      .    -LLM      (      ?)    ,     .</li>
</ul>
<hr />
<h1 id="heading-nytvh-silver-vs-gold">: Silver vs. Gold</h1>
<p>          :</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Gold ( )</td><td>Silver ( )</td><td></td></tr>
</thead>
<tbody>
<tr>
<td> ,  -KPI</td><td>, </td><td><strong></strong></td></tr>
<tr>
<td>Data Marts  Star Schemas</td><td>Delta Valut  3rd Normal Form</td><td><strong> </strong></td></tr>
<tr>
<td>Executives, Decision Makers &amp; AI Agents</td><td>Data Engineers &amp; ML Engineers</td><td><strong> </strong></td></tr>
</tbody>
</table>
</div><hr />
<h1 id="heading-sykhvm-htyd-hv-khvvt">:   </h1>
<p>      -   .    -AI      ,          .</p>
]]></description><link>https://thecodeline.org/from-data-swamp-to-gold-mine</link><guid isPermaLink="true">https://thecodeline.org/from-data-swamp-to-gold-mine</guid><category><![CDATA[MedallionArchitecture]]></category><category><![CDATA[data lakehouse]]></category><category><![CDATA[data-engineering]]></category><category><![CDATA[backend developments]]></category><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Sun, 15 Feb 2026 11:27:38 GMT</pubDate><cover_image/></item><item><title><![CDATA[BFF (Backend for Frontend)]]></title><description><![CDATA[<h1 id="heading-mlk">;</h1>
<p> Backend-for-Frontend ( BFF)       JSON  .     Public Client   ( ) -Confidential Client .     -BFF    (Goodbye, LocalStorage),    Over-fetching,     Next.js   BFF .</p>
<h1 id="heading-hrk-hvyh-m-one-size-fits-all">:   One Size Fits All</h1>
<p>    (        ):    -Go  Node.js.   API  .     Web,  IOS,     .</p>
<p>?            .  ?       .     Endpoint     5MB,     .</p>
<p> ,   :     -Access Token  -Web?    <code>localStorage</code>,    .  -BFF  </p>
<h1 id="heading-ykh-zh-vvd-hrkhytktvrh">  : </h1>
<p><img loading="lazy" src="/images/posts/bff-backend-for-frontend/img-1.webp" class="image--center mx-auto" /></p>
<p>, -BFF    (Facade)    .  API  ,          -Web.</p>
<p>    -Deep Tech     BFF: <strong></strong>.</p>
<p> -OAuth 2.0,  SPA (   )  <strong>Public Clients</strong>.      (  ).     .     -   XSS (Cross-Site Scripting).</p>
<p>-BFF  -<strong>Confidential Client</strong>.     .</p>
<ol>
<li><p> ()   -BFF  <strong>HttpOnly Cookie</strong> (   Javascript).</p>
</li>
<li><p>-BFF   -Tokens  (API Keys, OAuth Tokens)   -Session Store   .</p>
</li>
<li><p>-BFF  -Microservices  (Downstream Services)     .</p>
</li>
</ol>
<p>?     .    .</p>
<h1 id="heading-kvd-h-bff-hmvdrny">: -BFF </h1>
<p>        -BFF    .   Next.js, Remix,  SvelteKit   <strong>Integrated BFF</strong>.</p>
<p>     -Next.js (App Router).      -Route Handler      :</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// app/api/user-dashboard/route.ts</span>
<span class="hljs-keyword">import</span> { cookies } <span class="hljs-keyword">from</span> <span class="hljs-string">'next/headers'</span>;
<span class="hljs-keyword">import</span> { NextResponse } <span class="hljs-keyword">from</span> <span class="hljs-string">'next/server'</span>;

<span class="hljs-comment">// This acts as our BFF layer</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">GET</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// 1. Security: Get the session ID from a secure, HttpOnly cookie</span>
  <span class="hljs-keyword">const</span> cookieStore = cookies();
  <span class="hljs-keyword">const</span> sessionId = cookieStore.get(<span class="hljs-string">'secure_session_id'</span>)?.value;

  <span class="hljs-keyword">if</span> (!sessionId) {
    <span class="hljs-keyword">return</span> NextResponse.json({ error: <span class="hljs-string">'Unauthorized'</span> }, { status: <span class="hljs-number">401</span> });
  }

  <span class="hljs-comment">// 2. Downstream Call: Fetch heavy data from the core Microservice</span>
  <span class="hljs-comment">// The actual API Key is stored safely on the server environment</span>
  <span class="hljs-keyword">const</span> upstreamResponse = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://api.internal.corp/heavy-user-data'</span>, {
    headers: {
      <span class="hljs-string">'Authorization'</span>: <span class="hljs-string">`Bearer <span class="hljs-subst">${process.env.CORE_SERVICE_API_KEY}</span>`</span>,
      <span class="hljs-string">'X-Session-ID'</span>: sessionId
    }
  });

  <span class="hljs-keyword">const</span> heavyData = <span class="hljs-keyword">await</span> upstreamResponse.json();

  <span class="hljs-comment">// 3. Transformation: The "Frontend" part of BFF</span>
  <span class="hljs-comment">// Instead of sending 50 fields, we send exactly what the UI needs</span>
  <span class="hljs-keyword">const</span> optimizedPayload = {
    displayName: <span class="hljs-string">`<span class="hljs-subst">${heavyData.firstName}</span> <span class="hljs-subst">${heavyData.lastName}</span>`</span>,
    avatar: heavyData.profileImages[<span class="hljs-string">'thumbnail_200px'</span>], <span class="hljs-comment">// Logic tailored for UI</span>
    pendingTasks: heavyData.tasks.filter(<span class="hljs-function">(<span class="hljs-params">t: <span class="hljs-built_in">any</span></span>) =&gt;</span> t.status === <span class="hljs-string">'URGENT'</span>).length
  };

  <span class="hljs-keyword">return</span> NextResponse.json(optimizedPayload);
}
</code></pre>
<p><strong>  ?</strong></p>
<ol>
<li><p><strong>Security Boundary:</strong> -API key  (<code>process.env.CORE_SERVICE_API_KEY</code>)    .</p>
</li>
<li><p><strong>Payload Optimization:</strong>          ,  JSON   .</p>
</li>
</ol>
<h1 id="heading-nytvh-l-hkhl-vrvd-trade-offs">:    (Trade-offs)</h1>
<p>   ,   .</p>
<ol>
<li><p><strong>-Fan-Out Problem:</strong> -BFF    -5      ,  .    ,   .        ,   .</p>
<ol>
<li><strong>:</strong>  -Circuit Breakers (   Netflix Hystrix )    Caching   -BFF.</li>
</ol>
</li>
<li><p><strong> :</strong>    BFF  -BFF -Web,       .</p>
<ol>
<li><strong>:</strong>   (Shared Libraries)     <strong>GraphQL</strong> (   WunderGraph)   BFF-   ,        Build.</li>
</ol>
</li>
<li><p><strong>   ?</strong>   ( ),  BFF-   .    -<strong>Federated Supergraphs</strong> ( Apollo Federation),        ,      .</p>
</li>
</ol>
<h1 id="heading-sykhvm"></h1>
<p>-BFF      .       -Backend            .        Web  Mobile,       - -BFF   ,  .</p>
<h2 id="heading-htsd-hv-lkhm">  </h2>
<p>    .      -Database   -UI?     -Local Storage?        .</p>
]]></description><link>https://thecodeline.org/bff-backend-for-frontend</link><guid isPermaLink="true">https://thecodeline.org/bff-backend-for-frontend</guid><category><![CDATA[software development]]></category><category><![CDATA[cybersecurity]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Sat, 31 Jan 2026 21:02:31 GMT</pubDate><cover_image/></item><item><title><![CDATA[מכאוס לקונטקסט: המדריך הטכני]]></title><description><![CDATA[<h1 id="heading-mlk">;</h1>
<p>  ? .         :   ,  -Git Worktree ,  -Cursor Rule (.mdc) ,           AI.</p>
<hr />
<h1 id="heading-hkdmh-trv-ly-t-hkvd">:    </h1>
<p><a target="_blank" href="https://www.thecodeline.org/mkhvs-lkvntkst"> </a>,  ,         AI.   ,      :</p>
<blockquote>
<p>  !           <br />   how to worktree      </p>
</blockquote>
<p> .   ,     .      -IDE     --    </p>
<h1 id="heading-lv-1-zyrt-hmhkym-the-setup"> 1:   (The Setup)</h1>
<p>   -Workflow,        .     .   Workspace     :</p>
<p>  -root :</p>
<pre><code class="lang-bash">$ ll
drwxr-xr-x  common-libraries  <span class="hljs-comment">#  </span>
drwxr-xr-x  rnd-documentation <span class="hljs-comment">#   -Software Designs</span>
drwxr-xr-x  first-repo         <span class="hljs-comment">#   - Production Branch</span>
drwxr-xr-x  second-repo          <span class="hljs-comment">#   - Production Branch</span>
</code></pre>
<p><strong>  ?</strong>  -<code>first-repo</code>    VS COde     -Source of Truth.     .    ( -AI) ,  ,  -History.   .   <code>second-repo</code></p>
<p>      ,    <code>git checkout</code>    .     .</p>
<h1 id="heading-lv-2-hnytvh-git-worktree"> 2:  (Git Worktree)</h1>
<p>  <code>git clone</code>    ,   -<code>git worktree</code>.           ,    Branch .</p>
<p>   (  ), :</p>
<pre><code class="lang-bash">git worktree add -b bugfix/PROJ-123-fix-bridge ../worktrees/proj-123-bridge master
</code></pre>
<p> :</p>
<pre><code class="lang-bash">git worktree add -b &lt;new branch name&gt; &lt;path to the worktree new dir&gt; &lt;base branch to checkout&gt;
</code></pre>
<p><strong>   </strong> <code>git checkout</code>?   .   ,   ,   ,  .    <code>first-repo</code>     ,          . -Build       Build  ,    .</p>
<p>    -worktree   :</p>
<pre><code class="lang-bash">git worktree rm ../worktrees/proj-123-bridge
</code></pre>
<p>   :</p>
<pre><code class="lang-bash">git worktree rm &lt;worktree directory&gt;
</code></pre>
<p><strong>,       ?</strong>  :      -Monorepos .        , <code>git worktree</code>     .       ,   ,     Code Reveiew     ?   <code>git stash</code>,  , ,    <code>git stash pop</code> -    Worktree .</p>
<p><strong>:   </strong>      ,   -Cursor   .     agent           :</p>
<ul>
<li><p> - local -    </p>
</li>
<li><p>  - worktree -    worktree      agents  -ui  (      )</p>
</li>
<li><p> - cloud -      ,        .</p>
</li>
</ul>
<p><img loading="lazy" src="/images/posts/cursor-git-worktree-workflow/img-1.webp" class="image--center mx-auto" /></p>
<h1 id="heading-lv-3-hmvh-cursor-rules-amp-personas"> 3:  (Cursor Rules &amp; Personas)</h1>
<p>     .   Cursor   ,  -<strong>Context</strong> -<strong>Persona</strong>   .</p>
<p> <code>.cursor/rules</code>   -    repos  -   -<code>.mdc</code>.         .     :</p>
<h2 id="heading-hhvkr-the-researcher"> (The Researcher)</h2>
<p>      .       .     :</p>
<pre><code class="lang-markdown"><span class="hljs-section"># Bug Researcher Character</span>
...
<span class="hljs-section">## Core Principles</span>
<span class="hljs-bullet">1.</span> Systematic Investigation: Follow precise hierarchy of investigation.
<span class="hljs-bullet">2.</span> Evidence-Based: Base conclusions on code evidence, not assumptions.

<span class="hljs-section">## Workflow</span>
<span class="hljs-bullet">1.</span> <span class="hljs-strong">**Identify**</span>: Extract error message, timestamp, patterns.
<span class="hljs-bullet">2.</span> <span class="hljs-strong">**Hypothesize**</span>: Generate 3 plausible root causes based ONLY on the error.
<span class="hljs-bullet">3.</span> <span class="hljs-strong">**Investigate**</span>: Request specific code snippets (Do NOT ask for the whole codebase).
<span class="hljs-bullet">4.</span> <span class="hljs-strong">**Explain**</span>: Provide a short explanation of WHY the bug is happening.
<span class="hljs-bullet">5.</span> <span class="hljs-strong">**Wait for Approval**</span>: DO NOT provide fix details until user explicitly approves.
</code></pre>
<p>(       )</p>
<h2 id="heading-hmtkhnt-the-coder"> (The Coder)</h2>
<p>   ,     .     -Clean Code -Builds:</p>
<pre><code class="lang-markdown"><span class="hljs-section"># Coding Character</span>
...
<span class="hljs-section">## Core Principles</span>
<span class="hljs-bullet">-</span> <span class="hljs-strong">**Test-Driven Development**</span>: Always write tests before implementation.
<span class="hljs-bullet">-</span> <span class="hljs-strong">**No Comments**</span>: Code must be self-documenting.
<span class="hljs-bullet">-</span> <span class="hljs-strong">**Build Must Pass**</span>: Never commit if build fails locally.

<span class="hljs-section">## Workflow</span>
<span class="hljs-bullet">1.</span> <span class="hljs-strong">**Analyze Requirements**</span>: Read the Jira ticket or Prompt.
<span class="hljs-bullet">2.</span> <span class="hljs-strong">**Audit Existing Tests**</span>: Check coverage.
<span class="hljs-bullet">3.</span> <span class="hljs-strong">**Generate Test Suite**</span>: Happy path, Edge cases.
<span class="hljs-bullet">4.</span> <span class="hljs-strong">**Implement**</span>: Minimal implementation to pass tests.
<span class="hljs-bullet">5.</span> <span class="hljs-strong">**Refactor**</span>: Apply strict coding standards (Immutable objects, Constructor injection).
</code></pre>
<h1 id="heading-lv-4-hvkhhh-mhth"> 4:  </h1>
<p>  ,      .    :     -Bridge   .</p>
<h2 id="heading-lv-hhkyrh-hryt">  </h2>
<p>  Cursor   ( -ui),       <strong>Bug Researcher</strong>    :</p>
<blockquote>
<p>@.cursor/rules/characters/bug-researcher-character.mdc I am researching an upgrade to master - but bridge does not finish the upgrade process. In the logs I see..." [Logs Attached]</p>
</blockquote>
<p>   <code>Failed to handle MapRuleTasks</code>  ,     . -Researcher   -Stack Trace     Recovery.    -<code>finalize()</code> .<br />   :</p>
<blockquote>
<p><strong>Root Cause:</strong> Recovery scenario bug. When bridge restarts during upgrade... if upgrade instruction documents are missing... it calls <code>updateAllStatuses</code> which throws <code>NotFoundException</code>.</p>
</blockquote>
<h2 id="heading-lv-hmsyrh"> </h2>
<p>   .   -AI    .        .  ,  -Researcher:</p>
<blockquote>
<p>"Write a summarize prompt here in chat for another agent to fix this issue."</p>
</blockquote>
<p>   <strong>Prompt  </strong>  -Agent .     ,  ,   .</p>
<h2 id="heading-lv-hvytsv"> </h2>
<p> .  -worktree  <code>cd ../worktrees/fix-bridge</code>),   -Agent  Cursor :</p>
<pre><code class="lang-bash">cursor-agent --promp <span class="hljs-string">"&lt;prompt from previous step&gt;"</span>
</code></pre>
<p>-Agent  (   -IDE )   ,    ,   ,   ,     .</p>
<p>   ?      IDE .</p>
<hr />
<h1 id="heading-sykhvm-lhyvt-hmntsh-l-htzmvrt">:    </h1>
<p>          AI.</p>
<ol>
<li><p><strong> :</strong>   , Worktrees  .</p>
</li>
<li><p><strong> </strong>:    ,    .</p>
</li>
<li><p><strong>  </strong>:  -AI    -AI  .</p>
</li>
</ol>
<p>    (  ,   Worktrees),    ?       .</p>
]]></description><link>https://thecodeline.org/cursor-git-worktree-workflow</link><guid isPermaLink="true">https://thecodeline.org/cursor-git-worktree-workflow</guid><category><![CDATA[cursor IDE]]></category><category><![CDATA[Git worktree]]></category><category><![CDATA[ai-agent]]></category><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Sun, 11 Jan 2026 16:13:26 GMT</pubDate><cover_image/></item><item><title><![CDATA[מכאוס לקונטקסט]]></title><description><![CDATA[<h1 id="heading-mlk">;</h1>
<p>   AI  Cursor     .      Monorepo ,     ?        -Workflow   <strong>Git Worktrees, VS Code Workspace</strong>   -<strong>Cursor Rules</strong> ()   ,        (  ).</p>
<hr />
<h1 id="heading-rk-htgr-hrkhytktvny">:  </h1>
<p>   -Workflow    -Tufin,      .      ,     . ,      Repositories      -UI,   Repos     (Common Libraries).</p>
<p>?        ,   (Dependencies)     </p>
<hr />
<h1 id="heading-lv-1-hgyh-hnyvyt-vkhylvnh"> 1:   ()</h1>
<p>,  -Cursor   -IntelliJ  :     .       -Gradle    -VS Code Engine (:    , -LSP        IntelliJ).</p>
<p>   ,     <strong> </strong>.      ,         . ,      ,    ()      .</p>
<p><strong>:</strong> AI          -    ,       .</p>
<hr />
<h1 id="heading-lv-2-yhvd-hkhvhvt-workspaces"> 2:   (Workspaces )</h1>
<p>      VS Code  <strong>Multi-root Workspaces</strong>. ,     -ide:   X, Y -Z     .</p>
<p>  .  -Cursor   .          .     -: <strong>-</strong>.</p>
<p>    ( 30    ). ,   <code>git clone</code>            .   Repo   ,      .</p>
<hr />
<h1 id="heading-lv-3-h-game-changer-git-worktree-amp-personas"> 3: -Game Changer (Git Worktree &amp; Personas)</h1>
<p>       -Workflow   .</p>
<h2 id="heading-git-worktree">Git Worktree</h2>
<p>   -Repo ( Clone),   -<code>git worktree</code>.           -Git Object Database,    Branch .  ,  (<a target="_blank" href="https://internet-israel.com/%D7%A4%D7%99%D7%AA%D7%95%D7%97-%D7%90%D7%99%D7%A0%D7%98%D7%A8%D7%A0%D7%98/%D7%91%D7%A0%D7%99%D7%99%D7%AA-%D7%90%D7%AA%D7%A8%D7%99-%D7%90%D7%99%D7%A0%D7%98%D7%A8%D7%A0%D7%98-%D7%9C%D7%9E%D7%A4%D7%AA%D7%97%D7%99%D7%9D/%D7%9E%D7%93%D7%A8%D7%99%D7%9A-%D7%9E%D7%A2%D7%A9%D7%99-%D7%9C%D7%9B%D7%AA%D7%99%D7%91%D7%AA-%D7%A7%D7%95%D7%93-%D7%A2%D7%9D-ai-agents-%D7%A9%D7%A8%D7%A6%D7%99%D7%9D-%D7%91%D7%9E%D7%A7%D7%91%D7%99/"> -     ,  </a>)</p>
<h2 id="heading-hsvd-hmyty-cursor-rules-amp-personas">  - Cursor Rules &amp; Personas</h2>
<p>    .     :  ,   ( High Level Design),  Code Review,   .      <strong></strong>    <code>.mdc</code>  <code>.cursor/rules</code></p>
<p>  :</p>
<ul>
<li><p><strong></strong>:  , Clean Code, TDD   Tufin.</p>
</li>
<li><p><strong> software design</strong>:      software design     agent .</p>
</li>
<li><p><strong></strong>:  ,  ,       </p>
</li>
<li><p><strong>-Reviewer</strong>:  code review</p>
</li>
</ul>
<p><strong>  :</strong>      .        ,          .</p>
<hr />
<h1 id="heading-h-workflow-hnvkhhy-hlkhh-lmh">-workflow :  </h1>
<p>,     :   <strong> </strong>       .      .</p>
<h2 id="heading-thlykh-fytvh-fytsr-mktsh-lktsh">    :</h2>
<ol>
<li><p><strong> </strong>:         .      .</p>
</li>
<li><p><strong> </strong>:      .     software design.    ,  pr        -agent  .</p>
</li>
<li><p><strong> </strong>:</p>
<ol>
<li><p>  <code>git worktree</code>   .</p>
</li>
<li><p>  :       ,   -<strong>cursor agent</strong>   .</p>
</li>
<li><p>  -agent  -design  ,     -.</p>
</li>
</ol>
</li>
</ol>
<h2 id="heading-lmh-agent-vtrmynl"> agent ?</h2>
<p>   -ui    ,  ,  -agents     Worktrees .</p>
<hr />
<h1 id="heading-sykhvm-vmsknvt"> </h1>
<p>   AI    .       ,    Context -Agent.</p>
<h2 id="heading-hytrvnvt">:</h2>
<ul>
<li><p>      </p>
</li>
<li><p>   /   </p>
</li>
<li><p>         -AI.</p>
</li>
</ul>
<h2 id="heading-hsrvnvt">:</h2>
<ul>
<li>   .     -Worktrees    .</li>
</ul>
<p>   ?            .</p>
]]></description><link>https://thecodeline.org/mkhvs-lkvntkst</link><guid isPermaLink="true">https://thecodeline.org/mkhvs-lkvntkst</guid><category><![CDATA[AI]]></category><category><![CDATA[software development]]></category><category><![CDATA[cursor]]></category><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Sat, 27 Dec 2025 22:27:14 GMT</pubDate><cover_image/></item><item><title><![CDATA[הפרדוקס החדש]]></title><description><![CDATA[<h2 id="heading-mlk">;</h2>
<p>     (Specialization)    (Generalization) . ?   AI   ---    .   ,          .    -<a target="_blank" href="https://martinfowler.com/articles/expert-generalist.html"><strong>Expert Generalist</strong></a>   ,     ,           ,   .</p>
<h2 id="heading-hkdmh-vyrt-hdykhvtvmyh">:  </h2>
<p> ,        :       -PostgreSQL Internals,      ,    ?</p>
<p>    :</p>
<blockquote>
<p>Specialists are seen as people with a deep skill in a specific subject, while genralists have broad but shallow skills</p>
</blockquote>
<p>           .        -T-Shaped Person -      ( )      ( ).</p>
<p>         <strong>Expert Generalist</strong>.       T,             (Trade-offs) .</p>
<p>   .           .</p>
<h2 id="heading-htfnyt-h-ai-kh-specialist-hvltymtyvy">: -AI -Specialist </h2>
<p>     (LLMs)    AI ( Cursor)    .</p>
<p>       :</p>
<ul>
<li><p>   Paxos -Rust? -AI   </p>
</li>
<li><p>   Terraform  -AWS? -AI    </p>
</li>
</ul>
<p>   -T, -AI       . <strong>-AI  -Specialist      </strong>.</p>
<p>  ?   -AI      -T.   <strong></strong>.     ,   .</p>
<p>    -Expert Generalist .     <em> </em>  <em>  </em>   .</p>
<h2 id="heading-mkrh-mvhn-hmhnds-mvl-hmkhvnh"> :   </h2>
<p>     ,     (   ).</p>
<p><strong>:</strong>   (5 ),  -Product Market Fit .          (Background Jobs)   </p>
<p><strong>  -AI ():</strong>   -AI   : Design a robust, scalable background job system for our e-commerce platform</p>
<p>-AI,  ,    .    Microservices  Kafka  RabbitMQ,  Consumers -Go,   Kubernetes   State  -Dead Letter Queues. <strong>:</strong>    ,    (Operational Complexity)     </p>
<p><strong>  -Expert Generalist ( ):</strong>      -AI.        ,      .     (  ): "  5 .    DevOps .    .      -Overhead   ?" <strong>:</strong>            Redis ( BullMQ)     -PostgreSQL ,  -Polling.</p>
<h2 id="heading-hmndt-hhd-3-mvdy-htvvkh-l-h-expert-generalist"> : 3    -Expert Generalist</h2>
<p>         ,      :</p>
<h3 id="heading-nvvh-kvntkstvlyt-contextual-humility">  (Contextual Humility):</h3>
<p>-AI      . -Generalist   .</p>
<blockquote>
<p>Effective generalists react to that by first understanding why this odd behavior is the way it is Humility encourages the Expert Generalist to not leap into challenging things until they are sure they understand the full context</p>
</blockquote>
<p>      ?      ,       </p>
<h3 id="heading-skrnvt-mmvkdt-rkh-value-directed-curiosity"> - (Value-Directed Curiosity)</h3>
<p>   - ,         </p>
<blockquote>
<p>Customer-focus is the necessary lens to focus curiosity. Expert generalists prioritize their attention that the things that will help them help their users to excel</p>
</blockquote>
<p>-Generalist        .               .</p>
<h3 id="heading-mnvt-hhkyrh-the-art-of-inquiry">  (The Art of Inquiry)</h3>
<p>      -AI.</p>
<blockquote>
<p>Rather than just typing in some code from Stack Overflow There is an art to asking questions that elicit deeper answers without leading the witness</p>
</blockquote>
<p>   -AI   (   X),     ( -Trade-offs        ?).           </p>
<h2 id="heading-sykhvm-hmvr-myd-lyfvt">:   </h2>
<p>  Expert Generalist  ,    .     ()       AI,      ( ).</p>
<p>     ,   ,             .</p>
]]></description><link>https://thecodeline.org/expert-generalist</link><guid isPermaLink="true">https://thecodeline.org/expert-generalist</guid><category><![CDATA[Expert Generalist]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[AI]]></category><category><![CDATA[engineering-strategy]]></category><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Sat, 22 Nov 2025 21:40:52 GMT</pubDate><cover_image/></item><item><title><![CDATA[קוטלין למתכנתי ג'אווה - מבוא חלק ב']]></title><description><![CDATA[<p> ,<br />        '.<br /><a target="_blank" href="https://www.thecodeline.org/kotlin-intro-part-1"> </a>        <br />  ,    <br />       </p>
<p> ,      ,   '.</p>
<p>    ,       <a target="_blank" href="https://www.atomickotlin.com/">Atomic Kotlin</a></p>
<h3 id="heading-hvylvt-vtstym"> </h3>
<h4 id="heading-hgdrt-hvylvt"> </h4>
<p>       .<br />       .<br />                    - <code>package</code><br />:</p>
<p>Kotlin</p>
<pre><code>package com.yoururl.libraryname

<span class="hljs-comment">// Componentes to reuse...</span>
fun f() = <span class="hljs-string">"result"</span>
</code></pre><p>     components  ,   components        .<br />   component  <code>f()</code>.</p>
<p>      ,       .<br />     <code>yoururl.com</code></p>
<p>'          .<br />,   <code>com.yoururl.libraryname</code>      <code>com/yoururl/libraryname</code>.<br />    ,         '       .</p>
<h4 id="heading-ymv-vhvylvt"> </h4>
<p>     ,    -<code>import</code></p>
<p>Kotlin</p>
<pre><code><span class="hljs-keyword">import</span> com.yoururl.libraryname.*

fun main() {
  val x x = f()
}
</code></pre><p>  <code>libraryname</code>      -components   <code>libraryname</code>.<br />    component ,       -component.</p>
<h4 id="heading-atomic-test">atomic test</h4>
<p>      ,       <code>atomictest</code>.<br />   ,     .<br />   <a target="_blank" href="https://github.com/BruceEckel/AtomicKotlinExamples/blob/5bcf85b6024095a8237bb1f43448bdaf640f3c94/Examples/AtomicTest/AtomicTest.kt"></a><br />   <code>atomictest</code>,    -<code>eq</code> ( ) -<code>neq</code> (  ).</p>
<p>Kotlin</p>
<pre><code><span class="hljs-keyword">import</span> atomictest.*

fun main() {
  val pi = <span class="hljs-number">3.14</span>
  val pie = <span class="hljs-string">"A round dessert"</span>
  pi eq <span class="hljs-number">3.14</span>
  pie eq <span class="hljs-string">"A round dessert"</span>
  pi neq pie
}

<span class="hljs-comment">/* Output:
3.14
A round dessert
3.14
*/</span>
</code></pre><p>  -<code>eq</code>   <code>neq</code>      <code>infix notation</code>.<br />    <code>infix</code>  : <code>pi.eq(3.14)</code>   <code>infix notation</code>, : <code>pi eq 3.14</code>.<br />  <code>eq</code>  <code>neq</code>  assersions          .<br />,        .</p>
<p><code>atomictest.trace</code>               </p>
<p>Kotlin</p>
<pre><code><span class="hljs-keyword">import</span> atomictest.*

fun main() {
  trace(<span class="hljs-string">"Hello,"</span>)
  trace(<span class="hljs-number">47</span>)
  trace(<span class="hljs-string">"World!"</span>)
  trace eq <span class="hljs-string">""</span><span class="hljs-string">"
    Hello,
    47
    World!
  "</span><span class="hljs-string">""</span>
}
</code></pre><p>     <code>println()</code> .</p>
<h3 id="heading-vvyyktym-vkhl-mkvm">  </h3>
<p>    .<br />     <a target="_blank" href="https://en.wikipedia.org/wiki/Object-oriented_programming">Object Oriented</a>  -<a target="_blank" href="https://en.wikipedia.org/wiki/Functional_programming">Functional Programming</a>.</p>
<p>      <code>vals</code> -<code>vars</code>    (  <code>properties</code>).<br />            .</p>
<p>   <code>var</code>  <code>val</code>   ,       .</p>
<p>      -<code>container</code>  <code>collection</code>.<br />      .<br />      <code>List</code>   <code>Doubles</code>.<br /> <code>listOf()</code>  <code>List</code> </p>
<p>Kotlin</p>
<pre><code><span class="hljs-keyword">import</span> atomictest.eq

fun main() {
  val lst = listOf(<span class="hljs-number">19.2</span>, <span class="hljs-number">88.3</span>, <span class="hljs-number">22.1</span>)
  lst[<span class="hljs-number">1</span>] eq <span class="hljs-number">88.3</span> <span class="hljs-comment">// Indexing</span>
  lst.reversed() eq listOf(<span class="hljs-number">22.1</span>, <span class="hljs-number">88.3</span>, <span class="hljs-number">19.2</span>)
  lst.sorted() eq listOf(<span class="hljs-number">19.2</span>, <span class="hljs-number">22.1</span>, <span class="hljs-number">88.3</span>)
  lst.sum() eq <span class="hljs-number">129.6</span>
}
</code></pre><p>     -<code>import</code>    -<code>List</code>.<br />    <code>[]</code>      ,    -0.</p>
<p>      -<code>List</code>   out of the box,   (<code>sorted()</code>),    (<code>reversed()</code>),  (<code>sum()</code>).</p>
<p>   -<code>sorted()</code> -<code>reversed()</code>    ,       .<br />  -         -    ,       .</p>
<h3 id="heading-mhlkvt"></h3>
<p>    ,   -<code>class</code>,       .</p>
<p>Kotlin</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NoBody</span>

<span class="hljs-title">class</span> <span class="hljs-title">SomeBody</span> </span>{
  val name = <span class="hljs-string">"Shaked Eyal"</span>
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">EveryBody</span> </span>{
  val all = listOf(SomeBody(), SomeBody(), SomeBody())
}

fun main() {
  val noBody = NoBody()
  val someBody = SomeBody()
  val everyBody = EveryBody()
}
</code></pre><p> ',      ,         <br />        -<code>new</code>.<br />      .<br /> <code>SomeBody</code>    <code>String</code>  <code>EveryBody</code>     <code>List</code>   <code>SomeBody</code></p>
<p>     </p>
<p>Kotlin</p>
<pre><code>package summary_2

<span class="hljs-keyword">import</span> atomictest.eq

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Temperature</span> </span>{
    <span class="hljs-keyword">var</span> current = <span class="hljs-number">0.0</span>
    <span class="hljs-keyword">var</span> scale = <span class="hljs-string">"f"</span>

    fun setFahrenheit(now: Double) {
        current = now
        scale = <span class="hljs-string">"f"</span>
    }

    fun setCelsius(now: Double) {
        current = now
        scale = <span class="hljs-string">"c"</span>
    }

    fun getFahrenheit(): Double =
        <span class="hljs-keyword">if</span> (scale == <span class="hljs-string">"f"</span>)
            current
        <span class="hljs-keyword">else</span>
            current * <span class="hljs-number">9.0</span> / <span class="hljs-number">5.0</span> + <span class="hljs-number">32.0</span>

    fun getCelsius(): Double =
        <span class="hljs-keyword">if</span> (scale == <span class="hljs-string">"c"</span>)
            current
        <span class="hljs-keyword">else</span>
            (current - <span class="hljs-number">32.0</span>) * <span class="hljs-number">5.0</span> / <span class="hljs-number">9.0</span>
}

fun main() {
    val temp = Temperature()
    temp.setFahrenheit(<span class="hljs-number">98.6</span>)
    temp.getFahrenheit() eq <span class="hljs-number">98.6</span>
    temp.getCelsius() eq <span class="hljs-number">37.0</span>
    temp.setCelsius(<span class="hljs-number">100.0</span>)
    temp.getFahrenheit() eq <span class="hljs-number">212.0</span>
}
</code></pre><p>       <a target="_blank" href="https://www.thecodeline.org/kotlin-intro-part-1"> </a>.<br />                .</p>
<p><strong> </strong><br />   <code>temp</code>  <code>val</code>,        .<br />-<code>val</code>         -<code>temp</code>,         .</p>
<p>        </p>
<p>Kotlin</p>
<pre><code>package summary_2

<span class="hljs-keyword">import</span> atomictest.eq

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cell</span> </span>{
    <span class="hljs-keyword">var</span> entry = <span class="hljs-string">' '</span>

    fun setValue(e: Char): <span class="hljs-built_in">String</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> (entry == <span class="hljs-string">' '</span> &amp;&amp; (e == <span class="hljs-string">'X'</span> || e == <span class="hljs-string">'O'</span>)) {
            entry = e
            <span class="hljs-string">"Successful move"</span>
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-string">"Invalid move"</span>
        }
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Grid</span> </span>{
    val cells = listOf(
        listOf(Cell(), Cell(), Cell()),
        listOf(Cell(), Cell(), Cell()),
        listOf(Cell(), Cell(), Cell())
    )

    fun play(e: Char, <span class="hljs-attr">x</span>: Int, <span class="hljs-attr">y</span>: Int): <span class="hljs-built_in">String</span> =
        <span class="hljs-keyword">if</span> (x !<span class="hljs-keyword">in</span> <span class="hljs-number">0.</span><span class="hljs-number">.2</span> || y !<span class="hljs-keyword">in</span> <span class="hljs-number">0.</span><span class="hljs-number">.2</span>)
            <span class="hljs-string">"Invalid move"</span>
        <span class="hljs-keyword">else</span>
            cells[x][y].setValue(e)
}

fun main() {
    val grid = Grid()
    grid.play(<span class="hljs-string">'X'</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>) eq <span class="hljs-string">"Successful move"</span>
    grid.play(<span class="hljs-string">'X'</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>) eq <span class="hljs-string">"Invalid move"</span>
    grid.play(<span class="hljs-string">'O'</span>, <span class="hljs-number">1</span>, <span class="hljs-number">3</span>) eq <span class="hljs-string">"Invalid move"</span>
}
</code></pre><p> <code>Cell</code>  <code>entry</code>  -<code>var</code>        <code>setValue()</code>.<br />  <code>'</code>      <code>Char</code>   <code>String</code>,       <code>entry</code>     <code>Char</code>.<br /> <code>setValue()</code>   -<code>Cell</code>         <code>String</code><br /> <code>play()</code>          ,   -<code>setValue()</code>  <code>Cell</code>        .</p>
<h4 id="heading-vnym-constructors"> - Constructors</h4>
<p>     .<br /> '         .</p>
<p>          .      ,        .</p>
<p> <code>Badger</code>      ,         .<br /> <code>id</code> -<code>years</code>    .</p>
<p>        ,            .    - <code>Snake</code>  -<code>Moose</code></p>
<p>    -<code>val</code>       -<code>var</code> .</p>
<p> '     -<code>String</code>    ,   -<code>toString()</code></p>
<p>Kotlin</p>
<pre><code>package summary_2

<span class="hljs-keyword">import</span> atomictest.eq

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Badger</span>(<span class="hljs-title">id</span>: <span class="hljs-title">String</span>, <span class="hljs-title">years</span>: <span class="hljs-title">Int</span>) </span>{
    val name = id
    val age = years

    override fun toString(): <span class="hljs-built_in">String</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Badger: $name, age: $age"</span>
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Snake</span>(<span class="hljs-title">var</span> <span class="hljs-title">type</span>: <span class="hljs-title">String</span>, <span class="hljs-title">var</span> <span class="hljs-title">length</span>: <span class="hljs-title">Double</span>) </span>{
    override fun toString(): <span class="hljs-built_in">String</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Snake: $type, length: $length"</span>
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Moose</span>(<span class="hljs-title">val</span> <span class="hljs-title">age</span>: <span class="hljs-title">Int</span>, <span class="hljs-title">val</span> <span class="hljs-title">height</span>:<span class="hljs-title">Double</span>) </span>{
    override fun toString(): <span class="hljs-built_in">String</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Moose, age: $age, height: $height"</span>
    }
}

fun main() {
    Badger(<span class="hljs-string">"Bob"</span>, <span class="hljs-number">11</span>) eq <span class="hljs-string">"Badger: Bob, age: 11"</span>
    Snake(<span class="hljs-string">"Garden"</span>, <span class="hljs-number">2.4</span>) eq <span class="hljs-string">"Snake: Garden, length: 2.4"</span>
    Moose(<span class="hljs-number">16</span>, <span class="hljs-number">7.2</span>) eq <span class="hljs-string">"Moose, age: 16, height: 7.2"</span>
}
</code></pre><h3 id="heading-hgvlt-nrvt"> </h3>
<p>      -CPP  JAVA.<br />  -<code>public, private, protected, internal</code>.</p>
<p><code>public</code>  <code>private</code>    ,   .<br />   </p>
<h4 id="heading-public">public</h4>
<p>  ,       .<br />    <code>public</code>        .<br />     ,   -<code>public</code>  .</p>
<h4 id="heading-private">private</h4>
<p>  , ,   -<code>private</code>           ( )</p>
<p>  -<code>counter</code>   <code>private</code>,     "   ,     .       "     -<code>counter</code>.</p>
<p>Kotlin</p>
<pre><code>package summary_2

<span class="hljs-keyword">import</span> atomictest.trace

private <span class="hljs-keyword">var</span> count = <span class="hljs-number">0</span>

private <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Box</span>(<span class="hljs-title">val</span> <span class="hljs-title">dimension</span>: <span class="hljs-title">Int</span>) </span>{
    fun volume() =
        dimension * dimension * dimension

    override fun toString(): <span class="hljs-built_in">String</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Box volume: ${volume()}"</span>
    }
}

private fun countBox(box: Box) {
    trace(<span class="hljs-string">"$box"</span>)
    count++
}

fun countBoxes() {
    countBox(Box(<span class="hljs-number">4</span>))
    countBox(Box(<span class="hljs-number">5</span>))
}

fun main() {
    countBoxes()
    trace(<span class="hljs-string">"$count boxes"</span>)
    trace eq <span class="hljs-string">""</span><span class="hljs-string">"
        Box volume: 64
        Box volume: 125
    "</span><span class="hljs-string">""</span>.trimIndent()
}
</code></pre><p>  -<code>fuel</code> -<code>warning</code>  -<code>private</code>    <code>JetPack</code>.        <code>JetPack</code>   .</p>
<p><code>burn()</code>   -<code>private</code>,       <code>JetPack</code></p>
<p> <code>fly()</code> -<code>check()</code>   <code>public</code>      </p>
<p>Kotlin</p>
<pre><code>package summary_2

<span class="hljs-keyword">import</span> atomictest.eq

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">JetPack</span>(<span class="hljs-title">private</span> <span class="hljs-title">var</span> <span class="hljs-title">fuel</span>: <span class="hljs-title">Double</span>) </span>{
    private <span class="hljs-keyword">var</span> warning = <span class="hljs-literal">false</span>

    private fun burn() =
        <span class="hljs-keyword">if</span> (fuel - <span class="hljs-number">1</span> &lt;= <span class="hljs-number">0</span>) {
            fuel = <span class="hljs-number">0.0</span>
            warning = <span class="hljs-literal">true</span>
        } <span class="hljs-keyword">else</span> {
            fuel -= <span class="hljs-number">1</span>
        }

    public fun fly() = burn()

    fun check() =
        <span class="hljs-keyword">if</span> (warning) {
            <span class="hljs-string">"Warning"</span>
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-string">"OK"</span>
        }
}

fun main() {
    val jetPack = JetPack(<span class="hljs-number">3.0</span>)
    <span class="hljs-keyword">while</span> (jetPack.check() != <span class="hljs-string">"Warning"</span>) {
        jetPack.check() eq <span class="hljs-string">"OK"</span>
        jetPack.fly()
    }
    jetPack.check() eq <span class="hljs-string">"Warning"</span>
}
</code></pre><h4 id="heading-internal">internal</h4>
<p>       .<br />        .<br />   -<code>internal</code>         .<br />   -<code>[Gradle](https://gradle.org/)</code>  -<code>[Maven](https://maven.apache.org/)</code>       ,       .</p>
<h3 id="heading-exceptions">Exceptions</h3>
<p>   <code>toDouble()</code>,   <code>String</code> -<code>Double</code>.<br />         ?</p>
<p>Kotlin</p>
<pre><code>fun main() {
  <span class="hljs-comment">// val i = "$1.9".toDouble()</span>
}
</code></pre><p>        2,    .<br />  ,  '         ,    .<br />           -<code>stack trace</code>   .<br />-<code>atomictest</code>             </p>
<p>Kotlin</p>
<pre><code><span class="hljs-keyword">import</span> atomictest.*

fun main() {
  capture {
    <span class="hljs-string">"$1.9"</span>.toDouble()
  } eq <span class="hljs-string">"NumberFormatException: For input string: \"$1.9\""</span>
}
</code></pre>]]></description><link>https://thecodeline.org/kvtlyn-lmtkhnty-gvvh-mvv-hlk-v</link><guid isPermaLink="true">https://thecodeline.org/kvtlyn-lmtkhnty-gvvh-mvv-hlk-v</guid><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Thu, 20 Nov 2025 12:21:13 GMT</pubDate></item><item><title><![CDATA[תכנות ריאקטיבי - Reactor - יצירת רצף מותאם אישית]]></title><description><![CDATA[<p> ,<br />     Reactor   .<br />       <strong><code>Flux</code></strong>  <strong><code>Mono</code></strong>,      (<strong><code>subscribe</code></strong>)<br />      '      ,            ,   .</p>
<h3 id="heading-ytsyrh-vtsvrh-synkhrvnyt-vmtsvt-generate">    generate</h3>
<p>    <strong><code>Flux</code></strong>    <strong><code>generate</code></strong>       -<strong><code>Flux</code></strong>.</p>
<p>    ,     -   .  -sync    <strong><code>SynchronousSink</code></strong>,    <code>**next()**</code>          -callback.      -<strong><code>error(Throwable)</code></strong> -<strong><code>complete()</code></strong>,    .</p>
<p>          -state ,        .     <strong><code>BiFunction&lt;S, SynchronousSink&lt;T&gt;, S&gt;</code></strong>  <strong><code>&lt;S&gt;</code></strong>     state -<strong><code>&lt;T&gt;</code></strong>      .    <strong><code>Supplier&lt;S&gt;</code></strong>        -state,         state.</p>
<p>,    -int  -state :</p>


<p>    ,     <strong><code>generate</code></strong>      -state  0. 
 ,     -state          .             3  -state   <br />  3,      ,  .          state  -1   .<br />   .          -state     .<br /> 8,   -<strong><code>flux.doOnNext</code></strong>,      ,    -<strong><code>blockLast()</code></strong>.      ,     ,       complete   error.<br />,   -sink         ,    ,     <strong><code>sink.next()</code></strong>,            <strong><code>sink.complete()</code></strong>.</p>
<p>    :</p>
<p><strong><code>3 X 0 = 0   3 X 1 = 3   3 X 2 = 6   3 X 3 = 9   3 X 4 = 12   3 X 5 = 15   3 X 6 = 18   3 X 7 = 21   3 X 8 = 24   3 X 9 = 27   3 X 10 = 30</code></strong></p>
<p>      mutable  -state .<br />          <strong><code>AtomicLong</code></strong>  -state ,       .<br />  :</p>


<p>   ,      <strong><code>AtomicLong</code></strong>  -state .<br />,      Flux   ,         .</p>
<p>     <strong><code>generate</code></strong>,   : <strong>`</strong>generate(Supplier<s>, BiFunction, Consumer<s>)<strong>`</strong>      <code>**Consumer&lt;S&gt;**</code>    -state ,     <br />        -state .<br />     </s></s></p>


<p> ,       -state  .<br />   <strong><code>state: 11</code></strong>   2      -state       10  i,  -state  11.</p>
<h3 id="heading-ytsyrh-vtsvrh-synkhrvnyt-vmtsvt-create">    create</h3>
<p> <strong><code>create</code></strong>       <strong><code>Flux</code></strong>        ,     threads .<br />  <code>**FluxSink**</code>    <strong><code>next, error, complete</code></strong> ,  -<strong><code>generate</code></strong>   state.<br /> ,     threads    .<br />    create    API   -listeners  .</p>
<p>  <strong><code>create</code></strong>      ,    ,         .    block    -<strong><code>create</code></strong>      -deadlock  .   -<strong><code>subscribeOn</code></strong>,                ,       - <strong><code>sink.next(t)</code></strong>.       .<br />      - <strong><code>subscirbeOn(Scheduler, false)</code></strong></p>
<p>    -API   listener.    -chunks    :</p>
<ul>
<li><p>chunk   </p>
</li>
<li><p>    (terminal event)</p>
</li>
</ul>
<p>  :</p>



<p>     <strong><code>create</code></strong>       -<strong><code>Flux&lt;T&gt;</code></strong></p>



<p>  -<strong><code>EventListener&lt;String&gt;</code></strong>     -API -<strong><code>Flux&lt;T&gt;</code></strong><br />   chunk       -Flux     <strong><code>sink::next</code></strong>.    <strong><code>processComplete()</code></strong> -<strong><code>sink.complete()</code></strong><br />        -<strong><code>myEventProcessor</code></strong> .</p>
<p>,  -<code>**create**</code>    API    backpressure,          -backpressure    -<strong><code>overflowStrategy</code></strong>:</p>
<ul>
<li><p><strong><code>IGNORE</code></strong> -     </p>
</li>
<li><p><strong><code>ERROR</code></strong> -    -downstream    </p>
</li>
<li><p><strong><code>DROP</code></strong> -      -downstream    </p>
</li>
<li><p><strong><code>LATEST</code></strong> -  -downstream    </p>
</li>
<li><p><strong><code>BUFFER</code></strong> -  ,       -downstream    .</p>
</li>
</ul>
<p>               its all binary</p>
<h3 id="heading-ytsyrh-vtsvrh-synkhrvnyt-v-thread-vvdd">   -thread </h3>
<p>        <strong><code>generate()</code></strong>     <strong><code>create()</code></strong>      ,        thread   <strong><code>push()</code></strong>.<br />  -<strong><code>create</code></strong>       backpressure,    -<strong><code>push</code></strong>    thread   .  -thread     -<strong><code>next, error, complete</code></strong></p>
<p> :</p>



<p>        <strong><code>Flux</code></strong>    <strong><code>push</code></strong></p>
<h3 id="heading-mvdl-hyvrydy-l-pushpull">   push/pull</h3>
<p>    reactor,  <code>**create**</code>,    push/pull.          (     push),     pull,   .<br />-consumer       ,  -producer    -consumer   ,       .<br />    ,    <strong><code>push(), create()</code></strong>     <strong><code>onRequest</code></strong>    consumer    ,     -sink     </p>


<p>    -<strong><code>onRequest</code></strong>      ,      ,           .</p>
<h3 id="heading-nykvy-hry-create-push">  create, push</h3>
<p>            publisher  <strong><code>onDispose, onCancel</code></strong><br /> <strong><code>onDispose</code></strong>     <strong><code>Flux</code></strong>   ,  ,    .<br /> <strong><code>onCancel</code></strong>           -<strong><code>Flux</code></strong>   <strong><code>onDispose</code></strong> </p>


<h3 id="heading-hvfrtvr-handle"> handle</h3>
<p> <strong><code>handle</code></strong>   .   -instance method.           ( <strong><code>map, filter, doOnNext</code></strong> ').     <strong><code>Flux</code></strong>   <strong><code>Mono</code></strong>.</p>
<p>    <strong><code>generate</code></strong>             .            ,     .<br />       <strong><code>map</code></strong>  <strong><code>filter</code></strong> (        <a target="_blank" href="https://www.thecodeline.org/ultimate-guide-java-streams/">  </a>).<br />    <strong><code>Flux&lt;R&gt; handle(BiConsumer&lt;T, SynchronusSink&lt;R&gt;&gt;);</code></strong></p>
<p>   . -<a target="_blank" href="https://www.reactive-streams.org/">reactive streamse specification</a>    null .       -<strong><code>map</code></strong>     ,     null?<br />    :</p>


<p>  -<strong><code>handle</code></strong>      -null</p>


<p>   <strong><code>alpahbet</code></strong>      ,       null.<br />  </p>
<p><strong><code>M   I   T</code></strong></p>
<h3 id="heading-sykhvm"></h3>
<p>                  <br />      ,     threads   thread .<br />          .</p>
<p>      <a target="_blank" href="https://github.com/ShuratCode/reactiveProgramming/tree/master/src/main/java/org/reactor"></a></p>
<p> ,     ,     </p>
]]></description><link>https://thecodeline.org/tkhnvt-ryktyvy-reactor-ytsyrt-rtsf-mvtm-yyt</link><guid isPermaLink="true">https://thecodeline.org/tkhnvt-ryktyvy-reactor-ytsyrt-rtsf-mvtm-yyt</guid><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Thu, 20 Nov 2025 12:21:13 GMT</pubDate></item><item><title><![CDATA[אימוץ AI: מסע אל מערכת נתונים אחידה]]></title><description><![CDATA[<p>    ,     (AI)    </p>
]]></description><link>https://thecodeline.org/ymvts-ai-ms-l-mrkht-ntvnym-hydh</link><guid isPermaLink="true">https://thecodeline.org/ymvts-ai-ms-l-mrkht-ntvnym-hydh</guid><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Thu, 20 Nov 2025 12:21:13 GMT</pubDate></item><item><title><![CDATA[איך ליצור IAM USER ב AWS]]></title><description><![CDATA[<p> ,<br />        -cloud,       IAM User permission        -AWS  -Tufin.<br />       ,        </p>
<h3 id="heading-z-mh-zh-iam-user">   IAM USER?</h3>
<p>       AWS.<br />     AWS             ,    IAM user      .</p>
<p>     Identity and Access Management (IAM)  AWS.<br />          .</p>
<h3 id="heading-ykh-yvtsrym-yvzr-hd-v-aws">    - AWS</h3>
<p>          -AWS.<br />       <a target="_blank" href="https://aws.amazon.com/free/?all-free-tier.sort-by=item.additionalFields.SortRank&amp;all-free-tier.sort-order=asc&amp;awsf.Free%20Tier%20Types=*all&amp;awsf.Free%20Tier%20Categories=*all">  </a>  aws  ,                      -      .</p>
<p>         Bob       AWS management Console (      AWS  )</p>
<p>     :</p>
<ul>
<li><p>   <a target="_blank" href="https://signin.aws.amazon.com/">   AWS</a></p>
</li>
<li><p>   Root User (         )</p>
</li>
</ul>
<figure>

<img loading="lazy" src="/images/posts/ykh-lytsvr-iam-user-v-aws/img-1.webp" alt="   AWS" />

<figcaption>

   AWS

</figcaption>

</figure>

<ul>
<li><p>     </p>
</li>
<li><p>   <code>IAM</code>    <code>IAM</code>   </p>
</li>
</ul>
<figure>

<img loading="lazy" src="/images/posts/ykh-lytsvr-iam-user-v-aws/img-2.webp" alt="   IAM" />

<figcaption>

   IAM

</figcaption>

</figure>

<ul>
<li>    ,    <code>Users</code>   </li>
</ul>
<figure>

<img loading="lazy" src="/images/posts/ykh-lytsvr-iam-user-v-aws/img-3.webp" alt="  Users " />

<figcaption>

  Users

</figcaption>

</figure>

<ul>
<li>    <code>Create Use</code>r</li>
</ul>
<figure>

<img loading="lazy" src="/images/posts/ykh-lytsvr-iam-user-v-aws/img-4.webp" />

<figcaption>

 User 

</figcaption>

</figure>

<ul>
<li>    : Bob,       AWS Management Console   Next</li>
</ul>
<pre><code> :     AWS  canse insensitive.      Bob  BOB.
</code></pre>]]></description><link>https://thecodeline.org/ykh-lytsvr-iam-user-v-aws</link><guid isPermaLink="true">https://thecodeline.org/ykh-lytsvr-iam-user-v-aws</guid><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Thu, 20 Nov 2025 12:21:13 GMT</pubDate></item><item><title><![CDATA[קוטלין למתכנתי ג'אווה]]></title><description><![CDATA[<p> ,<br />    ,     <br />           ,      .</p>
<h3 id="heading-lmh-kvtlyn"> ?</h3>
<p>    2011,  1.0    2016. 
    <a target="_blank" href="https://www.jetbrains.com/">JetBrains</a>,     .<br /> -C++        C,           Java.        .</p>
<p>     '   ,       .<br />      '  .   ,            .</p>
<h5 id="heading-kryvt-readability"> Readability</h5>
<p>       .     ,        (    ),       .</p>
<h5 id="heading-tmykhh-vfrdygmvt-mrvvvt">  </h5>
<p>   :</p>
<ul>
<li><p><a target="_blank" href="https://he.wikipedia.org/wiki/%D7%AA%D7%9B%D7%A0%D7%95%D7%AA_%D7%90%D7%99%D7%9E%D7%A4%D7%A8%D7%98%D7%99%D7%91%D7%99"> </a></p>
</li>
<li><p><a target="_blank" href="https://he.wikipedia.org/wiki/%D7%AA%D7%9B%D7%A0%D7%95%D7%AA_%D7%A4%D7%95%D7%A0%D7%A7%D7%A6%D7%99%D7%95%D7%A0%D7%9C%D7%99"> </a></p>
</li>
<li><p><a target="_blank" href="https://he.wikipedia.org/wiki/%D7%AA%D7%9B%D7%A0%D7%95%D7%AA_%D7%9E%D7%95%D7%A0%D7%97%D7%94-%D7%A2%D7%A6%D7%9E%D7%99%D7%9D">  </a></p>
</li>
</ul>
<h5 id="heading-tmykhh-vfltfvrmvt-mrvvvt">  </h5>
<p>      </p>
<ul>
<li><p>JVM -       -bytecode ( <code>.class</code>)       JVM</p>
</li>
<li><p>Android -      - <a target="_blank" href="https://source.android.com/docs/core/runtime">ART</a>      <code>.dex</code></p>
</li>
<li><p>JavaScript -    </p>
</li>
<li><p>Native Binaries -     CPU </p>
</li>
</ul>
<h3 id="heading-hello-world">Hello, World!</h3>
<p>        ,    .<br /> ',   -<code>//</code>      <code>/* */</code>    .<br />        <code>main()</code></p>


<p> <code>println()</code>          <code>String</code> (      <code>String</code>).     -<code>String</code>  .<br />          <code>print()</code></p>
<p>    -<code>;</code>   .             </p>
<h3 id="heading-mtnym-kvvym-mtnym-vsvgy-mtnym"> ,   </h3>
<p>    ,         ,    -<code>val</code>.<br />       </p>
<p><code>val identifier: Type = value</code></p>
<p> ,         ,       .<br />      </p>
<p><code>val identifier = value</code></p>
<p>     </p>
<p><code>val daysInFebruary = 28</code><br /><code>val daysInMarch: Int =31</code></p>
<p>           ,    -<code>var</code>.<br />   ,     </p>
<p><code>var identifire1 = value</code><br /><code>var indentifier2: Type = value</code></p>
<p> -<code>val</code>       <code>var</code></p>
<p><code>var hoursSpent = 20</code><br /><code>hourSpent = 25</code></p>
<p>      -type   .<br />   </p>
<p><code>hoursSpent = 30.5</code></p>
<p> -<code>hoursSpent</code>   <code>Int</code>      <code>Float</code></p>
<h3 id="heading-fvnktsyvt"></h3>
<p>    </p>


<p> <code>fun</code>      ,        .       .<br />        .<br />        .</p>
<p>    ,       .<br />  <code>expression body</code>   </p>
<p><code>fun functionName(arg1: Type1, arg2: Type2, ..): ReturnType = result</code></p>
<p>       </p>
<p> <code>cube()</code>   ,   -<code>return</code>.<br />     <code>bang()</code>  <code>String</code></p>


<h3 id="heading-mtnym-vvlynym"> </h3>
<p>        :</p>
<ul>
<li><p>! - </p>
</li>
<li><p>&amp;&amp; - </p>
</li>
<li><p>|| - </p>
</li>
</ul>
<p>   </p>
<p>   <code>isOpen</code>   -<code>&amp;&amp;</code>.     <code>hour &gt;= opens</code>  <code>false</code>        <code>false</code>.</p>
<p>   <code>isClosed</code>   -<code>||</code>   <code>true</code>   <code>hour &lt; opens</code>  </p>


<h3 id="heading-vytvyy-if"> if</h3>
<p> <code>if-else</code>  ,     ,   .<br />    </p>
<p>    ,     -if  .</p>


<p>       .<br /> <code>activity</code>, <code>hour</code>       -<code>if</code>     .<br />      -<code>if</code>  <code>opens</code>, <code>closes</code>     .<br />    <code>true</code>    14 .</p>


<h3 id="heading-mhrvzvt"></h3>
<p>      -<code>String.format()</code>  ',     .<br />       <code>String</code>   ,    $.<br />'   <code>String Templates</code><br />   </p>
<p> 3     <code>answer</code>      .       , 42<br /> 5     ,      <code>if condition</code>      (    -$  <code>Bash</code><br /> ,  6,     $1,      1       .</p>


<p>        </p>
<p>          ,  -<code>String Templates</code> .<br /> <code>trimIndent()</code>      <br />       -escaping     -"    -<code>"""</code>.<br />-<code>String</code>      -escaping.</p>


<h3 id="heading-svgy-msfrym"> </h3>
<p>      (<code>Int</code>, <code>Long</code>)   (<code>Double</code>).<br />  ,    -<code>Int</code>,    L ,    <code>Long</code>.<br />    ,     <code>Double</code></p>


<p>  <code>Int</code>     - 231-  231-1. 
      <code>Overflow</code>,         <code>Int</code>     </p>
<p>     <code>Int</code> -<code>Int</code>,   <code>Int</code>   ,    .<br />    1/2  0. 
    <code>Double</code> ,    -<code>Int</code> -<code>Doubl</code>e    .<br /> 1.0/2  0.5<br />      </p>
<p>   <code>d1</code>    3.4,         .       2/5,   <code>Int</code>   0.     -<code>Double</code>    3.0 + 0. 
  <code>d2</code>     <code>Double</code>  <code>Int</code>     ,   .</p>


<h3 id="heading-lvlt-while"> while</h3>
<p>  ,  <code>while</code>         <code>true</code><br />            ,        .</p>


<h3 id="heading-lvlvt-vtvvhym"> </h3>
<p>           -<code>iterable</code>,      </p>
<p>      -<code>String</code>     .<br /> ,  <code>c</code>    <code>val</code>           . <code>c += 1</code>  </p>


<p>     <code>in</code> -<code>range</code><br />    -<code>range</code>   <code>..</code></p>


<h3 id="heading-vytvyym-expression-amp-statements"> Expression &amp; Statements</h3>
<p>        <code>statement</code>  <code>expression</code><br />    ,  </p>
<ul>
<li><p>-<code>statement</code>   (<code>state</code>)</p>
</li>
<li><p>-<code>expression</code>   .</p>
</li>
</ul>
<p>     <code>expression</code></p>
<p><code>val hours = 10</code><br /><code>val minutesPerHour = 60</code><br /><code>val minutes = hours * minutesPerHour</code></p>
<p>       <code>=</code>  <code>expression</code>        <br />  <code>println()</code>      ,    <code>expression</code>,       .<br />       - <code>Unit</code></p>
]]></description><link>https://thecodeline.org/kvtlyn-lmtkhnty-gvvh</link><guid isPermaLink="true">https://thecodeline.org/kvtlyn-lmtkhnty-gvvh</guid><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Thu, 20 Nov 2025 12:21:13 GMT</pubDate></item><item><title><![CDATA[תכנות ריאקטיבי איך ליצור Flux או Mono ולבצע subscribe]]></title><description><![CDATA[<p> ,<br />      reactive programming.<br /> ,     <a target="_blank" href="https://projectreactor.io/docs/">Reactor</a>,    : <strong><code>Flux</code></strong>, <strong><code>Mono</code></strong><br />       -publishers <br />         <br />    (<strong><code>subscribe()</code></strong>)     .<br /> </p>
<h3 id="heading-hrmh-lmfrsm-subscribe">  - Subscribe</h3>
<p>    -<strong><code>publisher</code></strong> -<strong><code>Reactor</code></strong><br /> <strong><code>Flux</code></strong> -<strong><code>Mono</code></strong>   <strong><code>Java 8 lambdas</code></strong>.<br />       .<br />   <strong><code>subscribe()</code></strong>         :</p>
<p><code>subscribe();   subscribe(Consumer&lt;? super T&gt; consumer);   subscribe(Consumer&lt;? super T&gt; consumer, Consumer&lt;? super Throwable&gt; errorConsumer);   subscribe(Consumer&lt;? super T&gt; consumer, Consumer&lt;? super Throwable&gt; errorConsumer, Runnable completeConsumer);   subscribe(Consumer&lt;? super T&gt; consumer,</code><br /><code>Consumer&lt;? super Throwable&gt; errorConsumer,</code><br /><code>Runnable completeConsumer,</code><br /><code>Consumer&lt;? super Subscription&gt; subscriptionConsumer);</code></p>
<p>        <br />        <br />         <br />             <br />,         -subscription    <strong><code>subscribe()</code></strong></p>
<p>  "   -subscription             .<br />    -subscription      ,      .<br />  <strong>Reactor</strong>         -<strong><code>Disposable interface</code></strong>.<br />    .</p>
<p>       <strong><code>Flux</code></strong>/<strong><code>Mono</code></strong>  </p>


<p>    <strong><code>Flux</code></strong>      - 1,2,3. 
    -<strong><code>Flux</code></strong>   .</p>
<p>       ,   .<br />        .<br />   -<strong><code>subscribe</code></strong>      .<br />       </p>


<p>    :</p>
<p><code>1   2   3</code></p>
<p>    ,     :</p>


<p>     ,     :</p>
<p>   2   <strong><code>Flux</code></strong> ,   4  - 1,2,3,4<br />     <strong><code>map</code></strong>        .<br />       <br />       .<br /> 7   -<strong><code>Flux</code></strong>   :<br />    <br />   </p>
<p>    </p>
<p><code>**1   2   3   Error: java.lang.RuntimeException: Got to 4**</code></p>
<p>        ,       </p>


<p>   -<strong><code>Flux</code></strong>      <br />   ,    -<strong><code>Flux</code></strong>       .<br />  </p>
<p><code>**1   2   3   4   Done**</code></p>
<pre><code><span class="hljs-number">1</span>
<span class="hljs-number">2</span>
<span class="hljs-number">3</span>
<span class="hljs-number">4</span>
Done
</code></pre><p>         (terminals)     .<br />,    publisher   error signal  completion signal.<br />   -completion signal      .</p>
<h3 id="heading-vytvl-subscribe-m-disposable"> subscribe  Disposable</h3>
<p>   ,    -<strong><code>subscribe</code></strong>    <strong><code>Disposable</code></strong>.<br /> , -<strong><code>Disposable</code></strong>        -subscription     <strong><code>dispose()</code></strong>.</p>
<p> <strong><code>Flux</code></strong> -<strong><code>Mono</code></strong>  cancellation signal        .<br />      ,        ,             .</p>
<p>   <strong><code>Disposable</code></strong>    <strong><code>Disposables</code></strong>. , <strong><code>Disposables.swap()</code></strong>  <strong><code>Disposable</code></strong>     <strong><code>Disposable</code></strong> .<br />   , ,   -UI               .<br />    <code>**dispose()**</code>     ',            .</p>
<p>     <strong><code>Disposables.composite()</code></strong>.        <strong><code>Disposable</code></strong>     .<br />,      ,     .    <strong><code>dispose()</code></strong>  ,    <strong><code>Disposable</code></strong>    .</p>
<h3 id="heading-ltrntyvh-l-subscribe-m-lmvdvt">  Subscribe  </h3>
<p>    <strong><code>subscribe</code></strong>,      .<br />   <strong><code>Subscriber</code></strong>   .<br /> <strong>Reactor</strong>     <strong><code>BaseSubscriber</code></strong>     <strong><code>Subscriber</code></strong> .</p>
<pre><code> !!
 -BaseSubscriber        -,   -BaseSubscriber     -publisher      -publisher .
</code></pre><p>     .    <strong><code>SampleSubscriber</code></strong>:</p>


<p> <strong><code>SampleSubscriber</code></strong>   <strong><code>BaseSubscriber</code></strong>,                Subscribers   .<br />  <strong>hooks</strong>           -<strong><code>Subscriber</code></strong>.<br /> , -<strong><code>BaseSubscriber</code></strong>   subscribe ,       .<br />,                 .</p>
<p>  ,     <strong>subscriber</strong>  -<strong>publisher</strong>, -<strong>subscriber</strong>      ,   -<strong>publisher</strong>       .</p>
<p>   -<strong>Reactor</strong>         ,     <strong><code>hookOnSubscribe(</code></strong><code>**Subscription subscription)**</code>  <strong><code>hookOnNext(T value)</code></strong>     .    <strong><code>hookOnSubscribe</code></strong>     "Subscribed"     .    ,  <strong><code>hookOnNext</code></strong> ,       ,    .</p>
<p>    -<strong><code>SampleSubscriber</code></strong>  <code>**Flux**</code>:</p>


<p>   </p>
<p><code>Subscribed   1   2   3   4</code></p>
<p>-<strong><code>BaseSubscriber</code></strong>      <strong><code>requestUnbounded()</code></strong>       ,   -<strong><code>subscribe()</code></strong> (  -<strong><code>request(Long.MAX_VALUE)</code></strong>),    <code>**cancel()**</code>.</p>
<p>      <strong><code>hookOnComplete</code></strong>, <strong><code>hookOnError</code></strong>, <strong><code>hookOnCancel</code></strong>  <strong><code>hookFinally</code></strong> (    ,      <strong><code>SignalType</code></strong>).</p>
<p>      <strong><code>hookOnError</code></strong>, <strong><code>hookOnCancel</code></strong>  <strong><code>hookOnComplete</code></strong>. 
-<code>**SampleSubscriber**</code>       </p>
<h3 id="heading-backpressure-vdrkhym-lynvy-vkvt">Backpressure   </h3>
<p>         backpressure?</p>
<blockquote>
<p><strong>Back pressure</strong> (or <strong>backpressure</strong>) is a resistance or force opposing the desired flow of fluid through pipes, leading to <a target="_blank" href="https://en.wikipedia.org/wiki/Friction_loss">friction loss</a> and <a target="_blank" href="https://en.wikipedia.org/wiki/Pressure_drop">pressure drop</a>.<br />The term <em>back pressure</em> is a <a target="_blank" href="https://en.wikipedia.org/wiki/Misnomer">misnomer</a>, as <a target="_blank" href="https://en.wikipedia.org/wiki/Pressure">pressure</a> is a <a target="_blank" href="https://en.wikipedia.org/wiki/Scalar_\(physics\)">scalar quantity</a>, so it has a magnitude but no direction.</p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Back_pressure">Wikipedia</a></p>
</blockquote>
<p> ,     publisher    ,  subscriber     .<br />  backpressure  -publisher   -subscriber .</p>
<p>   backpressure -<strong>Reactor</strong>, -subscriber  <strong><code>request</code></strong>  -publisher (   ,     ).<br />"    ""  " ".       <code>**Long.MAX_VALUE**</code>,     .     -publisher   "    ",     -backpressure.</p>
<p>-<strong><code>request</code></strong>   -subscriber    ,    ,     subscription     -backpressure.<br />:</p>
<ul>
<li><p><strong><code>subscribe()</code></strong>      .</p>
</li>
<li><p>  <strong><code>block(), blockFirst(), blockLast()</code></strong> (   )</p>
</li>
<li><p><strong><code>toIterable(), toStream()</code></strong></p>
</li>
</ul>
<p>      ,       <strong><code>hookOnSubscribe</code></strong>  <strong><code>BaseSubscriber</code></strong>   </p>


<p>      .<br /> <strong><code>doOnRequest</code></strong>    -Flux        .<br />   -<strong><code>BaseSubscriber</code></strong>   .<br />  subscription     -publisher,           .</p>
<p>  :</p>
<p><code>**request of 1   Cancelling after having received 1**</code></p>
<p>      subscriber     ,        -publisher  ,  -<strong><code>Flux</code></strong>  "".
     <strong><code>BaseSubscriber</code></strong>   .</p>
<h3 id="heading-sykhvm"></h3>
<p>        <strong>Reactor</strong><br />     <strong><code>Flux</code></strong>  <strong><code>Mono</code></strong>      subscription .<br />,      subscription   .<br />     subscriber ,            -backpressure.</p>
<p> ,              .<br /> ,    ,     .</p>
]]></description><link>https://thecodeline.org/tkhnvt-ryktyvy-ykh-lytsvr-flux-v-mono-vlvts-subscribe</link><guid isPermaLink="true">https://thecodeline.org/tkhnvt-ryktyvy-ykh-lytsvr-flux-v-mono-vlvts-subscribe</guid><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Thu, 20 Nov 2025 12:21:13 GMT</pubDate></item><item><title><![CDATA[מבוא ללמידת מכונה]]></title><description><![CDATA[<p><img loading="lazy" src="/images/posts/mvv-llmydt-mkhvnh/img-1.webp" /></p>
<p> ,<br />      -AI,  ,        .<br />   ,         .<br /> <a target="_blank" href="https://www.thecodeline.org/tufin-hackathon-2024/"> </a>     AI  <a target="_blank" href="https://www.tufin.com">Tufin</a>,         .<br />       </p>
<p>        ,              .</p>
<p>          <a target="_blank" href="https://www.coursera.org/instructor/andrewng">Andrew Ng</a></p>
<h3 id="heading-mh-zh-lmydt-mkhvnh">   </h3>
<p>      machine learning  AI,     ?     ?<br /> ,    ,       .</p>
<p>            <a target="_blank" href="https://en.wikipedia.org/wiki/Arthur_Samuel_\(computer_scientist\)">Arthur Samuel</a></p>
<blockquote>
<p>Field of study that gives computers the ability to learn without being explicitly programmed</p>
<p>Arthur Samuel</p>
</blockquote>
<p>  ,           .</p>
<p>    Arthur         .        ,        ,  ,             .</p>
<p>       .      10       .<br /><strong>  </strong></p>
<h3 id="heading-svgym-l-lmydt-mkhvnh">   </h3>
<p>      :</p>
<ul>
<li><p>  - supervised learning</p>
</li>
<li><p>   - unsupervised learning</p>
</li>
</ul>
<p>   ,         .</p>
<p>     </p>
<h4 id="heading-lmydh-mfvkht-supervised-learning">  - Supervised Learning</h4>
<p>             X  Y.<br />       ()  " " ()     .<br />       X  -Y  .</p>
<h5 id="heading-dvgmvt"></h5>
<p>          :</p>
<ul>
<li><p>   -                   (0  1).</p>
</li>
<li><p>  -        (audio)   .</p>
</li>
<li><p>      ( )   ().</p>
</li>
</ul>
<p>      .           .<br />                             .</p>
<p>    ,       ,         .</p>
<p> <a target="_blank" href="https://www.appliedmaterials.com/">Applied Materials</a>           .</p>
<p>         .    X -Y      (       ,     '),             .</p>
<h5 id="heading-rgrsyh-regression"> - Regression</h5>
<p>   supervised learning    <a target="_blank" href="https://en.wikipedia.org/wiki/Regression_analysis"></a>.<br />          </p>
<h6 id="heading-thzyt-l-mhyry-vtym">   </h6>
<p>            .<br />      </p>
<figure>

<img loading="lazy" src="/images/posts/mvv-llmydt-mkhvnh/img-2.webp" alt="      " />

<figcaption>

     

</figcaption>

</figure>

<p> -X    ,  -Y     .<br />            750?<br />  ,           ,          </p>
<figure>

<img loading="lazy" src="/images/posts/mvv-llmydt-mkhvnh/img-3.webp" alt="    " />

<figcaption>

    

</figcaption>

</figure>

<p>       ,         :</p>
<figure>

<img loading="lazy" src="/images/posts/mvv-llmydt-mkhvnh/img-4.webp" alt="      " />

<figcaption>

      

</figcaption>

</figure>

<p>        ,      -scope .<br />  ,          (-Y  )      .</p>
<h5 id="heading-syvvg-classification"> - Classification</h5>
<p>    supervised learning   .<br />      .</p>
<h6 id="heading-syvvg-l-gydvlym">  </h6>
<p>                  .<br /> </p>
<p>            .<br />        :</p>
<figure>

|   |  |
| --- | --- |
| 2 | 0 |
| 5 | 1 |
| 1 | 0 |
| 7 | 1 |

<figcaption>

   

</figcaption>

</figure>

<p>  0       -1  .<br />      :</p>
<figure>

<img loading="lazy" src="/images/posts/mvv-llmydt-mkhvnh/img-5.webp" />

<figcaption>

    

</figcaption>

</figure>

<p>  -X    ,  -Y        .           .<br />           .<br />         (class)  .</p>
<p>           (  ),          .</p>
<h6 id="heading-l-rk-vynry">  </h6>
<p>                  </p>
<figure>

<img loading="lazy" src="/images/posts/mvv-llmydt-mkhvnh/img-6.webp" />

<figcaption>

     

</figcaption>

</figure>

<p>         ,   , 0  1. 
       .<br />           ,       .<br />       :</p>
<figure>

<img loading="lazy" src="/images/posts/mvv-llmydt-mkhvnh/img-7.webp" />

<figcaption>

      

</figcaption>

</figure>

<p>       ,       .<br />     ,      .</p>
<h6 id="heading-yvtr-mklt-hd">  </h6>
<p>      ,      .<br />             :</p>
<figure>

<img loading="lazy" src="/images/posts/mvv-llmydt-mkhvnh/img-8.webp" />

<figcaption>

     

</figcaption>

</figure>

<p>        .<br />              X    O</p>
<figure>

<img loading="lazy" src="/images/posts/mvv-llmydt-mkhvnh/img-9.webp" />

<figcaption>

    

</figcaption>

</figure>

<h5 id="heading-sykhvm-supervised-learning"> Supervised Learning</h5>
<p>     " "</p>
<p>     supervised learning:</p>
<ul>
<li><p></p>
<ul>
<li><p>  ()</p>
</li>
<li><p>     </p>
</li>
</ul>
</li>
<li><p></p>
<ul>
<li><p>    </p>
</li>
<li><p>      </p>
</li>
</ul>
</li>
</ul>
]]></description><link>https://thecodeline.org/mvv-llmydt-mkhvnh</link><guid isPermaLink="true">https://thecodeline.org/mvv-llmydt-mkhvnh</guid><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Thu, 20 Nov 2025 12:21:13 GMT</pubDate></item><item><title><![CDATA[יסודות איתנים: בניית שרת API איכותי ב-Node.js עם Express ו-TypeScript]]></title><description><![CDATA[<h3 id="heading-mlk">;</h3>
<p>   ,      Node.js.      :        (boileplate) , ,    Express -TypeScript.      ,    Best Practices  .</p>
<h3 id="heading-hkdmh-lmh-lnsvt-mhv-hd"> -    ?</h3>
<p>,            API.  ,       :     ,     -,           ?</p>
<p>       <a target="_blank" href="https://www.thecodeline.org/pragmatic-programmer-timeless-lessons/">"The Pragmatic Programmer"</a>       .      ,     -ecosystem     ,    ,    -         .</p>
<p> :        .       -backend : <strong>Node.js   TypeScript -Express.</strong></p>
<p>      .          ,    ,  .   Best Practices     ,  ,  .              .</p>
<p>      -     API .</p>
<h3 id="heading-vny-hvnyyn-skyrt-htlvyvt-dependencies-hmrkhzyvt">  -   (Dependencies) </h3>
<p>    ,      .  Node.js       </p>
<h4 id="heading-express">Express</h4>
<p>     . Express  micro-framework          HTTP,  (routing),  -Middleware.       ,          .</p>
<h4 id="heading-typescript-v-ts-node">TypeScript -TS-Node</h4>
<p> JavaScript   , TypeScript     ,    .     (types)   JavaScript,         (compilation)    (runtime). <code>ts-node</code>        TypeScript ,     -JavaScript    /</p>
<h4 id="heading-rvyyyt-h-middleware-hhyvnyt"> -Middleware </h4>
<ul>
<li><p><code>helmet</code>:   <code>helmet</code>     .    (<code>app.use(helmet())</code>),        HTTP headers        XSS, Clickjacking .         .</p>
</li>
<li><p><code>cors</code> (Cross-Origin Resource Sharing) :  -web , -frontend  (  React     ) -backend ( -API    -AWS)   .  ,      . <code>cors</code>  -Middleware             -API .</p>
</li>
<li><p><code>compression</code>:        :   ( Gzip)    (response body)   . ? payload  ,   ,    ,   .</p>
</li>
<li><p><code>morgan</code>:     . <code>morgan</code>  logger   HTTP.        -    (GET/POST),   (URL),   -status code       .    -debugging   .</p>
</li>
</ul>
<h3 id="heading-h-pipeline-vfvlh-hvnt-middleware">-Pipeline :  Middleware</h3>
<p>  Middleware       Express.        .   HTTP        .  ,     ( -Middlewares).      :  ,  ,  ,      .</p>
<p>     -Middlewares  <code>app.use()</code>  ,        .       :</p>
<ol>
<li><p><code>app.use(helmet())</code>:    .            .</p>
</li>
<li><p><code>app.use(cors())</code>:   ,    .      ,     .</p>
</li>
<li><p><code>app.use(compression())</code>: </p>
</li>
<li><p><code>app.use(morgan('combined')</code>:       ,      .  <code>combined</code>    ,   <strong>     Apache</strong>.</p>
</li>
<li><p><code>app.use(express.json())</code>:   .      (body)   JSON,  ,       JavaScript   <code>req.body</code>.      ,      POST  PUT .</p>
</li>
</ol>
<p>       -Middleware ,        - -Route Handler.</p>
<p><img loading="lazy" src="/images/posts/ysvdvt-ytnym-vnyyt-rt-api-ykhvty-v-nodejs-m-express-v-typescript/img-1.webp" /></p>
<h3 id="heading-hgdrt-ntyvym-routes-nkvdvt-hktsh-l-h-api">  (Routes) -    -API</h3>
<p>   ,       (Endpoints) -API   . -Express,      <code>app.post()</code>, <code>app.get()</code> .</p>
<p>   Route  :</p>
<p>TypeScript</p>
<pre><code>app.get(<span class="hljs-string">'/path'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-comment">// Business logic here</span>
});
</code></pre><pre><code>app.get(<span class="hljs-string">'/path'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-comment">// Business logic here</span>
});
</code></pre><p>    :</p>
<ul>
<li><p><strong> (Path)</strong>:  -URL  -Endpoint ( <code>'api/users/</code>).</p>
</li>
<li><p><strong>-Handler</strong>:  (callback)     (<code>req</code>)   (<code>res</code>).</p>
<ul>
<li><p><code>req</code> (Request):         - headers,  -URL,  , .</p>
</li>
<li><p><code>res</code> (Response):       .       -status code ( <code>res.status(200)</code>),     ( <code>res.json({ message: 'Success' })</code>.</p>
</li>
</ul>
</li>
</ul>
<p>   endpoint   <code>/health</code></p>
<p>TypeScript</p>
<pre><code>app.get5(<span class="hljs-string">'/health'</span>, <span class="hljs-function">(<span class="hljs-params">_req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({
    <span class="hljs-attr">status</span>: <span class="hljs-string">'ok'</span>,
    <span class="hljs-attr">uptime</span>: process.uptime(),
  });
});
</code></pre><pre><code>app.get5(<span class="hljs-string">'/health'</span>, <span class="hljs-function">(<span class="hljs-params">_req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">200</span>).json({
    <span class="hljs-attr">status</span>: <span class="hljs-string">'ok'</span>,
    <span class="hljs-attr">uptime</span>: process.uptime(),
  });
});
</code></pre><p>-endpoint     nice to have,  best practice   .   Kubernetes  -Health Checks ( liveness and readiness probes)         .  -endpoint        200,          .</p>
<h3 id="heading-nyhvl-gyvt-lmktsvnym">  </h3>
<p>          .         </p>
<h4 id="heading-tyfvl-v-404-not-found"> -404 (Not Found):</h4>
<p>      -<code>api/non-existent-route</code>?    ,      timeout.   , <em></em>  -routes ,          -routes  :</p>
<p>TypeScript</p>
<pre><code>app.use(<span class="hljs-string">'*'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">404</span>).json({
    <span class="hljs-attr">error</span>: <span class="hljs-string">'Not Found'</span>,
    <span class="hljs-attr">message</span>: <span class="hljs-string">`The requested URL <span class="hljs-subst">${req.originalUrl}</span> was not found on this server.`</span>,
  });
});
</code></pre><pre><code>app.use(<span class="hljs-string">'*'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.status(<span class="hljs-number">404</span>).json({
    <span class="hljs-attr">error</span>: <span class="hljs-string">'Not Found'</span>,
    <span class="hljs-attr">message</span>: <span class="hljs-string">`The requested URL <span class="hljs-subst">${req.originalUrl}</span> was not found on this server.`</span>,
  });
});
</code></pre><p> (<code>*</code>)  -<code>wildcard</code>  .    ,      route     .</p>
<h4 id="heading-h-global-error-handler">-Global Error Handler:</h4>
<p>     <em></em>  -Route Handlers ? ,         ?    ,   <code>Node.js</code>     .</p>
<p>   -Middleware   .         (<code>err, req, res, next</code>):</p>
<p>TypeScript</p>
<pre><code>app.use(<span class="hljs-function">(<span class="hljs-params">err: <span class="hljs-built_in">Error</span>, _req, res, _next</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error:'</span>, err.stack) <span class="hljs-comment">//Log the full error for debugging</span>

  <span class="hljs-comment">// Send a generic message in production to avoid leaking detail</span>
  <span class="hljs-keyword">const</span> message = process.env.[NODE_ENV] === <span class="hljs-string">'development'</span>
    ? err.message
    : <span class="hljs-string">'An unexpected error occurred.'</span>;

  res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">'Internal Server Error'</span>, message });
});
</code></pre><pre><code>app.use(<span class="hljs-function">(<span class="hljs-params">err: <span class="hljs-built_in">Error</span>, _req, res, _next</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error:'</span>, err.stack) <span class="hljs-comment">//Log the full error for debugging</span>

  <span class="hljs-comment">// Send a generic message in production to avoid leaking detail</span>
  <span class="hljs-keyword">const</span> message = process.env.[NODE_ENV] === <span class="hljs-string">'development'</span>
    ? err.message
    : <span class="hljs-string">'An unexpected error occurred.'</span>;

  res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">'Internal Server Error'</span>, message });
});
</code></pre><p>        ,    (    ),    500   .     :  ,         -debugging.  prod,              .</p>
<h3 id="heading-hdlkt-hvrvt-vmh-hlh">   ?</h3>
<p>        ,            -   .</p>
<p>TypeScript</p>
<pre><code><span class="hljs-keyword">if</span> (process.env[NODE_ENV] !== <span class="hljs-string">'test'</span>) {
  app.listen(PORT, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server is running on http://localhost:<span class="hljs-subst">${PORT}</span>`</span>);
  }
}
&lt;div&gt;&lt;/div&gt;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> app;
</code></pre><pre><code><span class="hljs-keyword">if</span> (process.env[NODE_ENV] !== <span class="hljs-string">'test'</span>) {
  app.listen(PORT, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server is running on http://localhost:<span class="hljs-subst">${PORT}</span>`</span>);
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> app;
</code></pre><p>       HTTP    .   ?    (integration tests),      -<code>app</code>       (    <code>supertest</code>),         .  <code>export default app</code>      .</p>
<h4 id="heading-sykhvm-htvvnvt"> :</h4>
<p>     -"Hello World.    :</p>
<ul>
<li><p><strong> </strong>   Middleware.</p>
</li>
<li><p><strong> </strong>  .</p>
</li>
<li><p><strong> </strong> .</p>
</li>
<li><p><strong>  </strong>  </p>
</li>
<li><p><strong>  </strong>   .</p>
</li>
</ul>
<h4 id="heading-htsdym-hvym"> :</h4>
<p>     . ,        .      -unit testing   ,    node.js    .<br />             .</p>
]]></description><link>https://thecodeline.org/ysvdvt-ytnym-vnyyt-rt-api-ykhvty-v-nodejs-m-express-v-typescript</link><guid isPermaLink="true">https://thecodeline.org/ysvdvt-ytnym-vnyyt-rt-api-ykhvty-v-nodejs-m-express-v-typescript</guid><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Sun, 05 Oct 2025 00:00:00 GMT</pubDate></item><item><title><![CDATA[Factory vs. Repository ב-Domain Driven Design: מה ההבדל ולמה זה קריטי?]]></title><description><![CDATA[<h3 id="heading-mlk">;</h3>
<p>, <strong>Factory</strong>      Aggregates    . <strong>Repository</strong>      Aggregates   persistence ( database),   -Aggregate  .      ,        .</p>
<hr />
<h3 id="heading-hkdmh"></h3>
<p><a target="_blank" href="https://www.thecodeline.org/ddd/"> </a>  -DDD,     Aggregates      .      (Entities, Value Objects)       (Invariants) .</p>
<p>        :</p>
<ol>
<li><p>   Aggregate   ,         ?</p>
</li>
<li><p>     -Aggregates   ,        ?</p>
</li>
</ol>
<p>    Patterns   -DDD: -<strong>Factory</strong> -<strong>Repository</strong>.   ,        ,   .   </p>
<hr />
<h3 id="heading-dfvs-h-factory-mlkht-hytsyrh"> -Factory:  </h3>
<p>  Factory -DDD   : <strong>       Aggregates .</strong>     ?         -<code>new Object()</code>.</p>
<p>  Aggregate  <code>Order</code> ().     :</p>
<ul>
<li><p>   (ID).</p>
</li>
<li><p>    (     ).</p>
</li>
<li><p>   ( Pending").</p>
</li>
<li><p>     .</p>
</li>
</ul>
<p>     (Invariants)    <em></em>.      -constructor  <code>Order</code>    . -Factory        ,  ,   <code>Order</code>     .</p>
<p>Kotlin</p>
<pre><code><span class="hljs-keyword">import</span> java.util.UUID
&lt;div&gt;&lt;/div&gt;
<span class="hljs-comment">// Value Objects for Type Safety</span>
data <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OrderId</span>(<span class="hljs-title">val</span> <span class="hljs-title">value</span>: <span class="hljs-title">String</span>)
<span class="hljs-title">data</span> <span class="hljs-title">class</span> <span class="hljs-title">CustomerId</span>(<span class="hljs-title">val</span> <span class="hljs-title">value</span>: <span class="hljs-title">String</span>)
&lt;<span class="hljs-title">div</span>&gt;&lt;/<span class="hljs-title">div</span>&gt;
// <span class="hljs-title">Other</span> <span class="hljs-title">domain</span> <span class="hljs-title">classes</span>...
<span class="hljs-title">data</span> <span class="hljs-title">class</span> <span class="hljs-title">Product</span>(<span class="hljs-title">val</span> <span class="hljs-title">id</span>: <span class="hljs-title">String</span>, <span class="hljs-title">val</span> <span class="hljs-title">price</span>: <span class="hljs-title">Double</span>, <span class="hljs-title">private</span> <span class="hljs-title">val</span> <span class="hljs-title">inStock</span>: <span class="hljs-title">Boolean</span>) </span>{
    fun isInStock() = inStock
}
data <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Customer</span>(<span class="hljs-title">val</span> <span class="hljs-title">id</span>: <span class="hljs-title">CustomerId</span>, <span class="hljs-title">private</span> <span class="hljs-title">val</span> <span class="hljs-title">active</span>: <span class="hljs-title">Boolean</span>) </span>{
    fun isActive() = active
}
data <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LineItem</span>(<span class="hljs-title">val</span> <span class="hljs-title">productId</span>: <span class="hljs-title">String</span>, <span class="hljs-title">val</span> <span class="hljs-title">price</span>: <span class="hljs-title">Double</span>)
&lt;<span class="hljs-title">div</span>&gt;&lt;/<span class="hljs-title">div</span>&gt;
<span class="hljs-title">enum</span> <span class="hljs-title">class</span> <span class="hljs-title">OrderStatus</span> </span>{
    PENDING, SHIPPED, CANCELED
}
&lt;div&gt;&lt;/div&gt;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Order</span> <span class="hljs-title">private</span> <span class="hljs-title">constructor</span>(
    <span class="hljs-title">val</span> <span class="hljs-title">id</span>: <span class="hljs-title">OrderId</span>,
    <span class="hljs-title">val</span> <span class="hljs-title">customerId</span>: <span class="hljs-title">CustomerId</span>,
    <span class="hljs-title">initialItems</span>: <span class="hljs-title">List</span>&lt;<span class="hljs-title">LineItem</span>&gt;
) </span>{
    private val _lineItems: MutableList&lt;LineItem&gt; = initialItems.toMutableList()
    val lineItems: List&lt;LineItem&gt; get() = _lineItems.toList()
&lt;div&gt;&lt;/div&gt;
    <span class="hljs-keyword">var</span> status: OrderStatus = OrderStatus.PENDING
        private set
&lt;div&gt;&lt;/div&gt;
    companion object {
        fun createNew(customer: Customer, <span class="hljs-attr">initialItem</span>: Product): Order {

            <span class="hljs-comment">// Enforcing invariants (business rules)</span>
            <span class="hljs-built_in">require</span>(customer.isActive()) { <span class="hljs-string">"Cannot create order for an inactive customer."</span> }
            <span class="hljs-built_in">require</span>(initialItem.isInStock()) { <span class="hljs-string">"Cannot create order with an out-of-stock item."</span> }
&lt;div&gt;&lt;/div&gt;
            val newOrderId = OrderId(UUID.randomUUID().toString())
            val firstLineItem = LineItem(initialItem.id, initialItem.price)

            <span class="hljs-keyword">return</span> Order(newOrderId, customer.id, listOf(firstLineItem))
        }
    }
&lt;div&gt;&lt;/div&gt;
    fun ship() {
        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.status == OrderStatus.PENDING) {
            <span class="hljs-built_in">this</span>.status = OrderStatus.SHIPPED
        }
    }
}
</code></pre><pre><code><span class="hljs-keyword">import</span> java.util.UUID

<span class="hljs-comment">// Value Objects for Type Safety</span>
data <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OrderId</span>(<span class="hljs-title">val</span> <span class="hljs-title">value</span>: <span class="hljs-title">String</span>)
<span class="hljs-title">data</span> <span class="hljs-title">class</span> <span class="hljs-title">CustomerId</span>(<span class="hljs-title">val</span> <span class="hljs-title">value</span>: <span class="hljs-title">String</span>)

// <span class="hljs-title">Other</span> <span class="hljs-title">domain</span> <span class="hljs-title">classes</span>...
<span class="hljs-title">data</span> <span class="hljs-title">class</span> <span class="hljs-title">Product</span>(<span class="hljs-title">val</span> <span class="hljs-title">id</span>: <span class="hljs-title">String</span>, <span class="hljs-title">val</span> <span class="hljs-title">price</span>: <span class="hljs-title">Double</span>, <span class="hljs-title">private</span> <span class="hljs-title">val</span> <span class="hljs-title">inStock</span>: <span class="hljs-title">Boolean</span>) </span>{
    fun isInStock() = inStock
}
data <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Customer</span>(<span class="hljs-title">val</span> <span class="hljs-title">id</span>: <span class="hljs-title">CustomerId</span>, <span class="hljs-title">private</span> <span class="hljs-title">val</span> <span class="hljs-title">active</span>: <span class="hljs-title">Boolean</span>) </span>{
    fun isActive() = active
}
data <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LineItem</span>(<span class="hljs-title">val</span> <span class="hljs-title">productId</span>: <span class="hljs-title">String</span>, <span class="hljs-title">val</span> <span class="hljs-title">price</span>: <span class="hljs-title">Double</span>)

<span class="hljs-title">enum</span> <span class="hljs-title">class</span> <span class="hljs-title">OrderStatus</span> </span>{
    PENDING, SHIPPED, CANCELED
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Order</span> <span class="hljs-title">private</span> <span class="hljs-title">constructor</span>(
    <span class="hljs-title">val</span> <span class="hljs-title">id</span>: <span class="hljs-title">OrderId</span>,
    <span class="hljs-title">val</span> <span class="hljs-title">customerId</span>: <span class="hljs-title">CustomerId</span>,
    <span class="hljs-title">initialItems</span>: <span class="hljs-title">List</span>&lt;<span class="hljs-title">LineItem</span>&gt;
) </span>{
    private val _lineItems: MutableList&lt;LineItem&gt; = initialItems.toMutableList()
    val lineItems: List&lt;LineItem&gt; get() = _lineItems.toList()

    <span class="hljs-keyword">var</span> status: OrderStatus = OrderStatus.PENDING
        private set

    companion object {
        fun createNew(customer: Customer, <span class="hljs-attr">initialItem</span>: Product): Order {

            <span class="hljs-comment">// Enforcing invariants (business rules)</span>
            <span class="hljs-built_in">require</span>(customer.isActive()) { <span class="hljs-string">"Cannot create order for an inactive customer."</span> }
            <span class="hljs-built_in">require</span>(initialItem.isInStock()) { <span class="hljs-string">"Cannot create order with an out-of-stock item."</span> }

            val newOrderId = OrderId(UUID.randomUUID().toString())
            val firstLineItem = LineItem(initialItem.id, initialItem.price)

            <span class="hljs-keyword">return</span> Order(newOrderId, customer.id, listOf(firstLineItem))
        }
    }

    fun ship() {
        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.status == OrderStatus.PENDING) {
            <span class="hljs-built_in">this</span>.status = OrderStatus.SHIPPED
        }
    }
}
</code></pre><p> , -<code>Factory</code>    <code>createNew</code>   <code>Order</code> .        <code>Order</code>   .</p>
<hr />
<h3 id="heading-dfvs-h-repository-r-lvlm-hdth"> -Repository:   </h3>
<p>  <code>Order</code> ,    .  ,       -.  -Repository  .</p>
<p>  <strong>Repository</strong>       (-Aggregates)   -persistence ( , ,   ).       <strong>   </strong>.          -MongoDB, PostgreSQL   CSV.    -Repository  -<code>Order</code>  .</p>
<p>-Repository      :</p>
<ul>
<li><p><code>getById(id)</code>:  Aggregate </p>
</li>
<li><p><code>save(aggregate)</code>:  Aggregate (    ).</p>
</li>
<li><p><code>findBySomeCriteria(...)</code>:    Aggregates    .</p>
</li>
</ul>
<p>Kotlin</p>
<pre><code>interface OrderRepository {
  fun findById(orderId: OrderId): Order?
  fun save(order: Order)
  fun findPendingOrdersForCustomer(customerId: CustomerId): List&lt;Order&gt;
}
</code></pre><pre><code>interface OrderRepository {
  fun findById(orderId: OrderId): Order?
  fun save(order: Order)
  fun findPendingOrdersForCustomer(customerId: CustomerId): List&lt;Order&gt;
}
</code></pre><hr />
<h3 id="heading-hhvdl-hkryty-vhsynrgyh-vynyhm"> ,  </h3>
<p>   ?</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong></strong></td><td>Factory</td><td>Repository</td></tr>
</thead>
<tbody>
<tr>
<td><strong></strong></td><td>  <strong></strong>  </td><td>    <strong></strong></td></tr>
<tr>
<td><strong></strong></td><td> ,  </td><td> (ID)   </td></tr>
<tr>
<td><strong></strong></td><td>Aggregate ,   </td><td>Aggregate   ( )</td></tr>
<tr>
<td><strong> </strong></td><td>  </td><td>   </td></tr>
</tbody>
</table>
</div><p>    Factory -Repository       DDD .</p>
<ul>
<li><p> -<strong>Factory</strong>          ,      .</p>
</li>
<li><p> -<strong>Repository</strong>                 -Aggregates .</p>
</li>
</ul>
<p>      ;    ,   ,         .</p>
]]></description><link>https://thecodeline.org/factory-vs-repository-v-domain-driven-design-mh-hhvdl-vlmh-zh-kryty</link><guid isPermaLink="true">https://thecodeline.org/factory-vs-repository-v-domain-driven-design-mh-hhvdl-vlmh-zh-kryty</guid><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Sun, 17 Aug 2025 00:00:00 GMT</pubDate></item><item><title><![CDATA[מ-Fat Interface ל-Fine Interface: איך עקרון ה-ISP ישדרג לכם את הארכיטקטורה]]></title><description><![CDATA[<h3 id="heading-mlk">;</h3>
<ul>
<li><p><strong>:</strong>   (Fat Interfaces)          .    ,   .</p>
</li>
<li><p><strong>:</strong>    (ISP) :          .    ,      .</p>
</li>
<li><p><strong></strong>:   , ,    (low coupling)       </p>
</li>
</ul>
<hr />
<h3 id="heading-ftyh"></h3>
<p>  :  <code>IWhateverService</code>  15 ,         .  ?       <code>NoImplementedException</code>?<br /> ,    (Fat Interface),      ,   (coupling)    .         - Interface Segregation Principle (ISP),    -SOLID    .</p>
<h3 id="heading-hvyh-mmkym-mnym-fat-interaces">:   (Fat Interaces)</h3>
<p>        ,           -clients    .               .      ,      <code>Exception</code>   .</p>
<p> ,    coupling     .          ,               ,       .                  .</p>
<h3 id="heading-hftrvn-the-interface-segregation-principle-isp">: The Interface Segregation Principle (ISP)</h3>
<p> -ISP  :</p>
<blockquote>
<p>           .</p>
</blockquote>
<p>      ,    (cohesive)      .             .</p>
<h3 id="heading-dvgmt-kvd-mtyvryh-lkvd-nky"> :   </h3>
<p>    .<br />      microservices.          ,     .</p>
<h4 id="heading-lfny-isp-mmk-repository-khlvvynyk"> ISP:  Repository </h4>
<p>     , <code>IUserRepository</code>,   </p>
<p>Kotlin</p>
<pre><code><span class="hljs-comment">// Fat interface that contains read, write, and cache management actions</span>
interface UserRepository {
  fun getUserById(id: <span class="hljs-built_in">String</span>): User
  fun findUsersByCountry(countryCode: <span class="hljs-built_in">String</span>): List&lt;User&gt;
  fun saveUser(user: User)
  fun deleteUser(id: <span class="hljs-built_in">String</span>)
  fun invalidateCacheForUser(id: <span class="hljs-built_in">String</span>)
}
</code></pre><pre><code><span class="hljs-comment">// Fat interface that contains read, write, and cache management actions</span>
interface UserRepository {
  fun getUserById(id: <span class="hljs-built_in">String</span>): User
  fun findUsersByCountry(countryCode: <span class="hljs-built_in">String</span>): List&lt;User&gt;
  fun saveUser(user: User)
  fun deleteUser(id: <span class="hljs-built_in">String</span>)
  fun invalidateCacheForUser(id: <span class="hljs-built_in">String</span>)
}
</code></pre><p>     .     :</p>
<ol>
<li><p><strong>  (Reporting Service):</strong>        .        .</p>
</li>
<li><p><strong>   (User Management Service):</strong>     - , ,   cache.</p>
</li>
</ol>
<p>      :</p>
<p>Kotlin</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ReportingUserRepository</span>(<span class="hljs-title">private</span> <span class="hljs-title">val</span> <span class="hljs-title">dbConnection</span>: <span class="hljs-title">DbConnection</span>) : <span class="hljs-title">UserRepository</span> </span>{
&lt;div&gt;&lt;/div&gt;
    override fun getUserById(id: <span class="hljs-built_in">String</span>): User {
        <span class="hljs-comment">// logic to read from DB</span>
        println(<span class="hljs-string">"Fetching user $id for report"</span>)
        <span class="hljs-keyword">return</span> User(id, <span class="hljs-string">"Test User"</span>)
    }
&lt;div&gt;&lt;/div&gt;
    override fun findUsersByCountry(countryCode: <span class="hljs-built_in">String</span>): List&lt;User&gt; {
        <span class="hljs-comment">// login to read from DB</span>
        println(<span class="hljs-string">"Fetching users from $countryCode for report"</span>)
        <span class="hljs-keyword">return</span> listOf()
    }
&lt;div&gt;&lt;/div&gt;
    <span class="hljs-comment">// The real problem</span>
    override fun saveUser(user: User) {
        <span class="hljs-keyword">throw</span> UnsupportedOperationException(<span class="hljs-string">"Reporting repository is read-only!"</span>)
    }
&lt;div&gt;&lt;/div&gt;
    override fun deleteUser(id: <span class="hljs-built_in">String</span>) {
        <span class="hljs-keyword">throw</span> UnsupportedOperationException(<span class="hljs-string">"Reporting repository is read-only!"</span>)
    }
&lt;div&gt;&lt;/div&gt;
    override fun invalidateCacheForUser(id: <span class="hljs-built_in">String</span>) {
       <span class="hljs-comment">// Leave empty? That is confusing </span>
    }
}
</code></pre><pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ReportingUserRepository</span>(<span class="hljs-title">private</span> <span class="hljs-title">val</span> <span class="hljs-title">dbConnection</span>: <span class="hljs-title">DbConnection</span>) : <span class="hljs-title">UserRepository</span> </span>{

    override fun getUserById(id: <span class="hljs-built_in">String</span>): User {
        <span class="hljs-comment">// logic to read from DB</span>
        println(<span class="hljs-string">"Fetching user $id for report"</span>)
        <span class="hljs-keyword">return</span> User(id, <span class="hljs-string">"Test User"</span>)
    }

    override fun findUsersByCountry(countryCode: <span class="hljs-built_in">String</span>): List&lt;User&gt; {
        <span class="hljs-comment">// login to read from DB</span>
        println(<span class="hljs-string">"Fetching users from $countryCode for report"</span>)
        <span class="hljs-keyword">return</span> listOf()
    }

    <span class="hljs-comment">// The real problem</span>
    override fun saveUser(user: User) {
        <span class="hljs-keyword">throw</span> UnsupportedOperationException(<span class="hljs-string">"Reporting repository is read-only!"</span>)
    }

    override fun deleteUser(id: <span class="hljs-built_in">String</span>) {
        <span class="hljs-keyword">throw</span> UnsupportedOperationException(<span class="hljs-string">"Reporting repository is read-only!"</span>)
    }

    override fun invalidateCacheForUser(id: <span class="hljs-built_in">String</span>) {
       <span class="hljs-comment">// Leave empty? That is confusing </span>
    }
}
</code></pre><p>  :</p>
<ul>
<li><p>     read-only  ( )  .</p>
</li>
<li><p>          ,     .</p>
</li>
<li><p>     ?      ,      .</p>
</li>
</ul>
<h4 id="heading-hry-isp-hfrdt-hryvt-vhrvh-kt-nfy"> ISP:   (  )</h4>
<p>  ,      ,   CORS (Command Query Responsibility Segregation)</p>
<p>Kotlin</p>
<pre><code><span class="hljs-comment">// Specific interface for reading actions (Query)</span>
interface UserReader {
  fun getUserById(id: <span class="hljs-built_in">String</span>): User
  fun findUserByCountry(countryCode: <span class="hljs-built_in">String</span>): List&lt;User&gt;
}
&lt;div&gt;&lt;/div&gt;
<span class="hljs-comment">// Specific interface for write actions (Command)</span>
interface UserWriter {
  fun saveUser(user: User)
  fun deleteUser(id: <span class="hljs-built_in">String</span>)
}
&lt;div&gt;&lt;/div&gt;
<span class="hljs-comment">// Specific interface for manage cache</span>
interface CacheManager {
    fun invalidateCahceForUser(id: <span class="hljs-built_in">String</span>)
}
</code></pre><pre><code><span class="hljs-comment">// Specific interface for reading actions (Query)</span>
interface UserReader {
  fun getUserById(id: <span class="hljs-built_in">String</span>): User
  fun findUserByCountry(countryCode: <span class="hljs-built_in">String</span>): List&lt;User&gt;
}

<span class="hljs-comment">// Specific interface for write actions (Command)</span>
interface UserWriter {
  fun saveUser(user: User)
  fun deleteUser(id: <span class="hljs-built_in">String</span>)
}

<span class="hljs-comment">// Specific interface for manage cache</span>
interface CacheManager {
    fun invalidateCahceForUser(id: <span class="hljs-built_in">String</span>)
}
</code></pre><p>     ,  :</p>
<p>Kotlin</p>
<pre><code><span class="hljs-comment">// Implement the read-only repo</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ReportingUserRepository</span>(<span class="hljs-title">private</span> <span class="hljs-title">val</span> <span class="hljs-title">dbConnection</span>: <span class="hljs-title">DbConnection</span>) : <span class="hljs-title">UserReader</span> </span>{
    override fun getUserById(id: <span class="hljs-built_in">String</span>): User {
        println(<span class="hljs-string">"Fetching user $id for report"</span>)
        <span class="hljs-keyword">return</span> User(id, <span class="hljs-string">"Test User"</span>)
    }
&lt;div&gt;&lt;/div&gt;
    override fun findUsersByCountry(countryCode: <span class="hljs-built_in">String</span>): List&lt;User&gt; {
        println(<span class="hljs-string">"Fetching users from $countryCode for report"</span>)
        <span class="hljs-keyword">return</span> listOf()
    }
}
&lt;div&gt;&lt;/div&gt;

<span class="hljs-comment">//Implement the full repo for the read-write and cache</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FullUserRepository</span>(<span class="hljs-title">private</span> <span class="hljs-title">val</span> <span class="hljs-title">dbConnection</span>: <span class="hljs-title">DbConnection</span>) : <span class="hljs-title">UserReader</span>, <span class="hljs-title">UserWriter</span>, <span class="hljs-title">CacheManager</span> </span>{

    override fun getUserById(id: <span class="hljs-built_in">String</span>): User { <span class="hljs-comment">/* ... */</span> <span class="hljs-keyword">return</span> User(id, <span class="hljs-string">""</span>) }
    override fun findUsersByCountry(countryCode: <span class="hljs-built_in">String</span>): List&lt;User&gt; { <span class="hljs-comment">/* ... */</span> <span class="hljs-keyword">return</span> listOf() }

    override fun saveUser(user: User) { <span class="hljs-comment">/* ... */</span> }
    override fun deleteUser(id: <span class="hljs-built_in">String</span>) { <span class="hljs-comment">/* ... */</span> }
&lt;div&gt;&lt;/div&gt;
    override fun invalidateCacheForUser(id: <span class="hljs-built_in">String</span>) { <span class="hljs-comment">/* ... */</span> }
}
</code></pre><pre><code><span class="hljs-comment">// Implement the read-only repo</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ReportingUserRepository</span>(<span class="hljs-title">private</span> <span class="hljs-title">val</span> <span class="hljs-title">dbConnection</span>: <span class="hljs-title">DbConnection</span>) : <span class="hljs-title">UserReader</span> </span>{
    override fun getUserById(id: <span class="hljs-built_in">String</span>): User {
        println(<span class="hljs-string">"Fetching user $id for report"</span>)
        <span class="hljs-keyword">return</span> User(id, <span class="hljs-string">"Test User"</span>)
    }

    override fun findUsersByCountry(countryCode: <span class="hljs-built_in">String</span>): List&lt;User&gt; {
        println(<span class="hljs-string">"Fetching users from $countryCode for report"</span>)
        <span class="hljs-keyword">return</span> listOf()
    }
}

<span class="hljs-comment">//Implement the full repo for the read-write and cache</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FullUserRepository</span>(<span class="hljs-title">private</span> <span class="hljs-title">val</span> <span class="hljs-title">dbConnection</span>: <span class="hljs-title">DbConnection</span>) : <span class="hljs-title">UserReader</span>, <span class="hljs-title">UserWriter</span>, <span class="hljs-title">CacheManager</span> </span>{

    override fun getUserById(id: <span class="hljs-built_in">String</span>): User { <span class="hljs-comment">/* ... */</span> <span class="hljs-keyword">return</span> User(id, <span class="hljs-string">""</span>) }
    override fun findUsersByCountry(countryCode: <span class="hljs-built_in">String</span>): List&lt;User&gt; { <span class="hljs-comment">/* ... */</span> <span class="hljs-keyword">return</span> listOf() }

    override fun saveUser(user: User) { <span class="hljs-comment">/* ... */</span> }
    override fun deleteUser(id: <span class="hljs-built_in">String</span>) { <span class="hljs-comment">/* ... */</span> }

    override fun invalidateCacheForUser(id: <span class="hljs-built_in">String</span>) { <span class="hljs-comment">/* ... */</span> }
}
</code></pre><p>    .       <strong> </strong>  <code>UserReader</code>,               .   ,     .</p>
<h3 id="heading-hrvvh-hnky-lmh-zh-khl-khkh-mtlm"> :     ?</h3>
<p>  -ISP    :</p>
<ul>
<li><p><strong>Decoupling:</strong> -ISP     -coupling    .    ,    ( client )        .</p>
</li>
<li><p><strong> :</strong>          ,  .        ,         .</p>
</li>
<li><p><strong>Clarity &amp; Reusability</strong>:              .        ,          .</p>
</li>
</ul>
<hr />
<h3 id="heading-sykhvm"></h3>
<p> -Interface Segregation Principle     ,   .                 (   ).</p>
<p>       ,     :            ?.    ,      .             </p>
]]></description><link>https://thecodeline.org/m-fat-interface-l-fine-interface-ykh-krvn-h-isp-ydrg-lkhm-t-hrkhytktvrh</link><guid isPermaLink="true">https://thecodeline.org/m-fat-interface-l-fine-interface-ykh-krvn-h-isp-ydrg-lkhm-t-hrkhytktvrh</guid><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Sun, 10 Aug 2025 00:00:00 GMT</pubDate></item><item><title><![CDATA[פאטרן Acyclic Visitor: לשבור את מעגל התלות של Visitor]]></title><description><![CDATA[<p>   , Design Patterns      .  -Visitor       ,    ,    .     ,         : -Acyclic Visitor.</p>
<h3 id="heading-mlk">;</h3>
<p> -Visitor             .           <em></em>   ;       -Visitors .  <strong>Acyclic Visitor</strong>         .          ,             .</p>
<h3 id="heading-lmh-vkhll-tsrykh-visitor-tzkhvrt-l-hftrn-hklsy">   Visitor?    </h3>
<p>  .    <strong></strong> (<code>Assets</code>)   .     <code>Apartment</code>, <code>Car</code>, <code>Salary</code>.</p>
<p>,        .</p>
<ul>
<li><p><strong> </strong>:      <code>calculateArnonna()</code>, <code>calculateIncomeTax()</code> .          .</p>
</li>
<li><p><strong> -Visitor</strong>:    <strong></strong> ( ) <strong></strong> ().  <code>Visitor</code>  , , <code>IncomeTaxVisitor</code>. -Visitor         .</p>
</li>
</ul>
<p> :          ,   Visitor .      .</p>
<hr />
<h3 id="heading-hsdk-vysvdvt-hvyh-hmrkhzyt-vftrn-visitor-hklsy">  -    Visitor </h3>
<p>  ?         ,   .</p>
<p>          : <code>CryptocurrencyWallet</code> ( ).</p>
<p> -Visitors     ,       <code>Visitor</code>:</p>
<p>Kotlin</p>
<pre><code><span class="hljs-comment">// Before</span>
interface Visitor {
  fun visit(apt: Apartment)
  fun visit(salary: Salary)
  fun visit(car: Car)
}
&lt;div&gt;&lt;/div&gt;
<span class="hljs-comment">// After adding new asset</span>
interface Visitor {
    fun visit(apt: Apartment)
    fun visit(salary: Salary)
    fun visit(cw: CryptocurrencyWallet) <span class="hljs-comment">//this line breaks all implements</span>
}
</code></pre><pre><code><span class="hljs-comment">// Before</span>
interface Visitor {
  fun visit(apt: Apartment)
  fun visit(salary: Salary)
  fun visit(car: Car)
}

<span class="hljs-comment">// After adding new asset</span>
interface Visitor {
    fun visit(apt: Apartment)
    fun visit(salary: Salary)
    fun visit(cw: CryptocurrencyWallet) <span class="hljs-comment">//this line breaks all implements</span>
}
</code></pre><p>   <code>visit(CryptocurrencyWallet)</code>,   . <strong></strong> -Visitors   - <code>ArnonaVisitor</code>, <code>IncomeTaxVisitor</code>   - !          ,           .</p>
<p> <strong> </strong> (Cyclic Dependency).  <code>Element</code>       .</p>
<hr />
<h3 id="heading-hftrvn-hkhyrv-t-acyclic-visitor"> -   Acyclic Visitor</h3>
<p>       (Uncle Bob).           -<a target="_blank" href="https://www.thecodeline.org/isp/">Interface Segregation Principle</a>  .</p>
<p>  <code>Visitor</code>        :</p>
<ul>
<li><p>  <code>Visitor</code>  <strong></strong> (Marker Interface).</p>
</li>
<li><p>  <code>Asset</code> ( <code>Apartment</code>)   <code>Visitor</code>    ( <code>ApartmentVisitor</code>)</p>
</li>
<li><p>-<code>Concrete Visitors</code>     -Visitors       .</p>
</li>
</ul>
<p>,      -Visitor,  -Visitor  .   .</p>
<h3 id="heading-ykh-hksm-vvd-mvt-lvmk-hmymv">  ?   </h3>
<p>     <strong>Double Dispatch</strong>      . -<code>accept</code>     <code>Visitor</code> ,     ( <code>dynamic_cast</code>)  -Visitor  .</p>
<ul>
<li><p>    -&gt;  -Visitor     ,    -<code>visit</code> .</p>
</li>
<li><p>   -&gt;  -Visitor     .    .</p>
</li>
</ul>
<p>       .</p>
<h3 id="heading-vvv-nkhtvv-kvd-dvgmh-myt">   -  </h3>
<p> ,        .         Acyclic Visitor</p>
<h4 id="heading-lv-hgdrt-mhlkvt-vsysyt"> :   </h4>
<p>Kotlin</p>
<pre><code><span class="hljs-comment">// Empty and basic Visitor. Use for marker</span>
interface Visitor
&lt;div&gt;&lt;/div&gt;
<span class="hljs-comment">// Basic interface for all assets</span>
interface Asset {
  fun accept(visitor: Visitor)
}
</code></pre><pre><code><span class="hljs-comment">// Empty and basic Visitor. Use for marker</span>
interface Visitor

<span class="hljs-comment">// Basic interface for all assets</span>
interface Asset {
  fun accept(visitor: Visitor)
}
</code></pre><h4 id="heading-lv-v-hgdrt-hnkhsym-elements-vh-visitors-hsftsyfyym-lhm"> :   (Elements) -Visitors  </h4>
<p>Kotlin</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Apartment</span> : <span class="hljs-title">Asset</span> </span>{

  <span class="hljs-comment">// Specific visitor interface for the Apartment asset</span>
  interface ApartmentVisitor : Visitor {
    fun visit(apt: Apartment)
  }

  override fun accept(visitor: Visitor) {
    <span class="hljs-comment">// The magic: </span>
    <span class="hljs-keyword">if</span> (visitor is ApartmentVisitor) {
      visitor.visit(<span class="hljs-built_in">this</span>)
    }
  }
}
&lt;div&gt;&lt;/div&gt;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StockPortfolio</span> : <span class="hljs-title">Asset</span> </span>{
&lt;div&gt;&lt;/div&gt;
  interface StockPortfolioVisitor : Visitor {
    fun visit(sp: StockPortfolio)
  }

  override fun accept(visitor: Visitor) {
    <span class="hljs-keyword">if</span> (visitor is StockPortfolioVisitor) {
      visitor.visit(<span class="hljs-built_in">this</span>)
    }
  }
}
&lt;div&gt;&lt;/div&gt;
<span class="hljs-comment">// Implemnt other assets</span>
</code></pre><pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Apartment</span> : <span class="hljs-title">Asset</span> </span>{

  <span class="hljs-comment">// Specific visitor interface for the Apartment asset</span>
  interface ApartmentVisitor : Visitor {
    fun visit(apt: Apartment)
  }

  override fun accept(visitor: Visitor) {
    <span class="hljs-comment">// The magic: </span>
    <span class="hljs-keyword">if</span> (visitor is ApartmentVisitor) {
      visitor.visit(<span class="hljs-built_in">this</span>)
    }
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StockPortfolio</span> : <span class="hljs-title">Asset</span> </span>{

  interface StockPortfolioVisitor : Visitor {
    fun visit(sp: StockPortfolio)
  }

  override fun accept(visitor: Visitor) {
    <span class="hljs-keyword">if</span> (visitor is StockPortfolioVisitor) {
      visitor.visit(<span class="hljs-built_in">this</span>)
    }
  }
}

<span class="hljs-comment">// Implemnt other assets</span>
</code></pre><h4 id="heading-lv-g-mymv-gvfy-hmysvy-concrete-visitors"> :    (Concrete Visitors)</h4>
<p>Kotlin</p>
<pre><code><span class="hljs-comment">// The IRS is interesetd in the Salary and StockProtfolio</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IncomeTaxVisitor</span> : <span class="hljs-title">Salary</span>.<span class="hljs-title">SalaryVisitor</span>, <span class="hljs-title">StockPortfolio</span>.<span class="hljs-title">StockPortfolioVisitor</span> </span>{

  override fun visit (sl: Salary) {
    println(<span class="hljs-string">"IRS: calculate tax for salary"</span>)
  }

  override fun visit(sp: StockPortfolio) {
    println(<span class="hljs-string">"IRS: calculate tax for stock portfolio"</span>)
  }
}
</code></pre><pre><code><span class="hljs-comment">// The IRS is interesetd in the Salary and StockProtfolio</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IncomeTaxVisitor</span> : <span class="hljs-title">Salary</span>.<span class="hljs-title">SalaryVisitor</span>, <span class="hljs-title">StockPortfolio</span>.<span class="hljs-title">StockPortfolioVisitor</span> </span>{

  override fun visit (sl: Salary) {
    println(<span class="hljs-string">"IRS: calculate tax for salary"</span>)
  }

  override fun visit(sp: StockPortfolio) {
    println(<span class="hljs-string">"IRS: calculate tax for stock portfolio"</span>)
  }
}
</code></pre><h4 id="heading-lv-d-rg-hmt-hvsfh-l-nkhs-hd-lmrkht"> :   -     </h4>
<p>Kotlin```
class CryptocurrencyWallet : Asset {
  interface CryptoVisitor : Visitor {
    fun visit(cw: CryptoCurrencyWallet)
  }</p>
<p>  override fun accept(visitor: Visitor) {
    if (visitor is CryptoVisitor) {
      visitor.visit(this)
    }
  }
}</p>
<pre><code>
</code></pre><p>class CryptocurrencyWallet : Asset {
  interface CryptoVisitor : Visitor {
    fun visit(cw: CryptoCurrencyWallet)
  }</p>
<p>  override fun accept(visitor: Visitor) {
    if (visitor is CryptoVisitor) {
      visitor.visit(this)
    }
  }
}</p>
<pre><code>
   - <span class="hljs-string">`IncomeTaxVisitor`</span>    -asset 

Kotlin
</code></pre><p>class IncomeTaxVisitor : Salary.SalaryVisitor, StockPortfolio.StockPortfolioVisitor, CryptocurrencyWallet.CryptoVisitor {</p>
<p>  override fun visit (sl: Salary) {
    println("IRS: calculate tax for salary")
  }</p>
<p>  override fun visit(sp: StockPortfolio) {
    println("IRS: calculate tax for stock portfolio")
  }</p>
<p>  // new
  override fun visit(vw: CryptocurrencyWallet) {
    println("IRS: calculate tax for crypto profits")
  }
}</p>
<pre><code>
</code></pre><p>class IncomeTaxVisitor : Salary.SalaryVisitor, StockPortfolio.StockPortfolioVisitor, CryptocurrencyWallet.CryptoVisitor {</p>
<p>  override fun visit (sl: Salary) {
    println("IRS: calculate tax for salary")
  }</p>
<p>  override fun visit(sp: StockPortfolio) {
    println("IRS: calculate tax for stock portfolio")
  }</p>
<p>  // new
  override fun visit(vw: CryptocurrencyWallet) {
    println("IRS: calculate tax for crypto profits")
  }
}</p>
<pre><code>
####  :   

Kotlin
</code></pre><p>fun main() {
  val assets: List = listof(Apartment(), StockPortfolio(), Salary(), CryptocurrencyWallet())</p>
<p>  val arnona = ArnonaVisitor()
  for (asset in assets) {
    asset.accept(arnona) // print only for Apatment
  }</p>
<p>  val incomeTax = IncomeTaxVisitor()
  for (asset in assets) {
    asset.accept(incomeTax) // print for all assets beside Apartment
  }
}</p>
<pre><code>
</code></pre><p>fun main() {
  val assets: List = listof(Apartment(), StockPortfolio(), Salary(), CryptocurrencyWallet())</p>
<p>  val arnona = ArnonaVisitor()
  for (asset in assets) {
    asset.accept(arnona) // print only for Apatment
  }</p>
<p>  val incomeTax = IncomeTaxVisitor()
  for (asset in assets) {
    asset.accept(incomeTax) // print for all assets beside Apartment
  }
}
```</p>
<hr />
<h3 id="heading-nytvh-ytrvnvt-hsrvnvt-vtryyd-vfs"> - ,  -</h3>
<p>    ,    -</p>
<h4 id="heading-ytrvnvt"></h4>
<ul>
<li><p><strong> </strong>:   <code>Element</code>     .</p>
</li>
<li><p><strong>  </strong>:       -Elements -Visitors.</p>
</li>
<li><p><strong>  SOLID</strong>:  -Open/Close Principle -<a target="_blank" href="https://www.thecodeline.org/isp/">Interface Segregation Principle</a>.</p>
</li>
</ul>
<h4 id="heading-hsrvnvt"></h4>
<ul>
<li><p><strong> Compile-Time Saftey</strong>:  ,    . ,      .</p>
</li>
<li><p><strong> -Boilerplate</strong>:      .</p>
</li>
<li><p><strong>  ( )</strong>: -<code>dynamic_cast</code>     .</p>
</li>
</ul>
<hr />
<h3 id="heading-sykhvm-hnkvdvt-hmrkhzyvt-lkht-hvyth"> -    </h3>
<p>  Visitor  -Acyclic Visitor           .</p>
<ul>
<li><p>  <strong></strong>  ,     <strong></strong>  - -Visitor    ,  .</p>
</li>
<li><p>  <strong></strong> ,     <strong></strong>    - Acyclic Visitor   ,     .</p>
</li>
</ul>
<p>     -Visitor,   :    ,   ?.<br />      .</p>
]]></description><link>https://thecodeline.org/ftrn-acyclic-visitor-lvvr-t-mgl-htlvt-l-visitor</link><guid isPermaLink="true">https://thecodeline.org/ftrn-acyclic-visitor-lvvr-t-mgl-htlvt-l-visitor</guid><dc:creator><![CDATA[Shaked Eyal]]></dc:creator><pubDate>Sun, 03 Aug 2025 00:00:00 GMT</pubDate></item></channel></rss>