Full Code of xpinjection/design-patterns for AI

master c35bff7755d0 cached
104 files
56.5 KB
16.4k tokens
335 symbols
1 requests
Download .txt
Repository: xpinjection/design-patterns
Branch: master
Commit: c35bff7755d0
Files: 104
Total size: 56.5 KB

Directory structure:
gitextract_v3o3f7e_/

├── LICENSE
├── README.md
├── libs/
│   └── lombok-1.16.10.jar
└── src/
    └── com/
        └── xpinjection/
            └── patterns/
                ├── adapter/
                │   ├── ModernAdapterClient.java
                │   └── canonical/
                │       ├── AdapterClient.java
                │       ├── CharCounterTask.java
                │       └── ExecutorConsumerAdaptor.java
                ├── builder/
                │   ├── FutureBuilderClient.java
                │   ├── FutureCluster.java
                │   ├── LombokBuilderClient.java
                │   ├── LombokCluster.java
                │   └── canonical/
                │       ├── BuilderClient.java
                │       └── Cluster.java
                ├── chain/
                │   ├── ModernAuthRequestHandler.java
                │   ├── ModernChainClient.java
                │   └── canonical/
                │       ├── AbstractRequestHandler.java
                │       ├── AuthRequestHandler.java
                │       ├── ChainClient.java
                │       ├── LoggingRequestHandler.java
                │       ├── Request.java
                │       └── RequestHandler.java
                ├── command/
                │   ├── ModernCommandClient.java
                │   ├── ModernMacro.java
                │   └── canonical/
                │       ├── BoldCommand.java
                │       ├── Command.java
                │       ├── CommandClient.java
                │       ├── Document.java
                │       ├── Editor.java
                │       ├── ItalicCommand.java
                │       ├── Macro.java
                │       └── UnderlineCommand.java
                ├── decorator/
                │   ├── ModernDecoratorClient.java
                │   └── canonical/
                │       ├── BenchmarkingDigitCounter.java
                │       ├── DecoratorClient.java
                │       ├── DigitCounter.java
                │       └── NaiveDigitCounter.java
                ├── factorymethod/
                │   ├── ModernFactoryMethodClient.java
                │   └── canonical/
                │       ├── Document.java
                │       ├── DocumentFactory.java
                │       ├── FactoryMethodClient.java
                │       ├── JsonDocument.java
                │       └── JsonDocumentFactory.java
                ├── iterator/
                │   ├── ModernIteratorClient.java
                │   ├── ModernMultilineText.java
                │   ├── ModernText.java
                │   └── canonical/
                │       ├── IteratorClient.java
                │       ├── LineIterator.java
                │       ├── MultilineText.java
                │       └── Text.java
                ├── observer/
                │   ├── ModernObserver.java
                │   ├── ModernObserverClient.java
                │   ├── ModernTimeServer.java
                │   └── canonical/
                │       ├── Event.java
                │       ├── EventListener.java
                │       ├── LoggingEventListener.java
                │       ├── Observer.java
                │       ├── ObserverClient.java
                │       └── TimeServer.java
                ├── prototype/
                │   ├── Stats.java
                │   ├── StatsProcessor.java
                │   ├── TrafficStats.java
                │   └── canonical/
                │       ├── Circle.java
                │       ├── Editor.java
                │       ├── Figure.java
                │       ├── PrototypeClient.java
                │       └── Rectangle.java
                ├── proxy/
                │   ├── ModernProxyClient.java
                │   ├── PermissionChecker.java
                │   ├── canonical/
                │   │   ├── Order.java
                │   │   ├── OrderService.java
                │   │   ├── PermissionCheckingOrderServiceProxy.java
                │   │   ├── ProxyClient.java
                │   │   └── RealOrderService.java
                │   └── spring-context.xml
                ├── singleton/
                │   ├── ModernServiceRegistry.java
                │   ├── ModernSingletonClient.java
                │   ├── canonical/
                │   │   ├── NamedService.java
                │   │   ├── ServiceRegistry.java
                │   │   └── SingletonClient.java
                │   └── spring-context.xml
                ├── strategy/
                │   ├── ModernStrategyClient.java
                │   ├── TrafficCalculationStrategies.java
                │   └── canonical/
                │       ├── PageTrafficCalculator.java
                │       ├── Position.java
                │       ├── StrategyClient.java
                │       ├── TopTrafficCalculator.java
                │       └── TrafficCalculator.java
                ├── templatemethod/
                │   ├── LoggingUserStorage.java
                │   ├── ModernTemplateMethodClient.java
                │   ├── ModernUserRestorer.java
                │   └── canonical/
                │       ├── AbstractUserRestorer.java
                │       ├── LoggingUserRestorer.java
                │       ├── TemplateMethodClient.java
                │       └── User.java
                └── visitor/
                    ├── LambdaVisitor.java
                    ├── ModernVisitorClient.java
                    └── canonical/
                        ├── AreaVisitor.java
                        ├── Circle.java
                        ├── Element.java
                        ├── PerimeterVisitor.java
                        ├── Rectangle.java
                        ├── Square.java
                        ├── Visitor.java
                        └── VisitorClient.java

================================================
FILE CONTENTS
================================================

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2017-2025 XP Injection

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# design-patterns
Modern view on classic design patterns implementation in Java

[blog article](http://javaday.org.ua/modern-view-of-design-patterns-in-java/)


================================================
FILE: src/com/xpinjection/patterns/adapter/ModernAdapterClient.java
================================================
package com.xpinjection.patterns.adapter;

import com.xpinjection.patterns.adapter.canonical.CharCounterTask;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;

/**
 * @author Alimenkou Mikalai
 */
public class ModernAdapterClient {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(3);

        AtomicInteger counter = new AtomicInteger();
        Stream.of("af", "bdf", "c")
                .map(s -> new CharCounterTask(s, counter))
                .forEach(executor::execute);

        executor.shutdown();
        executor.awaitTermination(1, TimeUnit.SECONDS);
        System.out.println("Total count: " + counter.get());
    }
}


================================================
FILE: src/com/xpinjection/patterns/adapter/canonical/AdapterClient.java
================================================
package com.xpinjection.patterns.adapter.canonical;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;

/**
 * @author Alimenkou Mikalai
 */
public class AdapterClient {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(3);

        AtomicInteger counter = new AtomicInteger();
        Stream.of("af", "bdf", "c")
                .map(s -> new CharCounterTask(s, counter))
                .forEach(new ExecutorConsumerAdaptor(executor));

        executor.shutdown();
        executor.awaitTermination(1, TimeUnit.SECONDS);
        System.out.println("Total count: " + counter.get());
    }
}


================================================
FILE: src/com/xpinjection/patterns/adapter/canonical/CharCounterTask.java
================================================
package com.xpinjection.patterns.adapter.canonical;

import java.util.concurrent.atomic.AtomicInteger;

/**
* @author Alimenkou Mikalai
* @version 1.0
*/
public class CharCounterTask implements Runnable {
    private final String str;
    private final AtomicInteger counter;

    public CharCounterTask(String str, AtomicInteger counter) {
        this.str = str;
        this.counter = counter;
    }

    @Override
    public void run() {
        counter.addAndGet(str.length());
    }
}


================================================
FILE: src/com/xpinjection/patterns/adapter/canonical/ExecutorConsumerAdaptor.java
================================================
package com.xpinjection.patterns.adapter.canonical;

import java.util.concurrent.Executor;
import java.util.function.Consumer;

/**
 * @author Alimenkou Mikalai
 */
public class ExecutorConsumerAdaptor implements Consumer<Runnable> {
    private final Executor executor;

    public ExecutorConsumerAdaptor(Executor executor) {
        this.executor = executor;
    }

    @Override
    public void accept(Runnable task) {
        executor.execute(task);
    }
}


================================================
FILE: src/com/xpinjection/patterns/builder/FutureBuilderClient.java
================================================
package com.xpinjection.patterns.builder;

/**
 * @author Alimenkou Mikalai
 */
public class FutureBuilderClient {
    /** With hope for better Java ;)
     *
     * public static void main(String[] args) {
     *      FutureCluster cluster = new FutureCluster("localhost").setPort(3165)
     *                .setRetryAttempts(3).setMetricsEnabled(false);
     * }
     */
}


================================================
FILE: src/com/xpinjection/patterns/builder/FutureCluster.java
================================================
package com.xpinjection.patterns.builder;

/**
 * @author Alimenkou Mikalai
 */
public class FutureCluster {
    /** With hope for better Java ;)
     *
     * property String[] hosts;
     * property int port;
     * property int retryAttempts;
     * property boolean metricsEnabled;
     *
     */
}


================================================
FILE: src/com/xpinjection/patterns/builder/LombokBuilderClient.java
================================================
package com.xpinjection.patterns.builder;

/**
 * @author Alimenkou Mikalai
 */
public class LombokBuilderClient {
    public static void main(String[] args) {
        LombokCluster cluster = LombokCluster.builder()
                .host("localhost").port(3165)
                .retryAttempts(3).metricsEnabled(false).build();
    }
}


================================================
FILE: src/com/xpinjection/patterns/builder/LombokCluster.java
================================================
package com.xpinjection.patterns.builder;

import lombok.Builder;
import lombok.Getter;
import lombok.Singular;

import java.util.List;

/**
 * @author Alimenkou Mikalai
 */
@Builder
@Getter
public class LombokCluster {
    @Singular private List<String> hosts;
    private int port;
    private int retryAttempts;
    private boolean metricsEnabled;
}


================================================
FILE: src/com/xpinjection/patterns/builder/canonical/BuilderClient.java
================================================
package com.xpinjection.patterns.builder.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class BuilderClient {
    public static void main(String[] args) {
        Cluster cluster = Cluster.runtimeBuilder()
                .addContactPoints("localhost").withPort(3165)
                .withRetryAttempts(3)
                .withoutMetrics().build();

        cluster = Cluster.storingBuilder()
                .addContactPoints("localhost").withPort(3165)
                .withRetryAttempts(3)
                .withoutMetrics().build();
    }
}


