Создание java-методов, которые можно вызывать так: foo.bar (). Baz (). Quux () - PullRequest
2 голосов
/ 15 июля 2010

Я не уверен, как именно это называется, но мне было интересно, как вы можете создать класс, к которому можно вызывать несколько методов за один вызов.Например, используя класс Android, но это не имеет особого значения, вы можете вызывать все методы класса сразу:вернул this, но похоже, что это вызовет проблемы.Я не уверен, как, но это только кажется.

Кроме того, у этой техники есть имя?

Ответы [ 8 ]

7 голосов
/ 15 июля 2010

Этот метод называется метод цепочки , и он работает именно так, как вы себе представляли. У вас просто есть функции, возвращающие this вместо void.

3 голосов
/ 15 июля 2010

Кроме того, вместо того, чтобы создавать свой класс, чтобы всегда возвращать «this», вы также можете просто использовать хак для создания экземпляра класса с двойной скобкой, с обычным классом Java:

AlertDialog.Builder(){{
  setItem();
  setTitle();
  setPositiveButton();
  setCancelable();
   ...etc
}}

вот хороший справочник - http://www.c2.com/cgi/wiki?DoubleBraceInitialization

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

Это шаблон Builder .
То, что вы эффективно делаете, это:

AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setIcon(android.R.drawable.icon);
builder.setTitle(R.string.title);
builder.setMessage(R.string.message);
//etc.
1 голос
/ 15 июля 2010

Я всегда называл этот тип объекта "строителем".

Обратите внимание, что хорошие дизайны, как правило, имеют в конце вызов .build () для возврата создаваемого вами экземпляра.

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

1 голос
/ 15 июля 2010

Идея заключается в том, чтобы вернуть ссылку на this. Давайте посмотрим на простой пример:

class A{
    public A setStuffs(){
        return this;
    }
    public A setOtherStuffs(){
        return this;
    }
}

Тогда вы можете сделать:

A a = new A().setStuffs().setOtherStuffs();

Вы увидите это в классах, использующих шаблон Builder, например AlertDialog.Builder. Но я обычно делаю это на каждом занятии, потому что это помогает мне сохранять строки кода.

1 голос
/ 15 июля 2010

Это не вызовет проблем. Возвращение this является стандартной практикой для достижения этой цели.

Java StringBuilder является примером. ( см. Источник )

Говорят, что такие классы имеют свободный интерфейс

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

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

(хотя и плохое) решение состоит в том, чтобы перегрузить все ваши методы логическим аргументом для ReturnThis, который вызывает функцию, а затем возвращает это. Тем не менее, я бы определенно рекомендовал шаблон строителя вместо этого.

OR! Функция, которая принимает побитовый аргумент, выбирая, какие функции вы хотите выполнить! (ZOMG, это ужасное решение!)

ИЛИ ЕЩЕ! Используйте C # и создайте метод, который принимает массив параметров делегатов (указателей на функции), циклически перебирает массив и вызывает их всех (еще хуже!)

Это единственные варианты, которые я мог придумать. Если вы не можете создать цепочку методов, обратитесь к компоновщику или просто вызовите их все на их собственной линии. Или используйте один из трех вариантов выше (но действительно ставите под сомнение обоснованность ваших требований, если вы находитесь на этом шаге).

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

Это называется цепочкой методов, и самый простой способ получить этот эффект - вернуть текущий экземпляр объекта из каждого метода ...

class MyCoolChainingObject{

    public MyCoolChainingObject doSomething(){
        //TODO: Stuff
        return this;
    }

    public MyCoolChainingObject doSomethingElse(){
        //TODO: Stuff
        return this;
    }  
}

....

new MyCoolChainingObject().doSomething().doSomethingElse();
...