Ява: Я пропустил ограничивающий паттерн?Мне нужно ограничить реализацию только выбранными методами - PullRequest
0 голосов
/ 26 сентября 2011

Скажем, у меня есть некоторый класс, который слишком жирный методов для одного конкретного случая, но подходит примерно для половины из них, так что нет ничего другого, кроме как расширить его.Одновременно я хочу скрыть тот факт, что я расширил этот толстый класс от конечных пользователей.Затем я хочу ограничить этот класс некоторым новым интерфейсом и позволить ненужным методам выбросить UnsupportedOperationException:

public class TooFatClass {
    public void usefulMethodOne() { ... };
    public void usefulMethodTwo() { ... };
    public void usefulMethodThree() { ... };
    ...
    public void notUsefulMethodOne() { ... };
    public void notUsefulMethodTwo() { ... };
    public void notUsefulMethodThree() { ... };
    ...
}

public interface OnlyUsefulMethods {
    public void usefulMethodOne();
    public void usefulMethodTwo();
    public void usefulMethodThree();
    ...

    public static OnlyUsefulMethods create() {
        return new OnlyUsefulMethodsImpl();
    }
}

// notice it is package-private
class OnlyUsefulMethodsImpl extends TooFatClass implements OnlyUsefulMethods {
    public void usefulMethodOne() { ... };
    public void usefulMethodTwo() { ... };
    public void usefulMethodThree() { ... };
    ...
    public void notUsefulMethodOne() { throw new UnsupportedOperationException(); };
    public void notUsefulMethodTwo() { throw new UnsupportedOperationException(); };
    public void notUsefulMethodThree() { throw new UnsupportedOperationException(); };
    ...        
}

Итак, OnlyUsefulMethodsImpl экземпляр может быть приведен к TooFatClass, еслипользователь действительно хочет, но он скрывает этот факт и не заставляет пользователя делать это.

Однако java не допускает реализации статических методов в интерфейсах (я думаю, это глупо OnlyUsefulMethods абстрактно), поэтому я заканчиваю с этим вонючим фрагментом кода:

public interface OnlyUsefulMethods {
    public void usefulMethodOne();
    public void usefulMethodTwo();
    public void usefulMethodThree();
    ...

    public static final class Factory {
        public static OnlyUsefulMethods create() { return new OnlyUsefulMethodsImpl(); }
        public static OnlyUsefulMethods create(Options options) { 
               return new OnlyUsefulMethodsImpl(options); }
    }    

}

Даже если я переместу Factory за пределы интерфейса, он выглядит слишком сложным, чтобы использовать его только для одного класса, я хочу использовать фабричный метод, не показывая OnlyUsefulMethodsImpl снаружи.

Я что-то не так делаю/ слишком сложный и отсутствует какой-либо ограничивающий шаблон?


Может быть связан с этими вопросами (в любом случае, есть некоторые ответы, которые могут быть подходящими, я не уверен):

Ответы [ 2 ]

4 голосов
/ 26 сентября 2011

Звучит как хорошее время для делегирования.

Класс «худенький» оборачивает класс «толстый» и предоставляет только интерфейс класса «худой».Некоторые идентификаторы могут помочь вам реализовать делегирование.

2 голосов
/ 26 сентября 2011
class OnlyUsefulMethods extends TooFatClass{
    public void usefulMethodOne() { ... };
    public void usefulMethodTwo() { ... };
    public void usefulMethodThree() { ... };
    ...
    public void notUsefulMethodOne() { throw new UnsupportedOperationException(); };
    public void notUsefulMethodTwo() { throw new UnsupportedOperationException(); };
    public void notUsefulMethodThree() { throw new UnsupportedOperationException(); };
    ...        
}

Иногда я задаюсь вопросом, почему шаблоны могут усложнять ситуацию ... Не нужно фабрики, вы можете напрямую создать ее экземпляр с помощью new.

Вы также можете использовать шаблон композиции, чтобы обернуть экземпляр TooFatClass внутри класса, который предоставляет только необходимые методы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...