================================================
FILE: src/com/xpinjection/patterns/builder/canonical/Cluster.java
================================================
package com.xpinjection.patterns.builder.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class Cluster {
    private String[] hosts;
    private int port;
    private int retryAttempts;
    private boolean metricsEnabled;

    public static StoringBuilder storingBuilder() {
        return new StoringBuilder();
    }

    public static RuntimeBuilder runtimeBuilder() {
        return new RuntimeBuilder();
    }

    public Cluster(String[] hosts, int port) {
        this.hosts = hosts;
        this.port = port;
    }

    public Cluster() {
    }

    public void setHosts(String... hosts) {
        this.hosts = hosts;
    }

    public String[] getHosts() {
        return hosts;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public int getPort() {
        return port;
    }

    public void setRetryAttempts(int retryAttempts) {
        this.retryAttempts = retryAttempts;
    }

    public int getRetryAttempts() {
        return retryAttempts;
    }

    public void setMetricsEnabled(boolean metricsEnabled) {
        this.metricsEnabled = metricsEnabled;
    }

    public boolean isMetricsEnabled() {
        return metricsEnabled;
    }

    public static class RuntimeBuilder {
        private Cluster cluster = new Cluster();

        public RuntimeBuilder addContactPoints(String... hosts) {
            if (hosts == null || hosts.length == 0) {
                throw new IllegalArgumentException("Hosts must be set!");
            }
            cluster.setHosts(hosts);
            return this;
        }

        public RuntimeBuilder withPort(int port) {
            cluster.setPort(port);
            return this;
        }

        public RuntimeBuilder withRetryAttempts(int retryAttempts) {
            cluster.setRetryAttempts(retryAttempts);
            return this;
        }

        public RuntimeBuilder withoutMetrics() {
            cluster.setMetricsEnabled(false);
            return this;
        }

        public Cluster build() {
            return cluster;
        }
    }

    public static class StoringBuilder {
        private String[] hosts;
        private int port;
        private int retryAttempts;
        private boolean metricsEnabled;

        public StoringBuilder addContactPoints(String... hosts) {
            if (hosts == null || hosts.length == 0) {
                throw new IllegalArgumentException("Hosts must be set!");
            }
            this.hosts = hosts;
            return this;
        }

        public StoringBuilder withPort(int port) {
            this.port = port;
            return this;
        }

        public StoringBuilder withRetryAttempts(int retryAttempts) {
            this.retryAttempts = retryAttempts;
            return this;
        }

        public StoringBuilder withoutMetrics() {
            this.metricsEnabled = false;
            return this;
        }

        public Cluster build() {
            Cluster cluster = new Cluster(hosts, port);
            cluster.setMetricsEnabled(metricsEnabled);
            cluster.setRetryAttempts(retryAttempts);
            return cluster;
        }
    }
}


================================================
FILE: src/com/xpinjection/patterns/chain/ModernAuthRequestHandler.java
================================================
package com.xpinjection.patterns.chain;

import com.xpinjection.patterns.chain.canonical.Request;

import java.util.function.Consumer;

/**
 * @author Alimenkou Mikalai
 */
public class ModernAuthRequestHandler implements Consumer<Request> {
    private static final ThreadLocal<Long> currentUser = new ThreadLocal<>();

    @Override
    public void accept(Request request) {
        currentUser.set(request.getUserId());
        System.out.println("Current user is set to: " + request.getUserId());
        request.addParam("AUTH_PASSED", "TRUE");
    }

    public static Long getCurrentUser() {
        return currentUser.get();
    }
}


================================================
FILE: src/com/xpinjection/patterns/chain/ModernChainClient.java
================================================
package com.xpinjection.patterns.chain;

import com.xpinjection.patterns.chain.canonical.Request;

import java.util.function.Consumer;
import java.util.stream.Stream;

/**
 * @author Alimenkou Mikalai
 */
public class ModernChainClient {
    public static void main(String[] args) {
        Request request = new Request(5);
        chain(new ModernAuthRequestHandler(), ModernChainClient::log)
                .accept(request);
    }

    @SafeVarargs
    public static Consumer<Request> chain(Consumer<Request>... handlers) {
        return Stream.of(handlers)
                .reduce(Consumer::andThen)
                .get();
    }

    private static void log(Request request) {
        System.out.println("Request arrived: " + request);
    }
}


================================================
FILE: src/com/xpinjection/patterns/chain/canonical/AbstractRequestHandler.java
================================================
package com.xpinjection.patterns.chain.canonical;

/**
 * @author Alimenkou Mikalai
 */
public abstract class AbstractRequestHandler implements RequestHandler {
    private final RequestHandler next;

    public AbstractRequestHandler(RequestHandler next) {
        this.next = next;
    }

    protected void passToTheNext(Request request) {
        if (next != null) {
            next.handleRequest(request);
        }
    }
}


================================================
FILE: src/com/xpinjection/patterns/chain/canonical/AuthRequestHandler.java
================================================
package com.xpinjection.patterns.chain.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class AuthRequestHandler extends AbstractRequestHandler {
    private static final ThreadLocal<Long> currentUser = new ThreadLocal<>();

    public AuthRequestHandler(RequestHandler next) {
        super(next);
    }

    @Override
    public void handleRequest(Request request) {
        currentUser.set(request.getUserId());
        System.out.println("Current user is set to: " + request.getUserId());
        request.addParam("AUTH_PASSED", "TRUE");
        passToTheNext(request);
    }

    public static Long getCurrentUser() {
        return currentUser.get();
    }
}


================================================
FILE: src/com/xpinjection/patterns/chain/canonical/ChainClient.java
================================================
package com.xpinjection.patterns.chain.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class ChainClient {
    public static void main(String[] args) {
        Request request = new Request(5);
        RequestHandler handler = new AuthRequestHandler(new LoggingRequestHandler(null));
        handler.handleRequest(request);
    }
}


================================================
FILE: src/com/xpinjection/patterns/chain/canonical/LoggingRequestHandler.java
================================================
package com.xpinjection.patterns.chain.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class LoggingRequestHandler extends AbstractRequestHandler {
    public LoggingRequestHandler(RequestHandler next) {
        super(next);
    }

    @Override
    public void handleRequest(Request request) {
        System.out.println("Request arrived: " + request);
        passToTheNext(request);
    }
}


================================================
FILE: src/com/xpinjection/patterns/chain/canonical/Request.java
================================================
package com.xpinjection.patterns.chain.canonical;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Alimenkou Mikalai
 */
public class Request {
    private final long userId;
    private final Map<String, String> params = new HashMap<>();

    public Request(long userId) {
        this.userId = userId;
    }

    public Request addParam(String name, String value) {
        params.put(name, value);
        return this;
    }

    public long getUserId() {
        return userId;
    }

    public Map<String, String> getParams() {
        return params;
    }

    @Override
    public String toString() {
        return "Request{userId=" + userId + ", params=" + params + "}";
    }
}


================================================
FILE: src/com/xpinjection/patterns/chain/canonical/RequestHandler.java
================================================
package com.xpinjection.patterns.chain.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface RequestHandler {
    void handleRequest(Request request);
}


================================================
FILE: src/com/xpinjection/patterns/command/ModernCommandClient.java
================================================
package com.xpinjection.patterns.command;

import com.xpinjection.patterns.command.canonical.Document;

/**
 * @author Alimenkou Mikalai
 */
public class ModernCommandClient {
    public static void main(String[] args) {
        Document editor = new Document();
        ModernMacro macro = new ModernMacro();

        macro.record(editor::bold)
                .record(editor::italic)
                .record(editor::underline)
                .run();
    }
}


================================================
FILE: src/com/xpinjection/patterns/command/ModernMacro.java
================================================
package com.xpinjection.patterns.command;

import com.xpinjection.patterns.command.canonical.Command;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Alimenkou Mikalai
 */
public class ModernMacro {
    private final List<Command> commands = new ArrayList<>();

    public ModernMacro record(Command action) {
        commands.add(action);
        return this;
    }

    public void run() {
        commands.forEach(Command::execute);
    }
}


================================================
FILE: src/com/xpinjection/patterns/command/canonical/BoldCommand.java
================================================
package com.xpinjection.patterns.command.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class BoldCommand implements Command {
    private final Editor editor;

    public BoldCommand(Editor editor) {
        this.editor = editor;
    }

    @Override
    public void execute() {
        editor.bold();
    }
}


================================================
FILE: src/com/xpinjection/patterns/command/canonical/Command.java
================================================
package com.xpinjection.patterns.command.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface Command {
    void execute();
}


================================================
FILE: src/com/xpinjection/patterns/command/canonical/CommandClient.java
================================================
package com.xpinjection.patterns.command.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class CommandClient {
    public static void main(String[] args) {
        Document editor = new Document();

        Macro macro = new Macro();
        macro.record(new BoldCommand(editor));
        macro.record(new ItalicCommand(editor));
        macro.record(new UnderlineCommand(editor));
        macro.run();
    }
}


================================================
FILE: src/com/xpinjection/patterns/command/canonical/Document.java
================================================
package com.xpinjection.patterns.command.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class Document implements Editor {
    @Override
    public void bold() {
        System.out.println("Bold text...");
    }

    @Override
    public void italic() {
        System.out.println("Italic text...");
    }

    @Override
    public void underline() {
        System.out.println("Underline text...");
    }
}


================================================
FILE: src/com/xpinjection/patterns/command/canonical/Editor.java
================================================
package com.xpinjection.patterns.command.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface Editor {
    void bold();

    void italic();

    void underline();
}


================================================
FILE: src/com/xpinjection/patterns/command/canonical/ItalicCommand.java
================================================
package com.xpinjection.patterns.command.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class ItalicCommand implements Command {
    private final Editor editor;

    public ItalicCommand(Editor editor) {
        this.editor = editor;
    }

    @Override
    public void execute() {
        editor.italic();
    }
}



================================================
FILE: src/com/xpinjection/patterns/command/canonical/Macro.java
================================================
package com.xpinjection.patterns.command.canonical;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Alimenkou Mikalai
 */
public class Macro {
    private final List<Command> commands = new ArrayList<>();

    public void record(Command action) {
        commands.add(action);
    }

    public void run() {
        for (Command command : commands) {
            command.execute();
        }
    }
}


================================================
FILE: src/com/xpinjection/patterns/command/canonical/UnderlineCommand.java
================================================
package com.xpinjection.patterns.command.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class UnderlineCommand implements Command {
    private final Editor editor;

    public UnderlineCommand(Editor editor) {
        this.editor = editor;
    }

    @Override
    public void execute() {
        editor.underline();
    }
}


================================================
FILE: src/com/xpinjection/patterns/decorator/ModernDecoratorClient.java
================================================
package com.xpinjection.patterns.decorator;

import com.xpinjection.patterns.decorator.canonical.DigitCounter;
import com.xpinjection.patterns.decorator.canonical.NaiveDigitCounter;

import java.util.function.Function;

/**
 * @author Alimenkou Mikalai
 */
public class ModernDecoratorClient {
    public static void main(String[] args) {
        DigitCounter counter = wrap(new NaiveDigitCounter());
        int digitsCount = counter.count("fd6j78fh19kj");
        System.out.println(digitsCount + " digits found");

        digitsCount = ((Function<String, String>) String::trim)
                .andThen(new NaiveDigitCounter()::count)
                .apply(" \n 123 \t");
        System.out.println(digitsCount + " digits found");
    }

    public static DigitCounter wrap(DigitCounter counter) {
        return s -> {
            long startTime = System.currentTimeMillis();
            int count = counter.count(s);
            long endTime = System.currentTimeMillis();
            System.out.println("Counting took " + (endTime - startTime) + " ms");
            return count;
        };
    }
}


================================================
FILE: src/com/xpinjection/patterns/decorator/canonical/BenchmarkingDigitCounter.java
================================================
package com.xpinjection.patterns.decorator.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class BenchmarkingDigitCounter implements DigitCounter {
    private final DigitCounter delegate;

    public BenchmarkingDigitCounter(DigitCounter delegate) {
        this.delegate = delegate;
    }

    @Override
    public int count(String str) {
        long startTime = System.currentTimeMillis();
        int count = delegate.count(str);
        long endTime = System.currentTimeMillis();
        System.out.println("Counting took " + (endTime - startTime) + " ms");
        return count;
    }
}


================================================
FILE: src/com/xpinjection/patterns/decorator/canonical/DecoratorClient.java
================================================
package com.xpinjection.patterns.decorator.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class DecoratorClient {
    public static void main(String[] args) {
        DigitCounter counter = new BenchmarkingDigitCounter(new NaiveDigitCounter());
        int digitsCount = counter.count("fd6j78fh19kj");
        System.out.println(digitsCount + " digits found");
    }
}


================================================
FILE: src/com/xpinjection/patterns/decorator/canonical/DigitCounter.java
================================================
package com.xpinjection.patterns.decorator.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface DigitCounter {
    int count(String str);
}


================================================
FILE: src/com/xpinjection/patterns/decorator/canonical/NaiveDigitCounter.java
================================================
package com.xpinjection.patterns.decorator.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class NaiveDigitCounter implements DigitCounter {
    @Override
    public int count(String str) {
        int count = 0;
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (Character.isDigit(c)) {
                count++;
            }
        }
        return count;
    }
}


================================================
FILE: src/com/xpinjection/patterns/factorymethod/ModernFactoryMethodClient.java
================================================
package com.xpinjection.patterns.factorymethod;

import com.xpinjection.patterns.factorymethod.canonical.Document;
import com.xpinjection.patterns.factorymethod.canonical.DocumentFactory;
import com.xpinjection.patterns.factorymethod.canonical.JsonDocument;

import java.util.function.Function;

/**
 * @author Alimenkou Mikalai
 */
public class ModernFactoryMethodClient {
    public static void main(String[] args) {
        DocumentFactory factory = JsonDocument::new;
        printUserDetails(factory.create("USER"));

        Function<String, Document> plainFactory = JsonDocument::new;
        printUserDetails(plainFactory.apply("USER"));
    }

    private static void printUserDetails(Document document) {
        document.addField("name", "Mikalai");
        document.addField("surname", "Alimenkou");
        System.out.println(document);
    }
}


================================================
FILE: src/com/xpinjection/patterns/factorymethod/canonical/Document.java
================================================
package com.xpinjection.patterns.factorymethod.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface Document {
    String getName();

    void addField(String name, String value);

    String toString();
}


================================================
FILE: src/com/xpinjection/patterns/factorymethod/canonical/DocumentFactory.java
================================================
package com.xpinjection.patterns.factorymethod.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface DocumentFactory {
    Document create(String name);
}


================================================
FILE: src/com/xpinjection/patterns/factorymethod/canonical/FactoryMethodClient.java
================================================
package com.xpinjection.patterns.factorymethod.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class FactoryMethodClient {
    public static void main(String[] args) {
        DocumentFactory factory = new JsonDocumentFactory();
        Document document = factory.create("USER");
        document.addField("name", "Mikalai");
        document.addField("surname", "Alimenkou");
        System.out.println(document);
    }
}


================================================
FILE: src/com/xpinjection/patterns/factorymethod/canonical/JsonDocument.java
================================================
package com.xpinjection.patterns.factorymethod.canonical;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Alimenkou Mikalai
 */
public class JsonDocument implements Document {
    private final String name;
    private final Map<String, String> fields = new LinkedHashMap<>();

    public JsonDocument(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void addField(String name, String value) {
        fields.put(name, value);
    }

    @Override
    public String toString() {
        return fields.entrySet().stream()
                .map(e -> e.getKey() + ": " + e.getValue())
                .collect(Collectors.joining(",\n", "{\n", "\n}"));
    }
}


================================================
FILE: src/com/xpinjection/patterns/factorymethod/canonical/JsonDocumentFactory.java
================================================
package com.xpinjection.patterns.factorymethod.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class JsonDocumentFactory implements DocumentFactory {
    @Override
    public Document create(String name) {
        return new JsonDocument(name);
    }
}


================================================
FILE: src/com/xpinjection/patterns/iterator/ModernIteratorClient.java
================================================
package com.xpinjection.patterns.iterator;

import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * @author Alimenkou Mikalai
 */
public class ModernIteratorClient {
    public static void main(String[] args) {
        ModernText text = new ModernMultilineText("This is just \n" +
                " a simple multiline \n" +
                "\n" +
                " text\n" +
                "\n", "\n");
        text.linesStream().forEach(System.out::println);

        String sentence = "JEEConf is the oldest Java conference in Ukraine";
        System.out.println(capitalize(sentence));
    }

    private static String capitalize(String sentence) {
        return Arrays.stream(sentence.split(" "))
                .filter(word -> word.length() > 4)
                .map(String::toUpperCase)
                .collect(Collectors.joining(" "));
    }
}


================================================
FILE: src/com/xpinjection/patterns/iterator/ModernMultilineText.java
================================================
package com.xpinjection.patterns.iterator;

import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * @author Alimenkou Mikalai
 */
public class ModernMultilineText implements ModernText {
    private final String text;
    private final String lineSeparator;

    public ModernMultilineText(String text, String lineSeparator) {
        this.text = text;
        this.lineSeparator = lineSeparator;
    }

    @Override
    public Stream<String> linesStream() {
        return StreamSupport.stream(new LineSupplier(), false);
    }

    private class LineSupplier extends Spliterators.AbstractSpliterator<String> {
        private int lineStartIndex = 0;

        public LineSupplier() {
            super(Long.MAX_VALUE, Spliterator.NONNULL | Spliterator.SIZED);
        }

        @Override
        public boolean tryAdvance(Consumer<? super String> action) {
            if (lineStartIndex >= text.length()) {
                return false;
            }
            int separatorIndex = text.indexOf(lineSeparator, lineStartIndex + 1);
            if (separatorIndex < 0) {
                separatorIndex = text.length() - 1;
            }
            String line = text.substring(lineStartIndex, separatorIndex);
            action.accept(line);
            lineStartIndex = separatorIndex + 1;
            return true;
        }
    }
}


================================================
FILE: src/com/xpinjection/patterns/iterator/ModernText.java
================================================
package com.xpinjection.patterns.iterator;

import java.util.stream.Stream;

/**
 * @author Alimenkou Mikalai
 */
public interface ModernText {
    Stream<String> linesStream();
}


================================================
FILE: src/com/xpinjection/patterns/iterator/canonical/IteratorClient.java
================================================
package com.xpinjection.patterns.iterator.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class IteratorClient {
    public static void main(String[] args) {
        Text text = new MultilineText("This is just \n" +
                " a simple multiline \n" +
                "\n" +
                " text\n" +
                "\n", "\n");
        LineIterator lineIterator = text.lineIterator();
        String line = lineIterator.nextLine();
        while (line != null) {
            System.out.println(line);
            line = lineIterator.nextLine();
        }

        String sentence = "JEEConf is the oldest Java conference in Ukraine";
        System.out.println(capitalize(sentence));
    }

    private static String capitalize(String sentence) {
        String[] words = sentence.split(" ");
        StringBuilder caps = new StringBuilder();

        for (String word : words) {
            if (word.length() > 4) {
                caps.append(word.toUpperCase()).append(' ');
            }
        }

        return caps.toString().trim();
    }
}


================================================
FILE: src/com/xpinjection/patterns/iterator/canonical/LineIterator.java
================================================
package com.xpinjection.patterns.iterator.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface LineIterator {
    String nextLine();
}


================================================
FILE: src/com/xpinjection/patterns/iterator/canonical/MultilineText.java
================================================
package com.xpinjection.patterns.iterator.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class MultilineText implements Text {
    private final String text;
    private final String lineSeparator;

    public MultilineText(String text, String lineSeparator) {
        this.text = text;
        this.lineSeparator = lineSeparator;
    }

    @Override
    public LineIterator lineIterator() {
        return new SeparatorBasedLineIterator();
    }

    private class SeparatorBasedLineIterator implements LineIterator {
        private int lineStartIndex = 0;

        @Override
        public String nextLine() {
            if (lineStartIndex >= text.length()) {
                return null;
            }
            int separatorIndex = text.indexOf(lineSeparator, lineStartIndex + 1);
            if (separatorIndex < 0) {
                separatorIndex = text.length() - 1;
            }
            String line = text.substring(lineStartIndex, separatorIndex);
            lineStartIndex = separatorIndex + 1;
            return line;
        }
    }
}


================================================
FILE: src/com/xpinjection/patterns/iterator/canonical/Text.java
================================================
package com.xpinjection.patterns.iterator.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface Text {
    LineIterator lineIterator();
}


================================================
FILE: src/com/xpinjection/patterns/observer/ModernObserver.java
================================================
package com.xpinjection.patterns.observer;

import com.xpinjection.patterns.observer.canonical.Event;

import java.util.function.Consumer;

/**
 * @author Alimenkou Mikalai
 */
public interface ModernObserver {
    void addListener(Consumer<Event> listener);
}


================================================
FILE: src/com/xpinjection/patterns/observer/ModernObserverClient.java
================================================
package com.xpinjection.patterns.observer;

import com.xpinjection.patterns.observer.canonical.Event;

/**
 * @author Alimenkou Mikalai
 */
public class ModernObserverClient {
    public static void main(String[] args) {
        ModernTimeServer server = new ModernTimeServer();
        server.addListener(ModernObserverClient::log);
        server.addListener(e -> System.out.println("ANOTHER EVENT: " + e.getName()));
        server.reportTime();
        server.reportTime();
    }

