Что бы вы хотели исправить и / или улучшить в java-реализации Chain Of Responsibility? - PullRequest
1 голос
/ 15 июня 2010
package design.pattern.behavioral;

import design.pattern.behavioral.ChainOfResponsibility.*;

public class ChainOfResponsibility {
    public static class Chain {
        private Request[] requests = null;
        private Handler[] handlers = null;
        public Chain(Handler[] handlers, Request[] requests){
            this.handlers = handlers;
            this.requests = requests;
        }

        public void start() {
            for(Request r : requests)
              for (Handler h : handlers)
                    if(h.handle(r)) break;
        }
    }

    public static class Request {
        private int value;

        public Request setValue(int value){
            this.value = value;
            return this;
        }

        public int getValue() {
            return value;
        }
    }

    public static class Handler<T> {
        private Command<T> command = null;
        public Handler(Command<T> command) {
            this.command = command;
        }
        public boolean handle(T request) {
            return command.execute(request);
        }
    }

    public static abstract class Command<T>{
        public abstract Boolean execute(T request);
    }
}

class TestChainOfResponsibility {
     public static void main(String[] args) {
        new TestChainOfResponsibility().test();
    }

    private void test() {
        new Chain(new Handler[]{ // chain of responsibility
                new Handler<Request>(
                        new Command<Request>(){ // command
                            public Boolean execute(Request condition) {
                                boolean result = condition.getValue() >= 600;
                                if (result)  System.out.println("You are rich: " + condition.getValue()  + " (id: " + condition.hashCode() + ")");
                                return result;
                            }
                        }
                ),
                new Handler<Request>(
                        new Command<Request>(){
                            public Boolean execute(Request condition) {
                                boolean result = condition.getValue() >= 100;
                                if(result) System.out.println("You are poor: " + condition.getValue()  + " (id: " + condition.hashCode() + ")");
                                return result;
                            }
                        }
                ),
        },
        new Request[]{
                new Request().setValue(600), // chaining method
                new Request().setValue(100),
        }
        ).start();
    }
}

Ответы [ 3 ]

4 голосов
/ 15 июня 2010

Я не думаю, что есть значимый ответ на такой общий вопрос. Шаблоны проектирования не существуют изолированно и не имеют «идеальной формы»: они живут в контексте.

Шаблон - это решение проблемы в контексте .

Так что, не зная контекста вашего решения, мы мало что можем сказать по этому поводу. Какую конкретную проблему вы пытаетесь решить? Какие силы в игре? Каковы ваши ограничения? Есть ли у вас проблемы / проблемы с текущим решением? Если вы дадите более подробную информацию об этом, возможно, мы сможем дать лучший ответ.

2 голосов
/ 15 июня 2010

Лямбда не очень описательна (для большинства разработчиков).Это то, что вы извлекаете из теории функционального языка?

0 голосов
/ 15 июня 2010

Я бы, вероятно, просто избавился от класса 'control' и связал отдельные обработчики напрямую друг с другом - в основном, использовал бы больше подхода IoC.

Пример (в C #, простите) за запрос ...

    public interface IIntMessage
    {
        void HandleMesasge(int i);
    }

    public class EvenPrinter : IIntMessage
    {
        private IIntMessage m_next;

        public EvenPrinter(IIntMessage next)
        {
            m_next = next;
        }
        public void HandleMesasge(int i)
        {
            if(i % 2 == 0)
            {
                System.Console.WriteLine("Even!");
            }
            else
            {
                m_next.HandleMesasge(i);
            }
        }            
    }
    public class OddPrinter : IIntMessage
    {
        private IIntMessage m_next;

        public OddPrinter(IIntMessage next)
        {
            m_next = next;
        }
        public void HandleMesasge(int i)
        {
            if(i%2 == 1)
            {
                System.Console.WriteLine("Odd!");
            }
            else
            {
                m_next.HandleMesasge(i);
            }
        }
    }

Обратите внимание, что мы полностью избавляемся от "управляющего" класса и просто позволяем обработчикам запросов напрямую связываться друг с другом, не обращаясь к посреднику.

Кроме того, я мог бы, вероятно, извлечь «базовый» обработчик запроса цепочки команд, удалив часть дублирующего кода.

...