    public static void log(Event event) {
        System.out.println("EVENT: " + event.getName());
    }
}


================================================
FILE: src/com/xpinjection/patterns/observer/ModernTimeServer.java
================================================
package com.xpinjection.patterns.observer;

import com.xpinjection.patterns.observer.canonical.Event;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.Consumer;

/**
 * @author Alimenkou Mikalai
 */
public class ModernTimeServer implements ModernObserver {
    private static final String TIME_FORMAT = "HH:mm:ss";

    private final Queue<Consumer<Event>> listeners = new ConcurrentLinkedQueue<>();

    @Override
    public void addListener(Consumer<Event> listener) {
        listeners.add(listener);
    }

    public void reportTime() {
        Event event = new Event(new SimpleDateFormat(TIME_FORMAT).format(new Date()));
        listeners.forEach(listener -> listener.accept(event));
    }
}


================================================
FILE: src/com/xpinjection/patterns/observer/canonical/Event.java
================================================
package com.xpinjection.patterns.observer.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class Event {
    private final String name;

    public Event(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}


================================================
FILE: src/com/xpinjection/patterns/observer/canonical/EventListener.java
================================================
package com.xpinjection.patterns.observer.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface EventListener {
    void onEvent(Event event);
}


================================================
FILE: src/com/xpinjection/patterns/observer/canonical/LoggingEventListener.java
================================================
package com.xpinjection.patterns.observer.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class LoggingEventListener implements EventListener {
    @Override
    public void onEvent(Event event) {
        System.out.println("EVENT: " + event.getName());
    }
}


================================================
FILE: src/com/xpinjection/patterns/observer/canonical/Observer.java
================================================
package com.xpinjection.patterns.observer.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface Observer {
    void addListener(EventListener listener);
}


================================================
FILE: src/com/xpinjection/patterns/observer/canonical/ObserverClient.java
================================================
package com.xpinjection.patterns.observer.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class ObserverClient {
    public static void main(String[] args) {
        TimeServer server = new TimeServer();
        server.addListener(new LoggingEventListener());
        server.reportTime();
        server.reportTime();
    }
}


================================================
FILE: src/com/xpinjection/patterns/observer/canonical/TimeServer.java
================================================
package com.xpinjection.patterns.observer.canonical;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Alimenkou Mikalai
 */
public class TimeServer implements Observer {
    private static final String TIME_FORMAT = "HH:mm:ss";

    private final List<EventListener> listeners = new ArrayList<>();

    @Override
    public void addListener(EventListener listener) {
        listeners.add(listener);
    }

    public void reportTime() {
        Event event = new Event(new SimpleDateFormat(TIME_FORMAT).format(new Date()));
        for (EventListener listener : listeners) {
            listener.onEvent(event);
        }
    }
}


================================================
FILE: src/com/xpinjection/patterns/prototype/Stats.java
================================================
package com.xpinjection.patterns.prototype;

import java.util.Date;

/**
 * @author Alimenkou Mikalai
 */
public interface Stats<S> {
    S add(S delta);

    S invert(Date forDate);
}


================================================
FILE: src/com/xpinjection/patterns/prototype/StatsProcessor.java
================================================
package com.xpinjection.patterns.prototype;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Alimenkou Mikalai
 */
public class StatsProcessor {
    public List<Stats> process(long domainId, List<TrafficStats> stats) {
        Date now = new Date();
        return stats.stream()
                .filter(stat -> stat.getDomainId() == domainId)
                .map(stat -> stat.invert(now))
                .collect(Collectors.toList());
    }
}


================================================
FILE: src/com/xpinjection/patterns/prototype/TrafficStats.java
================================================
package com.xpinjection.patterns.prototype;

import java.util.Date;

/**
 * @author Alimenkou Mikalai
 */
public class TrafficStats implements Stats<TrafficStats> {
    private final long domainId;
    private final Date rankDate;

    private long estimatedTraffic;

    public TrafficStats(long domainId, Date rankDate) {
        this.domainId = domainId;
        this.rankDate = rankDate;
    }

    private TrafficStats(long domainId, Date rankDate, long traffic) {
        this(domainId, rankDate);
        this.estimatedTraffic = traffic;
    }

    public long getDomainId() {
        return domainId;
    }

    public Date getRankDate() {
        return rankDate;
    }

    public void setEstimatedTraffic(long estimatedTraffic) {
        this.estimatedTraffic = estimatedTraffic;
    }

    public long getEstimatedTraffic() {
        return estimatedTraffic;
    }

    @Override
    public TrafficStats add(TrafficStats delta) {
        return new TrafficStats(domainId, rankDate, estimatedTraffic + delta.estimatedTraffic);
    }

    @Override
    public TrafficStats invert(Date forDate) {
        return new TrafficStats(domainId, forDate, -estimatedTraffic);
    }

    @Override
    public String toString() {
        return "TrafficStats{domainId=" + domainId + ", rankDate=" + rankDate +
                ", estimatedTraffic=" + estimatedTraffic + "}";
    }
}


================================================
FILE: src/com/xpinjection/patterns/prototype/canonical/Circle.java
================================================
package com.xpinjection.patterns.prototype.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class Circle implements Figure {
    private int radix;

    public Circle(int radix) {
        this.radix = radix;
    }

    public void changeRadix(int delta) {
        radix += delta;
    }

    @Override
    public double getSquare() {
        return Math.PI * radix * radix;
    }

    @Override
    public Circle clone() {
        return new Circle(radix);
    }
}


================================================
FILE: src/com/xpinjection/patterns/prototype/canonical/Editor.java
================================================
package com.xpinjection.patterns.prototype.canonical;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Alimenkou Mikalai
 */
public class Editor {
    private final List<Figure> figures = new ArrayList<>();

    private final Circle defaultCircle = new Circle(5);
    private final Rectangle defaultRectangle = new Rectangle(2, 4);

    public Circle addCircle() {
        Circle circle = defaultCircle.clone();
        figures.add(circle);
        return circle;
    }

    public Rectangle addRectangle() {
        Rectangle rectangle = defaultRectangle.clone();
        figures.add(rectangle);
        return rectangle;
    }
}


================================================
FILE: src/com/xpinjection/patterns/prototype/canonical/Figure.java
================================================
package com.xpinjection.patterns.prototype.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface Figure {
    double getSquare();

    Figure clone();
}


================================================
FILE: src/com/xpinjection/patterns/prototype/canonical/PrototypeClient.java
================================================
package com.xpinjection.patterns.prototype.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class PrototypeClient {
    public static void main(String[] args) {
        Editor editor = new Editor();

        Circle circle = editor.addCircle();
        circle.changeRadix(5);

        Rectangle rectangle = editor.addRectangle();
        rectangle.changeSize(1, -1);
    }
}


================================================
FILE: src/com/xpinjection/patterns/prototype/canonical/Rectangle.java
================================================
package com.xpinjection.patterns.prototype.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class Rectangle implements Figure {
    private int width;
    private int height;

    public Rectangle(int width, int height) {
        this.width = width;
        this.height = height;
    }

    public void changeSize(int widthDelta, int heightDelta) {
        width += widthDelta;
        height += heightDelta;
    }

    @Override
    public double getSquare() {
        return width * height;
    }

    @Override
    public Rectangle clone() {
        return new Rectangle(width, height);
    }
}


================================================
FILE: src/com/xpinjection/patterns/proxy/ModernProxyClient.java
================================================
package com.xpinjection.patterns.proxy;

import com.xpinjection.patterns.proxy.canonical.Order;
import com.xpinjection.patterns.proxy.canonical.RealOrderService;

import java.util.function.Consumer;

/**
 * @author Alimenkou Mikalai
 */
public class ModernProxyClient {
    public static void main(String[] args) {
        Order order = new Order(5L);
        order.putItem("XP", 2);

        RealOrderService service = new RealOrderService();
        PermissionChecker checker = new PermissionChecker();
        Consumer<Order> processing = ((Consumer<Order>) checker::checkPermission)
                .andThen(service::processOrder);

        checker.setCurrentUser(5);
        processing.accept(order);
        checker.setCurrentUser(2);
        processing.accept(order);
    }
}


================================================
FILE: src/com/xpinjection/patterns/proxy/PermissionChecker.java
================================================
package com.xpinjection.patterns.proxy;

import com.xpinjection.patterns.proxy.canonical.Order;

/**
 * @author Alimenkou Mikalai
 */
public class PermissionChecker {
    private final ThreadLocal<Long> currentUser = new ThreadLocal<>();

    public void setCurrentUser(long userId) {
        currentUser.set(userId);
    }

    public void checkPermission(Order order) {
        if (order.getUserId() != currentUser.get()) {
            throw new IllegalStateException("Order for another user can't be processed: " + order);
        }
    }
}


================================================
FILE: src/com/xpinjection/patterns/proxy/canonical/Order.java
================================================
package com.xpinjection.patterns.proxy.canonical;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Alimenkou Mikalai
 */
public class Order {
    private final long userId;
    private final Map<String, Integer> items = new HashMap<>();

    public Order(long userId) {
        this.userId = userId;
    }

    public void putItem(String code, int count) {
        items.put(code, count);
    }

    public long getUserId() {
        return userId;
    }

    public Map<String, Integer> getItems() {
        return items;
    }

    @Override
    public String toString() {
        return "Order{userId=" + userId + ", items=" + items + "}";
    }
}


================================================
FILE: src/com/xpinjection/patterns/proxy/canonical/OrderService.java
================================================
package com.xpinjection.patterns.proxy.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface OrderService {
    void processOrder(Order order);
}


================================================
FILE: src/com/xpinjection/patterns/proxy/canonical/PermissionCheckingOrderServiceProxy.java
================================================
package com.xpinjection.patterns.proxy.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class PermissionCheckingOrderServiceProxy implements OrderService {
    private final ThreadLocal<Long> currentUser = new ThreadLocal<>();
    private final OrderService delegate;

    public PermissionCheckingOrderServiceProxy(OrderService delegate) {
        this.delegate = delegate;
    }

    public void setCurrentUser(long userId) {
        currentUser.set(userId);
    }

    @Override
    public void processOrder(Order order) {
        if (order.getUserId() != currentUser.get()) {
            throw new IllegalStateException("Order for another user can't be processed: " + order);
        }
        delegate.processOrder(order);
    }
}


================================================
FILE: src/com/xpinjection/patterns/proxy/canonical/ProxyClient.java
================================================
package com.xpinjection.patterns.proxy.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class ProxyClient {
    public static void main(String[] args) {
        Order order = new Order(5L);
        order.putItem("XP", 2);

        RealOrderService service = new RealOrderService();
        service.processOrder(order);

        PermissionCheckingOrderServiceProxy proxy = new PermissionCheckingOrderServiceProxy(service);
        proxy.setCurrentUser(5);
        proxy.processOrder(order);
        proxy.setCurrentUser(2);
        proxy.processOrder(order);
    }
}


================================================
FILE: src/com/xpinjection/patterns/proxy/canonical/RealOrderService.java
================================================
package com.xpinjection.patterns.proxy.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class RealOrderService implements OrderService {
    @Override
    public void processOrder(Order order) {
        System.out.println("Order processed: " + order);
    }
}


================================================
FILE: src/com/xpinjection/patterns/proxy/spring-context.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

    <bean id="permissionChecker" class="com.xpinjection.patterns.proxy.PermissionChecker"/>

    <bean id="orderService" class="com.xpinjection.patterns.proxy.canonical.RealOrderService"/>

    <aop:config>
        <aop:aspect id="checkPermissions" ref="permissionChecker" order="1">
            <aop:before method="checkPermission" arg-names="order"
                        pointcut="execution(public * com.xpinjection.patterns.proxy.canonical.*Service.*(..)) and args(order, ..)"/>
        </aop:aspect>
    </aop:config>
</beans>

================================================
FILE: src/com/xpinjection/patterns/singleton/ModernServiceRegistry.java
================================================
package com.xpinjection.patterns.singleton;

import com.xpinjection.patterns.singleton.canonical.NamedService;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @author Alimenkou Mikalai
 */
public class ModernServiceRegistry {
    private final ConcurrentMap<String, NamedService> services = new ConcurrentHashMap<>();

    public void register(NamedService service) {
        String name = service.getName();
        System.out.println("Register service with name: " + name);
        services.put(name, service);
    }

    public NamedService getService(String name) {
        return services.get(name);
    }
}


================================================
FILE: src/com/xpinjection/patterns/singleton/ModernSingletonClient.java
================================================
package com.xpinjection.patterns.singleton;

import com.xpinjection.patterns.singleton.canonical.NamedService;

/**
 * @author Alimenkou Mikalai
 */
public class ModernSingletonClient implements NamedService {
    private final ModernServiceRegistry registry;

    public ModernSingletonClient(ModernServiceRegistry registry) {
        this.registry = registry;
    }

    public static void main(String[] args) {
        ModernServiceRegistry registry = new ModernServiceRegistry();
        new ModernSingletonClient(registry).start();
    }

    public void start() {
        registry.register(this);
    }

    @Override
    public String getName() {
        return "MAIN";
    }
}


================================================
FILE: src/com/xpinjection/patterns/singleton/canonical/NamedService.java
================================================
package com.xpinjection.patterns.singleton.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface NamedService {
    String getName();
}


================================================
FILE: src/com/xpinjection/patterns/singleton/canonical/ServiceRegistry.java
================================================
package com.xpinjection.patterns.singleton.canonical;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @author Alimenkou Mikalai
 */
public final class ServiceRegistry {
    private static final ServiceRegistry INSTANCE = new ServiceRegistry();

    public static ServiceRegistry getInstance() {
        return INSTANCE;
    }

    private final ConcurrentMap<String, NamedService> services = new ConcurrentHashMap<>();

    private ServiceRegistry() {}

    public void register(NamedService service) {
        String name = service.getName();
        System.out.println("Register service with name: " + name);
        services.put(name, service);
    }

    public NamedService getService(String name) {
        return services.get(name);
    }
}


================================================
FILE: src/com/xpinjection/patterns/singleton/canonical/SingletonClient.java
================================================
package com.xpinjection.patterns.singleton.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class SingletonClient implements NamedService {
    public static void main(String[] args) {
        new SingletonClient().start();
    }

    public void start() {
        ServiceRegistry.getInstance().register(this);
    }

    @Override
    public String getName() {
        return "MAIN";
    }
}


================================================
FILE: src/com/xpinjection/patterns/singleton/spring-context.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">

    <bean id="client" class="com.xpinjection.patterns.singleton.ModernSingletonClient">
        <constructor-arg ref="registry"/>
    </bean>

    <bean id="registry" class="com.xpinjection.patterns.singleton.ModernServiceRegistry"/>

    <bean id="oldRegistry" class="com.xpinjection.patterns.singleton.canonical.ServiceRegistry"
          factory-method="getInstance"/>
</beans>


================================================
FILE: src/com/xpinjection/patterns/strategy/ModernStrategyClient.java
================================================
package com.xpinjection.patterns.strategy;

import com.xpinjection.patterns.strategy.canonical.Position;

import java.util.function.ToIntFunction;

/**
 * @author Alimenkou Mikalai
 */
public class ModernStrategyClient {
    private final ToIntFunction<Position> calculator;

    public ModernStrategyClient(ToIntFunction<Position> calculator) {
        this.calculator = calculator;
    }

    public static void main(String[] args) {
        Position position = new Position(3, 1000);
        new ModernStrategyClient(TrafficCalculationStrategies::calculateTopTrafficOnly).process(position);
        new ModernStrategyClient(TrafficCalculationStrategies::calculateTrafficForPage).process(position);

        // for unit tests
        new ModernStrategyClient(pos -> 15).process(position);
    }

    public void process(Position position) {
        int traffic = calculator.applyAsInt(position);
        System.out.println("Traffic is " + traffic + " for position " + position);
    }
}


================================================
FILE: src/com/xpinjection/patterns/strategy/TrafficCalculationStrategies.java
================================================
package com.xpinjection.patterns.strategy;

import com.xpinjection.patterns.strategy.canonical.Position;

/**
 * @author Alimenkou Mikalai
 */
public final class TrafficCalculationStrategies {
    private static final int PAGE_SIZE = 10;
    private static final double[] TOP_RANKS = {0.5, 0.3, 0.1, 0.05, 0.05};

    private TrafficCalculationStrategies() {}

    public static int calculateTrafficForPage(Position position) {
        int rank = position.getRank();
        if (rank < 0) {
            return 0;
        }
        int page = rank / PAGE_SIZE;
        return position.getMediaValue() / (PAGE_SIZE * (page + 1));
    }

    public static int calculateTopTrafficOnly(Position position) {
        int rank = position.getRank();
        if (rank < 0 || rank >= TOP_RANKS.length) {
            return 0;
        }
        return (int) (TOP_RANKS[rank] * position.getMediaValue());
    }
}


================================================
FILE: src/com/xpinjection/patterns/strategy/canonical/PageTrafficCalculator.java
================================================
package com.xpinjection.patterns.strategy.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class PageTrafficCalculator implements TrafficCalculator {
    private static final int PAGE_SIZE = 10;

    @Override
    public int calculate(Position position) {
        int rank = position.getRank();
        if (rank < 0) {
            return 0;
        }
        int page = rank / PAGE_SIZE;
        return position.getMediaValue() / (PAGE_SIZE * (page + 1));
    }
}


================================================
FILE: src/com/xpinjection/patterns/strategy/canonical/Position.java
================================================
package com.xpinjection.patterns.strategy.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class Position {
    private int rank;
    private int mediaValue;

    public Position(int rank, int mediaValue) {
        this.rank = rank;
        this.mediaValue = mediaValue;
    }

    public int getRank() {
        return rank;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }

    public int getMediaValue() {
        return mediaValue;
    }

    public void setMediaValue(int mediaValue) {
        this.mediaValue = mediaValue;
    }

    @Override
    public String toString() {
        return "Position{rank=" + rank + ", mediaValue=" + mediaValue + "}";
    }
}


================================================
FILE: src/com/xpinjection/patterns/strategy/canonical/StrategyClient.java
================================================
package com.xpinjection.patterns.strategy.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class StrategyClient {
    private final TrafficCalculator calculator;

    public StrategyClient(TrafficCalculator calculator) {
        this.calculator = calculator;
    }

    public static void main(String[] args) {
        Position position = new Position(3, 1000);
        new StrategyClient(new TopTrafficCalculator()).process(position);
        new StrategyClient(new PageTrafficCalculator()).process(position);
    }

    public void process(Position position) {
        int traffic = calculator.calculate(position);
        System.out.println("Traffic is " + traffic + " for position " + position);
    }
}


================================================
FILE: src/com/xpinjection/patterns/strategy/canonical/TopTrafficCalculator.java
================================================
package com.xpinjection.patterns.strategy.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class TopTrafficCalculator implements TrafficCalculator {
    private static final double[] TOP_RANKS = {0.5, 0.3, 0.1, 0.05, 0.05};

    @Override
    public int calculate(Position position) {
        int rank = position.getRank();
        if (rank < 0 || rank >= TOP_RANKS.length) {
            return 0;
        }
        return (int) (TOP_RANKS[rank] * position.getMediaValue());
    }
}


================================================
FILE: src/com/xpinjection/patterns/strategy/canonical/TrafficCalculator.java
================================================
package com.xpinjection.patterns.strategy.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface TrafficCalculator {
    int calculate(Position position);
}


================================================
FILE: src/com/xpinjection/patterns/templatemethod/LoggingUserStorage.java
================================================
package com.xpinjection.patterns.templatemethod;

import com.xpinjection.patterns.templatemethod.canonical.User;

/**
 * @author Alimenkou Mikalai
 */
public class LoggingUserStorage {
    public long store(User user) {
        System.out.println("User is stored: " + user);
        return System.currentTimeMillis();
    }
}


================================================
FILE: src/com/xpinjection/patterns/templatemethod/ModernTemplateMethodClient.java
================================================
package com.xpinjection.patterns.templatemethod;

import com.xpinjection.patterns.templatemethod.canonical.User;

/**
 * @author Alimenkou Mikalai
 */
public class ModernTemplateMethodClient {
    public static void main(String[] args) {
        LoggingUserStorage storage = new LoggingUserStorage();
        User mikalai = new ModernUserRestorer(storage::store).restore("Mikalai:32");
        System.out.println("Mikalai is restored: " + mikalai);

        // for unit tests
        mikalai = new ModernUserRestorer(user -> 5L).restore("Mikalai:32");
        System.out.println("Mikalai is restored: " + mikalai);
    }
}


================================================
FILE: src/com/xpinjection/patterns/templatemethod/ModernUserRestorer.java
================================================
package com.xpinjection.patterns.templatemethod;

import com.xpinjection.patterns.templatemethod.canonical.User;

import java.util.StringTokenizer;
import java.util.function.ToLongFunction;

/**
 * @author Alimenkou Mikalai
 */
public class ModernUserRestorer {
    private static final String DELIMITER = ":";

    private final ToLongFunction<User> storage;

    public ModernUserRestorer(ToLongFunction<User> storage) {
        this.storage = storage;
    }

    public User restore(String serialized) {
        StringTokenizer tokenizer = new StringTokenizer(serialized, DELIMITER);
        validate(tokenizer);
        User user = parse(tokenizer);
        long id = storage.applyAsLong(user);
        user.setId(id);
        return user;
    }

    private User parse(StringTokenizer tokenizer) {
        String name = tokenizer.nextToken();
        int age = Integer.parseInt(tokenizer.nextToken());
        return new User(name, age);
    }

    private void validate(StringTokenizer tokenizer) {
        if (tokenizer.countTokens() != 2) {
            throw new IllegalArgumentException("Invalid data format!");
        }
    }
}


================================================
FILE: src/com/xpinjection/patterns/templatemethod/canonical/AbstractUserRestorer.java
================================================
package com.xpinjection.patterns.templatemethod.canonical;

import java.util.StringTokenizer;

/**
 * @author Alimenkou Mikalai
 */
public abstract class AbstractUserRestorer {
    private static final String DELIMITER = ":";

    public final User restore(String serialized) {
        StringTokenizer tokenizer = new StringTokenizer(serialized, DELIMITER);
        validate(tokenizer);
        User user = parse(tokenizer);
        long id = store(user);
        user.setId(id);
        return user;
    }

    private User parse(StringTokenizer tokenizer) {
        String name = tokenizer.nextToken();
        int age = Integer.parseInt(tokenizer.nextToken());
        return new User(name, age);
    }

    private void validate(StringTokenizer tokenizer) {
        if (tokenizer.countTokens() != 2) {
            throw new IllegalArgumentException("Invalid data format!");
        }
    }

    protected abstract long store(User user);
}


================================================
FILE: src/com/xpinjection/patterns/templatemethod/canonical/LoggingUserRestorer.java
================================================
package com.xpinjection.patterns.templatemethod.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class LoggingUserRestorer extends AbstractUserRestorer {
    @Override
    protected long store(User user) {
        System.out.println("User is stored: " + user);
        return System.currentTimeMillis();
    }
}


================================================
FILE: src/com/xpinjection/patterns/templatemethod/canonical/TemplateMethodClient.java
================================================
package com.xpinjection.patterns.templatemethod.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class TemplateMethodClient {
    public static void main(String[] args) {
        User mikalai = new LoggingUserRestorer().restore("Mikalai:32");
        System.out.println("Mikalai is restored: " + mikalai);
    }
}


================================================
FILE: src/com/xpinjection/patterns/templatemethod/canonical/User.java
================================================
package com.xpinjection.patterns.templatemethod.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class User {
    private Long id;
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{id=" + id + ", name='" + name + "', age=" + age + "}";
    }
}


================================================
FILE: src/com/xpinjection/patterns/visitor/LambdaVisitor.java
================================================
package com.xpinjection.patterns.visitor;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

/**
 * @author Alimenkou Mikalai
 */
public class LambdaVisitor<A> implements Function<Object, A> {
    private final Map<Class<?>, Function<Object, A>> functions = new HashMap<>();

    public <B> Acceptor<A, B> on(Class<B> clazz) {
        return new Acceptor<>(this, clazz);
    }

    @Override
    public A apply(Object o) {
        return functions.get(o.getClass()).apply(o);
    }

    public static class Acceptor<A, B> {
        private final LambdaVisitor visitor;
        private final Class<B> clazz;

        public Acceptor(LambdaVisitor<A> visitor, Class<B> clazz) {
            this.visitor = visitor;
            this.clazz = clazz;
        }

        public LambdaVisitor<A> then(Function<B, A> f) {
            visitor.functions.put(clazz, f);
            return visitor;
        }
    }
}


================================================
FILE: src/com/xpinjection/patterns/visitor/ModernVisitorClient.java
================================================
package com.xpinjection.patterns.visitor;

import com.xpinjection.patterns.visitor.canonical.Circle;
import com.xpinjection.patterns.visitor.canonical.Rectangle;
import com.xpinjection.patterns.visitor.canonical.Square;

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;

/**
 * @author Alimenkou Mikalai
 */
public class ModernVisitorClient {
    private final static Function<Object, Double> AREA_CALCULATOR = new LambdaVisitor<Double>()
            .on(Square.class).then(s -> s.getSide() * s.getSide())
            .on(Circle.class).then(c -> Math.PI * c.getRadius() * c.getRadius())
            .on(Rectangle.class).then(r -> r.getHeight() * r.getWidth());

    private final static Function<Object, Double> PERIMETER_CALCULATOR = new LambdaVisitor<Double>()
            .on(Square.class).then(s -> 4 * s.getSide())
            .on(Circle.class).then(c -> 2 * Math.PI * c.getRadius())
            .on(Rectangle.class).then(r -> 2 * r.getHeight() + 2 * r.getWidth());

    public static void main(String[] args) {
        List<Object> figures = Arrays.asList(new Circle(4), new Square(5), new Rectangle(6, 7));

        double totalArea = figures.stream()
                .map(AREA_CALCULATOR)
                .reduce(0.0, Double::sum);
        System.out.println("Total area = " + totalArea);

        double totalPerimeter = figures.stream()
                .map(PERIMETER_CALCULATOR)
                .reduce(0.0, Double::sum);
        System.out.println("Total perimeter = " + totalPerimeter);
    }
}


================================================
FILE: src/com/xpinjection/patterns/visitor/canonical/AreaVisitor.java
================================================
package com.xpinjection.patterns.visitor.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class AreaVisitor implements Visitor<Double> {
    @Override
    public Double visit(Square element) {
        return element.getSide() * element.getSide();
    }

    @Override
    public Double visit(Circle element) {
        return Math.PI * element.getRadius() * element.getRadius();
    }

    @Override
    public Double visit(Rectangle element) {
        return element.getHeight() * element.getWidth();
    }
}


================================================
FILE: src/com/xpinjection/patterns/visitor/canonical/Circle.java
================================================
package com.xpinjection.patterns.visitor.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class Circle implements Element {
    private final double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }

    @Override
    public <T> T accept(Visitor<T> visitor) {
        return visitor.visit(this);
    }
}


================================================
FILE: src/com/xpinjection/patterns/visitor/canonical/Element.java
================================================
package com.xpinjection.patterns.visitor.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface Element {
    <T> T accept(Visitor<T> visitor);
}


================================================
FILE: src/com/xpinjection/patterns/visitor/canonical/PerimeterVisitor.java
================================================
package com.xpinjection.patterns.visitor.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class PerimeterVisitor implements Visitor<Double> {
    @Override
    public Double visit(Square element) {
        return 4 * element.getSide();
    }

    @Override
    public Double visit(Circle element) {
        return 2 * Math.PI * element.getRadius();
    }

    @Override
    public Double visit(Rectangle element) {
        return (2 * element.getHeight() + 2 * element.getWidth());
    }
}


================================================
FILE: src/com/xpinjection/patterns/visitor/canonical/Rectangle.java
================================================
package com.xpinjection.patterns.visitor.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class Rectangle implements Element {
    private final double width;
    private final double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    public double getWidth() {
        return width;
    }

    public double getHeight() {
        return height;
    }

    @Override
    public <T> T accept(Visitor<T> visitor) {
        return visitor.visit(this);
    }
}

================================================
FILE: src/com/xpinjection/patterns/visitor/canonical/Square.java
================================================
package com.xpinjection.patterns.visitor.canonical;

/**
 * @author Alimenkou Mikalai
 */
public class Square implements Element {
    private final double side;

    public Square(double side) {
        this.side = side;
    }

    public double getSide() {
        return side;
    }

    @Override
    public <T> T accept(Visitor<T> visitor) {
        return visitor.visit(this);
    }
}


================================================
FILE: src/com/xpinjection/patterns/visitor/canonical/Visitor.java
================================================
package com.xpinjection.patterns.visitor.canonical;

/**
 * @author Alimenkou Mikalai
 */
public interface Visitor<T> {
    T visit(Square element);

    T visit(Circle element);

    T visit(Rectangle element);
}


================================================
FILE: src/com/xpinjection/patterns/visitor/canonical/VisitorClient.java
================================================
package com.xpinjection.patterns.visitor.canonical;

import java.util.Arrays;
import java.util.List;

/**
 * @author Alimenkou Mikalai
 */
public class VisitorClient {
    public static void main(String[] args) {
        List<Element> figures = Arrays.asList(new Circle(4), new Square(5), new Rectangle(6, 7));

        double totalArea = 0.0;
        Visitor<Double> areaVisitor = new AreaVisitor();
        for (Element figure : figures) {
            totalArea += figure.accept(areaVisitor);
        }
        System.out.println("Total area = " + totalArea);

        double totalPerimeter = 0.0;
        Visitor<Double> perimeterVisitor = new PerimeterVisitor();
        for (Element figure : figures) {
            totalPerimeter += figure.accept(perimeterVisitor);
        }
        System.out.println("Total perimeter = " + totalPerimeter);
    }
}
Download .txt
gitextract_v3o3f7e_/

├── LICENSE
├── README.md
├── libs/
│   └── lombok-1.16.10.jar
└── src/
    └── com/
        └── xpinjection/
            └── patterns/
                ├── adapter/
                │   ├── ModernAdapterClient.java
                │   └── canonical/
                │       ├── AdapterClient.java
                │       ├── CharCounterTask.java
                │       └── ExecutorConsumerAdaptor.java
                ├── builder/
                │   ├── FutureBuilderClient.java
                │   ├── FutureCluster.java
                │   ├── LombokBuilderClient.java
                │   ├── LombokCluster.java
                │   └── canonical/
                │       ├── BuilderClient.java
                │       └── Cluster.java
                ├── chain/
                │   ├── ModernAuthRequestHandler.java
                │   ├── ModernChainClient.java
                │   └── canonical/
                │       ├── AbstractRequestHandler.java
                │       ├── AuthRequestHandler.java
                │       ├── ChainClient.java
                │       ├── LoggingRequestHandler.java
                │       ├── Request.java
                │       └── RequestHandler.java
                ├── command/
                │   ├── ModernCommandClient.java
                │   ├── ModernMacro.java
                │   └── canonical/
                │       ├── BoldCommand.java
                │       ├── Command.java
                │       ├── CommandClient.java
                │       ├── Document.java
                │       ├── Editor.java
                │       ├── ItalicCommand.java
                │       ├── Macro.java
                │       └── UnderlineCommand.java
                ├── decorator/
                │   ├── ModernDecoratorClient.java
                │   └── canonical/
                │       ├── BenchmarkingDigitCounter.java
                │       ├── DecoratorClient.java
                │       ├── DigitCounter.java
                │       └── NaiveDigitCounter.java
                ├── factorymethod/
                │   ├── ModernFactoryMethodClient.java
                │   └── canonical/
                │       ├── Document.java
                │       ├── DocumentFactory.java
                │       ├── FactoryMethodClient.java
                │       ├── JsonDocument.java
                │       └── JsonDocumentFactory.java
                ├── iterator/
                │   ├── ModernIteratorClient.java
                │   ├── ModernMultilineText.java
                │   ├── ModernText.java
                │   └── canonical/
                │       ├── IteratorClient.java
                │       ├── LineIterator.java
                │       ├── MultilineText.java
                │       └── Text.java
                ├── observer/
                │   ├── ModernObserver.java
                │   ├── ModernObserverClient.java
                │   ├── ModernTimeServer.java
                │   └── canonical/
                │       ├── Event.java
                │       ├── EventListener.java
                │       ├── LoggingEventListener.java
                │       ├── Observer.java
                │       ├── ObserverClient.java
                │       └── TimeServer.java
                ├── prototype/
                │   ├── Stats.java
                │   ├── StatsProcessor.java
                │   ├── TrafficStats.java
                │   └── canonical/
                │       ├── Circle.java
                │       ├── Editor.java
                │       ├── Figure.java
                │       ├── PrototypeClient.java
                │       └── Rectangle.java
                ├── proxy/
                │   ├── ModernProxyClient.java
                │   ├── PermissionChecker.java
                │   ├── canonical/
                │   │   ├── Order.java
                │   │   ├── OrderService.java
                │   │   ├── PermissionCheckingOrderServiceProxy.java
                │   │   ├── ProxyClient.java
                │   │   └── RealOrderService.java
                │   └── spring-context.xml
                ├── singleton/
                │   ├── ModernServiceRegistry.java
                │   ├── ModernSingletonClient.java
                │   ├── canonical/
                │   │   ├── NamedService.java
                │   │   ├── ServiceRegistry.java
                │   │   └── SingletonClient.java
                │   └── spring-context.xml
                ├── strategy/
                │   ├── ModernStrategyClient.java
                │   ├── TrafficCalculationStrategies.java
                │   └── canonical/
                │       ├── PageTrafficCalculator.java
                │       ├── Position.java
                │       ├── StrategyClient.java
                │       ├── TopTrafficCalculator.java
                │       └── TrafficCalculator.java
                ├── templatemethod/
                │   ├── LoggingUserStorage.java
                │   ├── ModernTemplateMethodClient.java
                │   ├── ModernUserRestorer.java
                │   └── canonical/
                │       ├── AbstractUserRestorer.java
                │       ├── LoggingUserRestorer.java
                │       ├── TemplateMethodClient.java
                │       └── User.java
                └── visitor/
                    ├── LambdaVisitor.java
                    ├── ModernVisitorClient.java
                    └── canonical/
                        ├── AreaVisitor.java
                        ├── Circle.java
                        ├── Element.java
                        ├── PerimeterVisitor.java
                        ├── Rectangle.java
                        ├── Square.java
                        ├── Visitor.java
                        └── VisitorClient.java
Download .txt
SYMBOL INDEX (335 symbols across 99 files)

FILE: src/com/xpinjection/patterns/adapter/ModernAdapterClient.java
  class ModernAdapterClient (line 14) | public class ModernAdapterClient {
    method main (line 15) | public static void main(String[] args) throws InterruptedException {

FILE: src/com/xpinjection/patterns/adapter/canonical/AdapterClient.java
  class AdapterClient (line 12) | public class AdapterClient {
    method main (line 13) | public static void main(String[] args) throws InterruptedException {

FILE: src/com/xpinjection/patterns/adapter/canonical/CharCounterTask.java
  class CharCounterTask (line 9) | public class CharCounterTask implements Runnable {
    method CharCounterTask (line 13) | public CharCounterTask(String str, AtomicInteger counter) {
    method run (line 18) | @Override

FILE: src/com/xpinjection/patterns/adapter/canonical/ExecutorConsumerAdaptor.java
  class ExecutorConsumerAdaptor (line 9) | public class ExecutorConsumerAdaptor implements Consumer<Runnable> {
    method ExecutorConsumerAdaptor (line 12) | public ExecutorConsumerAdaptor(Executor executor) {
    method accept (line 16) | @Override

FILE: src/com/xpinjection/patterns/builder/FutureBuilderClient.java
  class FutureBuilderClient (line 6) | public class FutureBuilderClient {

FILE: src/com/xpinjection/patterns/builder/FutureCluster.java
  class FutureCluster (line 6) | public class FutureCluster {

FILE: src/com/xpinjection/patterns/builder/LombokBuilderClient.java
  class LombokBuilderClient (line 6) | public class LombokBuilderClient {
    method main (line 7) | public static void main(String[] args) {

FILE: src/com/xpinjection/patterns/builder/LombokCluster.java
  class LombokCluster (line 12) | @Builder

FILE: src/com/xpinjection/patterns/builder/canonical/BuilderClient.java
  class BuilderClient (line 6) | public class BuilderClient {
    method main (line 7) | public static void main(String[] args) {

FILE: src/com/xpinjection/patterns/builder/canonical/Cluster.java
  class Cluster (line 6) | public class Cluster {
    method storingBuilder (line 12) | public static StoringBuilder storingBuilder() {
    method runtimeBuilder (line 16) | public static RuntimeBuilder runtimeBuilder() {
    method Cluster (line 20) | public Cluster(String[] hosts, int port) {
    method Cluster (line 25) | public Cluster() {
    method setHosts (line 28) | public void setHosts(String... hosts) {
    method getHosts (line 32) | public String[] getHosts() {
    method setPort (line 36) | public void setPort(int port) {
    method getPort (line 40) | public int getPort() {
    method setRetryAttempts (line 44) | public void setRetryAttempts(int retryAttempts) {
    method getRetryAttempts (line 48) | public int getRetryAttempts() {
    method setMetricsEnabled (line 52) | public void setMetricsEnabled(boolean metricsEnabled) {
    method isMetricsEnabled (line 56) | public boolean isMetricsEnabled() {
    class RuntimeBuilder (line 60) | public static class RuntimeBuilder {
      method addContactPoints (line 63) | public RuntimeBuilder addContactPoints(String... hosts) {
      method withPort (line 71) | public RuntimeBuilder withPort(int port) {
      method withRetryAttempts (line 76) | public RuntimeBuilder withRetryAttempts(int retryAttempts) {
      method withoutMetrics (line 81) | public RuntimeBuilder withoutMetrics() {
      method build (line 86) | public Cluster build() {
    class StoringBuilder (line 91) | public static class StoringBuilder {
      method addContactPoints (line 97) | public StoringBuilder addContactPoints(String... hosts) {
      method withPort (line 105) | public StoringBuilder withPort(int port) {
      method withRetryAttempts (line 110) | public StoringBuilder withRetryAttempts(int retryAttempts) {
      method withoutMetrics (line 115) | public StoringBuilder withoutMetrics() {
      method build (line 120) | public Cluster build() {

FILE: src/com/xpinjection/patterns/chain/ModernAuthRequestHandler.java
  class ModernAuthRequestHandler (line 10) | public class ModernAuthRequestHandler implements Consumer<Request> {
    method accept (line 13) | @Override
    method getCurrentUser (line 20) | public static Long getCurrentUser() {

FILE: src/com/xpinjection/patterns/chain/ModernChainClient.java
  class ModernChainClient (line 11) | public class ModernChainClient {
    method main (line 12) | public static void main(String[] args) {
    method chain (line 18) | @SafeVarargs
    method log (line 25) | private static void log(Request request) {

FILE: src/com/xpinjection/patterns/chain/canonical/AbstractRequestHandler.java
  class AbstractRequestHandler (line 6) | public abstract class AbstractRequestHandler implements RequestHandler {
    method AbstractRequestHandler (line 9) | public AbstractRequestHandler(RequestHandler next) {
    method passToTheNext (line 13) | protected void passToTheNext(Request request) {

FILE: src/com/xpinjection/patterns/chain/canonical/AuthRequestHandler.java
  class AuthRequestHandler (line 6) | public class AuthRequestHandler extends AbstractRequestHandler {
    method AuthRequestHandler (line 9) | public AuthRequestHandler(RequestHandler next) {
    method handleRequest (line 13) | @Override
    method getCurrentUser (line 21) | public static Long getCurrentUser() {

FILE: src/com/xpinjection/patterns/chain/canonical/ChainClient.java
  class ChainClient (line 6) | public class ChainClient {
    method main (line 7) | public static void main(String[] args) {

FILE: src/com/xpinjection/patterns/chain/canonical/LoggingRequestHandler.java
  class LoggingRequestHandler (line 6) | public class LoggingRequestHandler extends AbstractRequestHandler {
    method LoggingRequestHandler (line 7) | public LoggingRequestHandler(RequestHandler next) {
    method handleRequest (line 11) | @Override

FILE: src/com/xpinjection/patterns/chain/canonical/Request.java
  class Request (line 9) | public class Request {
    method Request (line 13) | public Request(long userId) {
    method addParam (line 17) | public Request addParam(String name, String value) {
    method getUserId (line 22) | public long getUserId() {
    method getParams (line 26) | public Map<String, String> getParams() {
    method toString (line 30) | @Override

FILE: src/com/xpinjection/patterns/chain/canonical/RequestHandler.java
  type RequestHandler (line 6) | public interface RequestHandler {
    method handleRequest (line 7) | void handleRequest(Request request);

FILE: src/com/xpinjection/patterns/command/ModernCommandClient.java
  class ModernCommandClient (line 8) | public class ModernCommandClient {
    method main (line 9) | public static void main(String[] args) {

FILE: src/com/xpinjection/patterns/command/ModernMacro.java
  class ModernMacro (line 11) | public class ModernMacro {
    method record (line 14) | public ModernMacro record(Command action) {
    method run (line 19) | public void run() {

FILE: src/com/xpinjection/patterns/command/canonical/BoldCommand.java
  class BoldCommand (line 6) | public class BoldCommand implements Command {
    method BoldCommand (line 9) | public BoldCommand(Editor editor) {
    method execute (line 13) | @Override

FILE: src/com/xpinjection/patterns/command/canonical/Command.java
  type Command (line 6) | public interface Command {
    method execute (line 7) | void execute();

FILE: src/com/xpinjection/patterns/command/canonical/CommandClient.java
  class CommandClient (line 6) | public class CommandClient {
    method main (line 7) | public static void main(String[] args) {

FILE: src/com/xpinjection/patterns/command/canonical/Document.java
  class Document (line 6) | public class Document implements Editor {
    method bold (line 7) | @Override
    method italic (line 12) | @Override
    method underline (line 17) | @Override

FILE: src/com/xpinjection/patterns/command/canonical/Editor.java
  type Editor (line 6) | public interface Editor {
    method bold (line 7) | void bold();
    method italic (line 9) | void italic();
    method underline (line 11) | void underline();

FILE: src/com/xpinjection/patterns/command/canonical/ItalicCommand.java
  class ItalicCommand (line 6) | public class ItalicCommand implements Command {
    method ItalicCommand (line 9) | public ItalicCommand(Editor editor) {
    method execute (line 13) | @Override

FILE: src/com/xpinjection/patterns/command/canonical/Macro.java
  class Macro (line 9) | public class Macro {
    method record (line 12) | public void record(Command action) {
    method run (line 16) | public void run() {

FILE: src/com/xpinjection/patterns/command/canonical/UnderlineCommand.java
  class UnderlineCommand (line 6) | public class UnderlineCommand implements Command {
    method UnderlineCommand (line 9) | public UnderlineCommand(Editor editor) {
    method execute (line 13) | @Override

FILE: src/com/xpinjection/patterns/decorator/ModernDecoratorClient.java
  class ModernDecoratorClient (line 11) | public class ModernDecoratorClient {
    method main (line 12) | public static void main(String[] args) {
    method wrap (line 23) | public static DigitCounter wrap(DigitCounter counter) {

FILE: src/com/xpinjection/patterns/decorator/canonical/BenchmarkingDigitCounter.java
  class BenchmarkingDigitCounter (line 6) | public class BenchmarkingDigitCounter implements DigitCounter {
    method BenchmarkingDigitCounter (line 9) | public BenchmarkingDigitCounter(DigitCounter delegate) {
    method count (line 13) | @Override

FILE: src/com/xpinjection/patterns/decorator/canonical/DecoratorClient.java
  class DecoratorClient (line 6) | public class DecoratorClient {
    method main (line 7) | public static void main(String[] args) {

FILE: src/com/xpinjection/patterns/decorator/canonical/DigitCounter.java
  type DigitCounter (line 6) | public interface DigitCounter {
    method count (line 7) | int count(String str);

FILE: src/com/xpinjection/patterns/decorator/canonical/NaiveDigitCounter.java
  class NaiveDigitCounter (line 6) | public class NaiveDigitCounter implements DigitCounter {
    method count (line 7) | @Override

FILE: src/com/xpinjection/patterns/factorymethod/ModernFactoryMethodClient.java
  class ModernFactoryMethodClient (line 12) | public class ModernFactoryMethodClient {
    method main (line 13) | public static void main(String[] args) {
    method printUserDetails (line 21) | private static void printUserDetails(Document document) {

FILE: src/com/xpinjection/patterns/factorymethod/canonical/Document.java
  type Document (line 6) | public interface Document {
    method getName (line 7) | String getName();
    method addField (line 9) | void addField(String name, String value);
    method toString (line 11) | String toString();

FILE: src/com/xpinjection/patterns/factorymethod/canonical/DocumentFactory.java
  type DocumentFactory (line 6) | public interface DocumentFactory {
    method create (line 7) | Document create(String name);

FILE: src/com/xpinjection/patterns/factorymethod/canonical/FactoryMethodClient.java
  class FactoryMethodClient (line 6) | public class FactoryMethodClient {
    method main (line 7) | public static void main(String[] args) {

FILE: src/com/xpinjection/patterns/factorymethod/canonical/JsonDocument.java
  class JsonDocument (line 10) | public class JsonDocument implements Document {
    method JsonDocument (line 14) | public JsonDocument(String name) {
    method getName (line 18) | @Override
    method addField (line 23) | @Override
    method toString (line 28) | @Override

FILE: src/com/xpinjection/patterns/factorymethod/canonical/JsonDocumentFactory.java
  class JsonDocumentFactory (line 6) | public class JsonDocumentFactory implements DocumentFactory {
    method create (line 7) | @Override

FILE: src/com/xpinjection/patterns/iterator/ModernIteratorClient.java
  class ModernIteratorClient (line 9) | public class ModernIteratorClient {
    method main (line 10) | public static void main(String[] args) {
    method capitalize (line 22) | private static String capitalize(String sentence) {

FILE: src/com/xpinjection/patterns/iterator/ModernMultilineText.java
  class ModernMultilineText (line 12) | public class ModernMultilineText implements ModernText {
    method ModernMultilineText (line 16) | public ModernMultilineText(String text, String lineSeparator) {
    method linesStream (line 21) | @Override
    class LineSupplier (line 26) | private class LineSupplier extends Spliterators.AbstractSpliterator<St...
      method LineSupplier (line 29) | public LineSupplier() {
      method tryAdvance (line 33) | @Override

FILE: src/com/xpinjection/patterns/iterator/ModernText.java
  type ModernText (line 8) | public interface ModernText {
    method linesStream (line 9) | Stream<String> linesStream();

FILE: src/com/xpinjection/patterns/iterator/canonical/IteratorClient.java
  class IteratorClient (line 6) | public class IteratorClient {
    method main (line 7) | public static void main(String[] args) {
    method capitalize (line 24) | private static String capitalize(String sentence) {

FILE: src/com/xpinjection/patterns/iterator/canonical/LineIterator.java
  type LineIterator (line 6) | public interface LineIterator {
    method nextLine (line 7) | String nextLine();

FILE: src/com/xpinjection/patterns/iterator/canonical/MultilineText.java
  class MultilineText (line 6) | public class MultilineText implements Text {
    method MultilineText (line 10) | public MultilineText(String text, String lineSeparator) {
    method lineIterator (line 15) | @Override
    class SeparatorBasedLineIterator (line 20) | private class SeparatorBasedLineIterator implements LineIterator {
      method nextLine (line 23) | @Override

FILE: src/com/xpinjection/patterns/iterator/canonical/Text.java
  type Text (line 6) | public interface Text {
    method lineIterator (line 7) | LineIterator lineIterator();

FILE: src/com/xpinjection/patterns/observer/ModernObserver.java
  type ModernObserver (line 10) | public interface ModernObserver {
    method addListener (line 11) | void addListener(Consumer<Event> listener);

FILE: src/com/xpinjection/patterns/observer/ModernObserverClient.java
  class ModernObserverClient (line 8) | public class ModernObserverClient {
    method main (line 9) | public static void main(String[] args) {
    method log (line 17) | public static void log(Event event) {

FILE: src/com/xpinjection/patterns/observer/ModernTimeServer.java
  class ModernTimeServer (line 14) | public class ModernTimeServer implements ModernObserver {
    method addListener (line 19) | @Override
    method reportTime (line 24) | public void reportTime() {

FILE: src/com/xpinjection/patterns/observer/canonical/Event.java
  class Event (line 6) | public class Event {
    method Event (line 9) | public Event(String name) {
    method getName (line 13) | public String getName() {

FILE: src/com/xpinjection/patterns/observer/canonical/EventListener.java
  type EventListener (line 6) | public interface EventListener {
    method onEvent (line 7) | void onEvent(Event event);

FILE: src/com/xpinjection/patterns/observer/canonical/LoggingEventListener.java
  class LoggingEventListener (line 6) | public class LoggingEventListener implements EventListener {
    method onEvent (line 7) | @Override

FILE: src/com/xpinjection/patterns/observer/canonical/Observer.java
  type Observer (line 6) | public interface Observer {
    method addListener (line 7) | void addListener(EventListener listener);

FILE: src/com/xpinjection/patterns/observer/canonical/ObserverClient.java
  class ObserverClient (line 6) | public class ObserverClient {
    method main (line 7) | public static void main(String[] args) {

FILE: src/com/xpinjection/patterns/observer/canonical/TimeServer.java
  class TimeServer (line 11) | public class TimeServer implements Observer {
    method addListener (line 16) | @Override
    method reportTime (line 21) | public void reportTime() {

FILE: src/com/xpinjection/patterns/prototype/Stats.java
  type Stats (line 8) | public interface Stats<S> {
    method add (line 9) | S add(S delta);
    method invert (line 11) | S invert(Date forDate);

FILE: src/com/xpinjection/patterns/prototype/StatsProcessor.java
  class StatsProcessor (line 10) | public class StatsProcessor {
    method process (line 11) | public List<Stats> process(long domainId, List<TrafficStats> stats) {

FILE: src/com/xpinjection/patterns/prototype/TrafficStats.java
  class TrafficStats (line 8) | public class TrafficStats implements Stats<TrafficStats> {
    method TrafficStats (line 14) | public TrafficStats(long domainId, Date rankDate) {
    method TrafficStats (line 19) | private TrafficStats(long domainId, Date rankDate, long traffic) {
    method getDomainId (line 24) | public long getDomainId() {
    method getRankDate (line 28) | public Date getRankDate() {
    method setEstimatedTraffic (line 32) | public void setEstimatedTraffic(long estimatedTraffic) {
    method getEstimatedTraffic (line 36) | public long getEstimatedTraffic() {
    method add (line 40) | @Override
    method invert (line 45) | @Override
    method toString (line 50) | @Override

FILE: src/com/xpinjection/patterns/prototype/canonical/Circle.java
  class Circle (line 6) | public class Circle implements Figure {
    method Circle (line 9) | public Circle(int radix) {
    method changeRadix (line 13) | public void changeRadix(int delta) {
    method getSquare (line 17) | @Override
    method clone (line 22) | @Override

FILE: src/com/xpinjection/patterns/prototype/canonical/Editor.java
  class Editor (line 9) | public class Editor {
    method addCircle (line 15) | public Circle addCircle() {
    method addRectangle (line 21) | public Rectangle addRectangle() {

FILE: src/com/xpinjection/patterns/prototype/canonical/Figure.java
  type Figure (line 6) | public interface Figure {
    method getSquare (line 7) | double getSquare();
    method clone (line 9) | Figure clone();

FILE: src/com/xpinjection/patterns/prototype/canonical/PrototypeClient.java
  class PrototypeClient (line 6) | public class PrototypeClient {
    method main (line 7) | public static void main(String[] args) {

FILE: src/com/xpinjection/patterns/prototype/canonical/Rectangle.java
  class Rectangle (line 6) | public class Rectangle implements Figure {
    method Rectangle (line 10) | public Rectangle(int width, int height) {
    method changeSize (line 15) | public void changeSize(int widthDelta, int heightDelta) {
    method getSquare (line 20) | @Override
    method clone (line 25) | @Override

FILE: src/com/xpinjection/patterns/proxy/ModernProxyClient.java
  class ModernProxyClient (line 11) | public class ModernProxyClient {
    method main (line 12) | public static void main(String[] args) {

FILE: src/com/xpinjection/patterns/proxy/PermissionChecker.java
  class PermissionChecker (line 8) | public class PermissionChecker {
    method setCurrentUser (line 11) | public void setCurrentUser(long userId) {
    method checkPermission (line 15) | public void checkPermission(Order order) {

FILE: src/com/xpinjection/patterns/proxy/canonical/Order.java
  class Order (line 9) | public class Order {
    method Order (line 13) | public Order(long userId) {
    method putItem (line 17) | public void putItem(String code, int count) {
    method getUserId (line 21) | public long getUserId() {
    method getItems (line 25) | public Map<String, Integer> getItems() {
    method toString (line 29) | @Override

FILE: src/com/xpinjection/patterns/proxy/canonical/OrderService.java
  type OrderService (line 6) | public interface OrderService {
    method processOrder (line 7) | void processOrder(Order order);

FILE: src/com/xpinjection/patterns/proxy/canonical/PermissionCheckingOrderServiceProxy.java
  class PermissionCheckingOrderServiceProxy (line 6) | public class PermissionCheckingOrderServiceProxy implements OrderService {
    method PermissionCheckingOrderServiceProxy (line 10) | public PermissionCheckingOrderServiceProxy(OrderService delegate) {
    method setCurrentUser (line 14) | public void setCurrentUser(long userId) {
    method processOrder (line 18) | @Override

FILE: src/com/xpinjection/patterns/proxy/canonical/ProxyClient.java
  class ProxyClient (line 6) | public class ProxyClient {
    method main (line 7) | public static void main(String[] args) {

FILE: src/com/xpinjection/patterns/proxy/canonical/RealOrderService.java
  class RealOrderService (line 6) | public class RealOrderService implements OrderService {
    method processOrder (line 7) | @Override

FILE: src/com/xpinjection/patterns/singleton/ModernServiceRegistry.java
  class ModernServiceRegistry (line 11) | public class ModernServiceRegistry {
    method register (line 14) | public void register(NamedService service) {
    method getService (line 20) | public NamedService getService(String name) {

FILE: src/com/xpinjection/patterns/singleton/ModernSingletonClient.java
  class ModernSingletonClient (line 8) | public class ModernSingletonClient implements NamedService {
    method ModernSingletonClient (line 11) | public ModernSingletonClient(ModernServiceRegistry registry) {
    method main (line 15) | public static void main(String[] args) {
    method start (line 20) | public void start() {
    method getName (line 24) | @Override

FILE: src/com/xpinjection/patterns/singleton/canonical/NamedService.java
  type NamedService (line 6) | public interface NamedService {
    method getName (line 7) | String getName();

FILE: src/com/xpinjection/patterns/singleton/canonical/ServiceRegistry.java
  class ServiceRegistry (line 9) | public final class ServiceRegistry {
    method getInstance (line 12) | public static ServiceRegistry getInstance() {
    method ServiceRegistry (line 18) | private ServiceRegistry() {}
    method register (line 20) | public void register(NamedService service) {
    method getService (line 26) | public NamedService getService(String name) {

FILE: src/com/xpinjection/patterns/singleton/canonical/SingletonClient.java
  class SingletonClient (line 6) | public class SingletonClient implements NamedService {
    method main (line 7) | public static void main(String[] args) {
    method start (line 11) | public void start() {
    method getName (line 15) | @Override

FILE: src/com/xpinjection/patterns/strategy/ModernStrategyClient.java
  class ModernStrategyClient (line 10) | public class ModernStrategyClient {
    method ModernStrategyClient (line 13) | public ModernStrategyClient(ToIntFunction<Position> calculator) {
    method main (line 17) | public static void main(String[] args) {
    method process (line 26) | public void process(Position position) {

FILE: src/com/xpinjection/patterns/strategy/TrafficCalculationStrategies.java
  class TrafficCalculationStrategies (line 8) | public final class TrafficCalculationStrategies {
    method TrafficCalculationStrategies (line 12) | private TrafficCalculationStrategies() {}
    method calculateTrafficForPage (line 14) | public static int calculateTrafficForPage(Position position) {
    method calculateTopTrafficOnly (line 23) | public static int calculateTopTrafficOnly(Position position) {

FILE: src/com/xpinjection/patterns/strategy/canonical/PageTrafficCalculator.java
  class PageTrafficCalculator (line 6) | public class PageTrafficCalculator implements TrafficCalculator {
    method calculate (line 9) | @Override

FILE: src/com/xpinjection/patterns/strategy/canonical/Position.java
  class Position (line 6) | public class Position {
    method Position (line 10) | public Position(int rank, int mediaValue) {
    method getRank (line 15) | public int getRank() {
    method setRank (line 19) | public void setRank(int rank) {
    method getMediaValue (line 23) | public int getMediaValue() {
    method setMediaValue (line 27) | public void setMediaValue(int mediaValue) {
    method toString (line 31) | @Override

FILE: src/com/xpinjection/patterns/strategy/canonical/StrategyClient.java
  class StrategyClient (line 6) | public class StrategyClient {
    method StrategyClient (line 9) | public StrategyClient(TrafficCalculator calculator) {
    method main (line 13) | public static void main(String[] args) {
    method process (line 19) | public void process(Position position) {

FILE: src/com/xpinjection/patterns/strategy/canonical/TopTrafficCalculator.java
  class TopTrafficCalculator (line 6) | public class TopTrafficCalculator implements TrafficCalculator {
    method calculate (line 9) | @Override

FILE: src/com/xpinjection/patterns/strategy/canonical/TrafficCalculator.java
  type TrafficCalculator (line 6) | public interface TrafficCalculator {
    method calculate (line 7) | int calculate(Position position);

FILE: src/com/xpinjection/patterns/templatemethod/LoggingUserStorage.java
  class LoggingUserStorage (line 8) | public class LoggingUserStorage {
    method store (line 9) | public long store(User user) {

FILE: src/com/xpinjection/patterns/templatemethod/ModernTemplateMethodClient.java
  class ModernTemplateMethodClient (line 8) | public class ModernTemplateMethodClient {
    method main (line 9) | public static void main(String[] args) {

FILE: src/com/xpinjection/patterns/templatemethod/ModernUserRestorer.java
  class ModernUserRestorer (line 11) | public class ModernUserRestorer {
    method ModernUserRestorer (line 16) | public ModernUserRestorer(ToLongFunction<User> storage) {
    method restore (line 20) | public User restore(String serialized) {
    method parse (line 29) | private User parse(StringTokenizer tokenizer) {
    method validate (line 35) | private void validate(StringTokenizer tokenizer) {

FILE: src/com/xpinjection/patterns/templatemethod/canonical/AbstractUserRestorer.java
  class AbstractUserRestorer (line 8) | public abstract class AbstractUserRestorer {
    method restore (line 11) | public final User restore(String serialized) {
    method parse (line 20) | private User parse(StringTokenizer tokenizer) {
    method validate (line 26) | private void validate(StringTokenizer tokenizer) {
    method store (line 32) | protected abstract long store(User user);

FILE: src/com/xpinjection/patterns/templatemethod/canonical/LoggingUserRestorer.java
  class LoggingUserRestorer (line 6) | public class LoggingUserRestorer extends AbstractUserRestorer {
    method store (line 7) | @Override

FILE: src/com/xpinjection/patterns/templatemethod/canonical/TemplateMethodClient.java
  class TemplateMethodClient (line 6) | public class TemplateMethodClient {
    method main (line 7) | public static void main(String[] args) {

FILE: src/com/xpinjection/patterns/templatemethod/canonical/User.java
  class User (line 6) | public class User {
    method User (line 11) | public User(String name, int age) {
    method getId (line 16) | public Long getId() {
    method setId (line 20) | public void setId(Long id) {
    method getName (line 24) | public String getName() {
    method setName (line 28) | public void setName(String name) {
    method getAge (line 32) | public int getAge() {
    method setAge (line 36) | public void setAge(int age) {
    method toString (line 40) | @Override

FILE: src/com/xpinjection/patterns/visitor/LambdaVisitor.java
  class LambdaVisitor (line 10) | public class LambdaVisitor<A> implements Function<Object, A> {
    method on (line 13) | public <B> Acceptor<A, B> on(Class<B> clazz) {
    method apply (line 17) | @Override
    class Acceptor (line 22) | public static class Acceptor<A, B> {
      method Acceptor (line 26) | public Acceptor(LambdaVisitor<A> visitor, Class<B> clazz) {
      method then (line 31) | public LambdaVisitor<A> then(Function<B, A> f) {

FILE: src/com/xpinjection/patterns/visitor/ModernVisitorClient.java
  class ModernVisitorClient (line 14) | public class ModernVisitorClient {
    method main (line 25) | public static void main(String[] args) {

FILE: src/com/xpinjection/patterns/visitor/canonical/AreaVisitor.java
  class AreaVisitor (line 6) | public class AreaVisitor implements Visitor<Double> {
    method visit (line 7) | @Override
    method visit (line 12) | @Override
    method visit (line 17) | @Override

FILE: src/com/xpinjection/patterns/visitor/canonical/Circle.java
  class Circle (line 6) | public class Circle implements Element {
    method Circle (line 9) | public Circle(double radius) {
    method getRadius (line 13) | public double getRadius() {
    method accept (line 17) | @Override

FILE: src/com/xpinjection/patterns/visitor/canonical/Element.java
  type Element (line 6) | public interface Element {
    method accept (line 7) | <T> T accept(Visitor<T> visitor);

FILE: src/com/xpinjection/patterns/visitor/canonical/PerimeterVisitor.java
  class PerimeterVisitor (line 6) | public class PerimeterVisitor implements Visitor<Double> {
    method visit (line 7) | @Override
    method visit (line 12) | @Override
    method visit (line 17) | @Override

FILE: src/com/xpinjection/patterns/visitor/canonical/Rectangle.java
  class Rectangle (line 6) | public class Rectangle implements Element {
    method Rectangle (line 10) | public Rectangle(double width, double height) {
    method getWidth (line 15) | public double getWidth() {
    method getHeight (line 19) | public double getHeight() {
    method accept (line 23) | @Override

FILE: src/com/xpinjection/patterns/visitor/canonical/Square.java
  class Square (line 6) | public class Square implements Element {
    method Square (line 9) | public Square(double side) {
    method getSide (line 13) | public double getSide() {
    method accept (line 17) | @Override

FILE: src/com/xpinjection/patterns/visitor/canonical/Visitor.java
  type Visitor (line 6) | public interface Visitor<T> {
    method visit (line 7) | T visit(Square element);
    method visit (line 9) | T visit(Circle element);
    method visit (line 11) | T visit(Rectangle element);

FILE: src/com/xpinjection/patterns/visitor/canonical/VisitorClient.java
  class VisitorClient (line 9) | public class VisitorClient {
    method main (line 10) | public static void main(String[] args) {
Condensed preview — 104 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (70K chars).
[
  {
    "path": "LICENSE",
    "chars": 1074,
    "preview": "MIT License\n\nCopyright (c) 2017-2025 XP Injection\n\nPermission is hereby granted, free of charge, to any person obtaining"
  },
  {
    "path": "README.md",
    "chars": 159,
    "preview": "# design-patterns\nModern view on classic design patterns implementation in Java\n\n[blog article](http://javaday.org.ua/mo"
  },
  {
    "path": "src/com/xpinjection/patterns/adapter/ModernAdapterClient.java",
    "chars": 878,
    "preview": "package com.xpinjection.patterns.adapter;\n\nimport com.xpinjection.patterns.adapter.canonical.CharCounterTask;\n\nimport ja"
  },
  {
    "path": "src/com/xpinjection/patterns/adapter/canonical/AdapterClient.java",
    "chars": 834,
    "preview": "package com.xpinjection.patterns.adapter.canonical;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concu"
  },
  {
    "path": "src/com/xpinjection/patterns/adapter/canonical/CharCounterTask.java",
    "chars": 491,
    "preview": "package com.xpinjection.patterns.adapter.canonical;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n* @author Al"
  },
  {
    "path": "src/com/xpinjection/patterns/adapter/canonical/ExecutorConsumerAdaptor.java",
    "chars": 463,
    "preview": "package com.xpinjection.patterns.adapter.canonical;\n\nimport java.util.concurrent.Executor;\nimport java.util.function.Con"
  },
  {
    "path": "src/com/xpinjection/patterns/builder/FutureBuilderClient.java",
    "chars": 376,
    "preview": "package com.xpinjection.patterns.builder;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class FutureBuilderClient {\n    /"
  },
  {
    "path": "src/com/xpinjection/patterns/builder/FutureCluster.java",
    "chars": 303,
    "preview": "package com.xpinjection.patterns.builder;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class FutureCluster {\n    /** Wit"
  },
  {
    "path": "src/com/xpinjection/patterns/builder/LombokBuilderClient.java",
    "chars": 335,
    "preview": "package com.xpinjection.patterns.builder;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class LombokBuilderClient {\n    p"
  },
  {
    "path": "src/com/xpinjection/patterns/builder/LombokCluster.java",
    "chars": 353,
    "preview": "package com.xpinjection.patterns.builder;\n\nimport lombok.Builder;\nimport lombok.Getter;\nimport lombok.Singular;\n\nimport "
  },
  {
    "path": "src/com/xpinjection/patterns/builder/canonical/BuilderClient.java",
    "chars": 553,
    "preview": "package com.xpinjection.patterns.builder.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class BuilderClient {\n "
  },
  {
    "path": "src/com/xpinjection/patterns/builder/canonical/Cluster.java",
    "chars": 3146,
    "preview": "package com.xpinjection.patterns.builder.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class Cluster {\n    pri"
  },
  {
    "path": "src/com/xpinjection/patterns/chain/ModernAuthRequestHandler.java",
    "chars": 641,
    "preview": "package com.xpinjection.patterns.chain;\n\nimport com.xpinjection.patterns.chain.canonical.Request;\n\nimport java.util.func"
  },
  {
    "path": "src/com/xpinjection/patterns/chain/ModernChainClient.java",
    "chars": 751,
    "preview": "package com.xpinjection.patterns.chain;\n\nimport com.xpinjection.patterns.chain.canonical.Request;\n\nimport java.util.func"
  },
  {
    "path": "src/com/xpinjection/patterns/chain/canonical/AbstractRequestHandler.java",
    "chars": 430,
    "preview": "package com.xpinjection.patterns.chain.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic abstract class AbstractRe"
  },
  {
    "path": "src/com/xpinjection/patterns/chain/canonical/AuthRequestHandler.java",
    "chars": 672,
    "preview": "package com.xpinjection.patterns.chain.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class AuthRequestHandler "
  },
  {
    "path": "src/com/xpinjection/patterns/chain/canonical/ChainClient.java",
    "chars": 340,
    "preview": "package com.xpinjection.patterns.chain.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class ChainClient {\n    p"
  },
  {
    "path": "src/com/xpinjection/patterns/chain/canonical/LoggingRequestHandler.java",
    "chars": 402,
    "preview": "package com.xpinjection.patterns.chain.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class LoggingRequestHandl"
  },
  {
    "path": "src/com/xpinjection/patterns/chain/canonical/Request.java",
    "chars": 705,
    "preview": "package com.xpinjection.patterns.chain.canonical;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * @author Alime"
  },
  {
    "path": "src/com/xpinjection/patterns/chain/canonical/RequestHandler.java",
    "chars": 165,
    "preview": "package com.xpinjection.patterns.chain.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface RequestHandler "
  },
  {
    "path": "src/com/xpinjection/patterns/command/ModernCommandClient.java",
    "chars": 461,
    "preview": "package com.xpinjection.patterns.command;\n\nimport com.xpinjection.patterns.command.canonical.Document;\n\n/**\n * @author A"
  },
  {
    "path": "src/com/xpinjection/patterns/command/ModernMacro.java",
    "chars": 464,
    "preview": "package com.xpinjection.patterns.command;\n\nimport com.xpinjection.patterns.command.canonical.Command;\n\nimport java.util."
  },
  {
    "path": "src/com/xpinjection/patterns/command/canonical/BoldCommand.java",
    "chars": 320,
    "preview": "package com.xpinjection.patterns.command.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class BoldCommand imple"
  },
  {
    "path": "src/com/xpinjection/patterns/command/canonical/Command.java",
    "chars": 139,
    "preview": "package com.xpinjection.patterns.command.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface Command {\n   "
  },
  {
    "path": "src/com/xpinjection/patterns/command/canonical/CommandClient.java",
    "chars": 419,
    "preview": "package com.xpinjection.patterns.command.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class CommandClient {\n "
  },
  {
    "path": "src/com/xpinjection/patterns/command/canonical/Document.java",
    "chars": 417,
    "preview": "package com.xpinjection.patterns.command.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class Document implemen"
  },
  {
    "path": "src/com/xpinjection/patterns/command/canonical/Editor.java",
    "chars": 178,
    "preview": "package com.xpinjection.patterns.command.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface Editor {\n    "
  },
  {
    "path": "src/com/xpinjection/patterns/command/canonical/ItalicCommand.java",
    "chars": 327,
    "preview": "package com.xpinjection.patterns.command.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class ItalicCommand imp"
  },
  {
    "path": "src/com/xpinjection/patterns/command/canonical/Macro.java",
    "chars": 420,
    "preview": "package com.xpinjection.patterns.command.canonical;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * @author "
  },
  {
    "path": "src/com/xpinjection/patterns/command/canonical/UnderlineCommand.java",
    "chars": 335,
    "preview": "package com.xpinjection.patterns.command.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class UnderlineCommand "
  },
  {
    "path": "src/com/xpinjection/patterns/decorator/ModernDecoratorClient.java",
    "chars": 1106,
    "preview": "package com.xpinjection.patterns.decorator;\n\nimport com.xpinjection.patterns.decorator.canonical.DigitCounter;\nimport co"
  },
  {
    "path": "src/com/xpinjection/patterns/decorator/canonical/BenchmarkingDigitCounter.java",
    "chars": 602,
    "preview": "package com.xpinjection.patterns.decorator.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class BenchmarkingDig"
  },
  {
    "path": "src/com/xpinjection/patterns/decorator/canonical/DecoratorClient.java",
    "chars": 378,
    "preview": "package com.xpinjection.patterns.decorator.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class DecoratorClient"
  },
  {
    "path": "src/com/xpinjection/patterns/decorator/canonical/DigitCounter.java",
    "chars": 153,
    "preview": "package com.xpinjection.patterns.decorator.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface DigitCounte"
  },
  {
    "path": "src/com/xpinjection/patterns/decorator/canonical/NaiveDigitCounter.java",
    "chars": 425,
    "preview": "package com.xpinjection.patterns.decorator.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class NaiveDigitCount"
  },
  {
    "path": "src/com/xpinjection/patterns/factorymethod/ModernFactoryMethodClient.java",
    "chars": 858,
    "preview": "package com.xpinjection.patterns.factorymethod;\n\nimport com.xpinjection.patterns.factorymethod.canonical.Document;\nimpor"
  },
  {
    "path": "src/com/xpinjection/patterns/factorymethod/canonical/Document.java",
    "chars": 219,
    "preview": "package com.xpinjection.patterns.factorymethod.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface Documen"
  },
  {
    "path": "src/com/xpinjection/patterns/factorymethod/canonical/DocumentFactory.java",
    "chars": 167,
    "preview": "package com.xpinjection.patterns.factorymethod.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface Documen"
  },
  {
    "path": "src/com/xpinjection/patterns/factorymethod/canonical/FactoryMethodClient.java",
    "chars": 432,
    "preview": "package com.xpinjection.patterns.factorymethod.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class FactoryMeth"
  },
  {
    "path": "src/com/xpinjection/patterns/factorymethod/canonical/JsonDocument.java",
    "chars": 811,
    "preview": "package com.xpinjection.patterns.factorymethod.canonical;\n\nimport java.util.LinkedHashMap;\nimport java.util.Map;\nimport "
  },
  {
    "path": "src/com/xpinjection/patterns/factorymethod/canonical/JsonDocumentFactory.java",
    "chars": 261,
    "preview": "package com.xpinjection.patterns.factorymethod.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class JsonDocumen"
  },
  {
    "path": "src/com/xpinjection/patterns/iterator/ModernIteratorClient.java",
    "chars": 868,
    "preview": "package com.xpinjection.patterns.iterator;\n\nimport java.util.Arrays;\nimport java.util.stream.Collectors;\n\n/**\n * @author"
  },
  {
    "path": "src/com/xpinjection/patterns/iterator/ModernMultilineText.java",
    "chars": 1460,
    "preview": "package com.xpinjection.patterns.iterator;\n\nimport java.util.Spliterator;\nimport java.util.Spliterators;\nimport java.uti"
  },
  {
    "path": "src/com/xpinjection/patterns/iterator/ModernText.java",
    "chars": 180,
    "preview": "package com.xpinjection.patterns.iterator;\n\nimport java.util.stream.Stream;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic"
  },
  {
    "path": "src/com/xpinjection/patterns/iterator/canonical/IteratorClient.java",
    "chars": 1069,
    "preview": "package com.xpinjection.patterns.iterator.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class IteratorClient {"
  },
  {
    "path": "src/com/xpinjection/patterns/iterator/canonical/LineIterator.java",
    "chars": 148,
    "preview": "package com.xpinjection.patterns.iterator.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface LineIterator"
  },
  {
    "path": "src/com/xpinjection/patterns/iterator/canonical/MultilineText.java",
    "chars": 1069,
    "preview": "package com.xpinjection.patterns.iterator.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class MultilineText im"
  },
  {
    "path": "src/com/xpinjection/patterns/iterator/canonical/Text.java",
    "chars": 150,
    "preview": "package com.xpinjection.patterns.iterator.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface Text {\n    L"
  },
  {
    "path": "src/com/xpinjection/patterns/observer/ModernObserver.java",
    "chars": 261,
    "preview": "package com.xpinjection.patterns.observer;\n\nimport com.xpinjection.patterns.observer.canonical.Event;\n\nimport java.util."
  },
  {
    "path": "src/com/xpinjection/patterns/observer/ModernObserverClient.java",
    "chars": 592,
    "preview": "package com.xpinjection.patterns.observer;\n\nimport com.xpinjection.patterns.observer.canonical.Event;\n\n/**\n * @author Al"
  },
  {
    "path": "src/com/xpinjection/patterns/observer/ModernTimeServer.java",
    "chars": 811,
    "preview": "package com.xpinjection.patterns.observer;\n\nimport com.xpinjection.patterns.observer.canonical.Event;\n\nimport java.text."
  },
  {
    "path": "src/com/xpinjection/patterns/observer/canonical/Event.java",
    "chars": 268,
    "preview": "package com.xpinjection.patterns.observer.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class Event {\n    priv"
  },
  {
    "path": "src/com/xpinjection/patterns/observer/canonical/EventListener.java",
    "chars": 157,
    "preview": "package com.xpinjection.patterns.observer.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface EventListene"
  },
  {
    "path": "src/com/xpinjection/patterns/observer/canonical/LoggingEventListener.java",
    "chars": 270,
    "preview": "package com.xpinjection.patterns.observer.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class LoggingEventList"
  },
  {
    "path": "src/com/xpinjection/patterns/observer/canonical/Observer.java",
    "chars": 167,
    "preview": "package com.xpinjection.patterns.observer.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface Observer {\n "
  },
  {
    "path": "src/com/xpinjection/patterns/observer/canonical/ObserverClient.java",
    "chars": 334,
    "preview": "package com.xpinjection.patterns.observer.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class ObserverClient {"
  },
  {
    "path": "src/com/xpinjection/patterns/observer/canonical/TimeServer.java",
    "chars": 708,
    "preview": "package com.xpinjection.patterns.observer.canonical;\n\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimp"
  },
  {
    "path": "src/com/xpinjection/patterns/prototype/Stats.java",
    "chars": 185,
    "preview": "package com.xpinjection.patterns.prototype;\n\nimport java.util.Date;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interfa"
  },
  {
    "path": "src/com/xpinjection/patterns/prototype/StatsProcessor.java",
    "chars": 496,
    "preview": "package com.xpinjection.patterns.prototype;\n\nimport java.util.Date;\nimport java.util.List;\nimport java.util.stream.Colle"
  },
  {
    "path": "src/com/xpinjection/patterns/prototype/TrafficStats.java",
    "chars": 1381,
    "preview": "package com.xpinjection.patterns.prototype;\n\nimport java.util.Date;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class T"
  },
  {
    "path": "src/com/xpinjection/patterns/prototype/canonical/Circle.java",
    "chars": 471,
    "preview": "package com.xpinjection.patterns.prototype.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class Circle implemen"
  },
  {
    "path": "src/com/xpinjection/patterns/prototype/canonical/Editor.java",
    "chars": 650,
    "preview": "package com.xpinjection.patterns.prototype.canonical;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * @autho"
  },
  {
    "path": "src/com/xpinjection/patterns/prototype/canonical/Figure.java",
    "chars": 165,
    "preview": "package com.xpinjection.patterns.prototype.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface Figure {\n  "
  },
  {
    "path": "src/com/xpinjection/patterns/prototype/canonical/PrototypeClient.java",
    "chars": 381,
    "preview": "package com.xpinjection.patterns.prototype.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class PrototypeClient"
  },
  {
    "path": "src/com/xpinjection/patterns/prototype/canonical/Rectangle.java",
    "chars": 605,
    "preview": "package com.xpinjection.patterns.prototype.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class Rectangle imple"
  },
  {
    "path": "src/com/xpinjection/patterns/proxy/ModernProxyClient.java",
    "chars": 783,
    "preview": "package com.xpinjection.patterns.proxy;\n\nimport com.xpinjection.patterns.proxy.canonical.Order;\nimport com.xpinjection.p"
  },
  {
    "path": "src/com/xpinjection/patterns/proxy/PermissionChecker.java",
    "chars": 544,
    "preview": "package com.xpinjection.patterns.proxy;\n\nimport com.xpinjection.patterns.proxy.canonical.Order;\n\n/**\n * @author Alimenko"
  },
  {
    "path": "src/com/xpinjection/patterns/proxy/canonical/Order.java",
    "chars": 667,
    "preview": "package com.xpinjection.patterns.proxy.canonical;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * @author Alime"
  },
  {
    "path": "src/com/xpinjection/patterns/proxy/canonical/OrderService.java",
    "chars": 158,
    "preview": "package com.xpinjection.patterns.proxy.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface OrderService {\n"
  },
  {
    "path": "src/com/xpinjection/patterns/proxy/canonical/PermissionCheckingOrderServiceProxy.java",
    "chars": 743,
    "preview": "package com.xpinjection.patterns.proxy.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class PermissionCheckingO"
  },
  {
    "path": "src/com/xpinjection/patterns/proxy/canonical/ProxyClient.java",
    "chars": 573,
    "preview": "package com.xpinjection.patterns.proxy.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class ProxyClient {\n    p"
  },
  {
    "path": "src/com/xpinjection/patterns/proxy/canonical/RealOrderService.java",
    "chars": 267,
    "preview": "package com.xpinjection.patterns.proxy.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class RealOrderService im"
  },
  {
    "path": "src/com/xpinjection/patterns/proxy/spring-context.xml",
    "chars": 1001,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:aop=\"http"
  },
  {
    "path": "src/com/xpinjection/patterns/singleton/ModernServiceRegistry.java",
    "chars": 664,
    "preview": "package com.xpinjection.patterns.singleton;\n\nimport com.xpinjection.patterns.singleton.canonical.NamedService;\n\nimport j"
  },
  {
    "path": "src/com/xpinjection/patterns/singleton/ModernSingletonClient.java",
    "chars": 685,
    "preview": "package com.xpinjection.patterns.singleton;\n\nimport com.xpinjection.patterns.singleton.canonical.NamedService;\n\n/**\n * @"
  },
  {
    "path": "src/com/xpinjection/patterns/singleton/canonical/NamedService.java",
    "chars": 148,
    "preview": "package com.xpinjection.patterns.singleton.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface NamedServic"
  },
  {
    "path": "src/com/xpinjection/patterns/singleton/canonical/ServiceRegistry.java",
    "chars": 799,
    "preview": "package com.xpinjection.patterns.singleton.canonical;\n\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.c"
  },
  {
    "path": "src/com/xpinjection/patterns/singleton/canonical/SingletonClient.java",
    "chars": 400,
    "preview": "package com.xpinjection.patterns.singleton.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class SingletonClient"
  },
  {
    "path": "src/com/xpinjection/patterns/singleton/spring-context.xml",
    "chars": 679,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "src/com/xpinjection/patterns/strategy/ModernStrategyClient.java",
    "chars": 989,
    "preview": "package com.xpinjection.patterns.strategy;\n\nimport com.xpinjection.patterns.strategy.canonical.Position;\n\nimport java.ut"
  },
  {
    "path": "src/com/xpinjection/patterns/strategy/TrafficCalculationStrategies.java",
    "chars": 900,
    "preview": "package com.xpinjection.patterns.strategy;\n\nimport com.xpinjection.patterns.strategy.canonical.Position;\n\n/**\n * @author"
  },
  {
    "path": "src/com/xpinjection/patterns/strategy/canonical/PageTrafficCalculator.java",
    "chars": 471,
    "preview": "package com.xpinjection.patterns.strategy.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class PageTrafficCalcu"
  },
  {
    "path": "src/com/xpinjection/patterns/strategy/canonical/Position.java",
    "chars": 699,
    "preview": "package com.xpinjection.patterns.strategy.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class Position {\n    p"
  },
  {
    "path": "src/com/xpinjection/patterns/strategy/canonical/StrategyClient.java",
    "chars": 715,
    "preview": "package com.xpinjection.patterns.strategy.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class StrategyClient {"
  },
  {
    "path": "src/com/xpinjection/patterns/strategy/canonical/TopTrafficCalculator.java",
    "chars": 490,
    "preview": "package com.xpinjection.patterns.strategy.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class TopTrafficCalcul"
  },
  {
    "path": "src/com/xpinjection/patterns/strategy/canonical/TrafficCalculator.java",
    "chars": 168,
    "preview": "package com.xpinjection.patterns.strategy.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface TrafficCalcu"
  },
  {
    "path": "src/com/xpinjection/patterns/templatemethod/LoggingUserStorage.java",
    "chars": 326,
    "preview": "package com.xpinjection.patterns.templatemethod;\n\nimport com.xpinjection.patterns.templatemethod.canonical.User;\n\n/**\n *"
  },
  {
    "path": "src/com/xpinjection/patterns/templatemethod/ModernTemplateMethodClient.java",
    "chars": 623,
    "preview": "package com.xpinjection.patterns.templatemethod;\n\nimport com.xpinjection.patterns.templatemethod.canonical.User;\n\n/**\n *"
  },
  {
    "path": "src/com/xpinjection/patterns/templatemethod/ModernUserRestorer.java",
    "chars": 1139,
    "preview": "package com.xpinjection.patterns.templatemethod;\n\nimport com.xpinjection.patterns.templatemethod.canonical.User;\n\nimport"
  },
  {
    "path": "src/com/xpinjection/patterns/templatemethod/canonical/AbstractUserRestorer.java",
    "chars": 943,
    "preview": "package com.xpinjection.patterns.templatemethod.canonical;\n\nimport java.util.StringTokenizer;\n\n/**\n * @author Alimenkou "
  },
  {
    "path": "src/com/xpinjection/patterns/templatemethod/canonical/LoggingUserRestorer.java",
    "chars": 319,
    "preview": "package com.xpinjection.patterns.templatemethod.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class LoggingUse"
  },
  {
    "path": "src/com/xpinjection/patterns/templatemethod/canonical/TemplateMethodClient.java",
    "chars": 321,
    "preview": "package com.xpinjection.patterns.templatemethod.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class TemplateMe"
  },
  {
    "path": "src/com/xpinjection/patterns/templatemethod/canonical/User.java",
    "chars": 773,
    "preview": "package com.xpinjection.patterns.templatemethod.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class User {\n   "
  },
  {
    "path": "src/com/xpinjection/patterns/visitor/LambdaVisitor.java",
    "chars": 938,
    "preview": "package com.xpinjection.patterns.visitor;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.function.Fun"
  },
  {
    "path": "src/com/xpinjection/patterns/visitor/ModernVisitorClient.java",
    "chars": 1543,
    "preview": "package com.xpinjection.patterns.visitor;\n\nimport com.xpinjection.patterns.visitor.canonical.Circle;\nimport com.xpinject"
  },
  {
    "path": "src/com/xpinjection/patterns/visitor/canonical/AreaVisitor.java",
    "chars": 516,
    "preview": "package com.xpinjection.patterns.visitor.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class AreaVisitor imple"
  },
  {
    "path": "src/com/xpinjection/patterns/visitor/canonical/Circle.java",
    "chars": 403,
    "preview": "package com.xpinjection.patterns.visitor.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class Circle implements"
  },
  {
    "path": "src/com/xpinjection/patterns/visitor/canonical/Element.java",
    "chars": 157,
    "preview": "package com.xpinjection.patterns.visitor.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface Element {\n   "
  },
  {
    "path": "src/com/xpinjection/patterns/visitor/canonical/PerimeterVisitor.java",
    "chars": 497,
    "preview": "package com.xpinjection.patterns.visitor.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class PerimeterVisitor "
  },
  {
    "path": "src/com/xpinjection/patterns/visitor/canonical/Rectangle.java",
    "chars": 542,
    "preview": "package com.xpinjection.patterns.visitor.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class Rectangle impleme"
  },
  {
    "path": "src/com/xpinjection/patterns/visitor/canonical/Square.java",
    "chars": 391,
    "preview": "package com.xpinjection.patterns.visitor.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic class Square implements"
  },
  {
    "path": "src/com/xpinjection/patterns/visitor/canonical/Visitor.java",
    "chars": 214,
    "preview": "package com.xpinjection.patterns.visitor.canonical;\n\n/**\n * @author Alimenkou Mikalai\n */\npublic interface Visitor<T> {\n"
  },
  {
    "path": "src/com/xpinjection/patterns/visitor/canonical/VisitorClient.java",
    "chars": 856,
    "preview": "package com.xpinjection.patterns.visitor.canonical;\n\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * @author Ali"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the xpinjection/design-patterns GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 104 files (56.5 KB), approximately 16.4k tokens, and a symbol index with 335 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!