Является ли необходимость передавать Context большинству классов как признак плохого дизайна? - PullRequest
6 голосов
/ 20 сентября 2011

Android сконструирован таким образом, что для того, чтобы метод мог прочитать ресурс, он должен иметь доступ к Context .

Поскольку большинство классов в моем приложении полагаются на гибкость строковых ресурсов (например, изменение языка без необходимости изменения кода и т. Д.), Мое простое решение состояло в том, чтобы передать Context в их конструкторе, чтобы обеспечить доступ к ресурсам для каждого из них. такой класс.

Мне не имеет смысла передавать только строку в конструкторе, потому что классу нужна гибкость доступа к переменному количеству строк.

Итак, чтобы упростить задачу, я передаю только Context , и всякий раз, когда требуется строковый ресурс, я просто использую Context.getString () .

Это признак плохого дизайна?

Есть ли лучший способ сделать это?

Ответы [ 4 ]

5 голосов
/ 20 сентября 2011

Это шаблон локатора службы - вы передаете локатор службы (часто называемый «контекст») и получаете от него необходимые зависимости. Это не анти-паттерн и не такой уж плохой дизайн, но обычно внедрение зависимостей считается лучшим.

То, что вы делаете - передаете локатор сервиса еще дальше вниз по графу объектов. Рекомендуется дать каждому классу только те зависимости, в которых он нуждается. Таким образом, вместо передачи Context в конструктор, вы передаете все необходимые строки. Таким образом, вы не будете нарушать Закон Деметры

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

Это один из редких случаев, когда глобально доступный класс singleton может быть лучше, чем передавать Context каждому отдельному классу.

Я хотел бы рассмотреть возможность создания синглтона для локализациизатем используйте Context внутри (если вам не нужны другие аспекты Context повсюду).

Конечно, это вопрос вкуса и предпочтений.YMMV

1 голос
/ 01 января 2019

Я не знаю, является ли это плохой практикой, использовать это таким образом, но я провел сравнение времени, которое потребовало загрузки 200 легких объектов в Array-list с одним из Конструкторов, принимающих Context в качестве параметра, и другим получение необходимого контекста с помощью статического метода, как предложил @Eric Farr. Конечным результатом было то, что доступ к контексту через статический метод вместо передачи в конструктор всегда был на 5-25% быстрее ..

@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
    initBlocks(map); // takes context through static method
    blocks.clear();
    initBlocks(getContext(), map); // pass context down to every block object
    mainthread = new GameThread(getHolder(), this);
    mainthread.setRunning(true);
    mainthread.start();
}


I/art: Background sticky concurrent mark sweep GC freed 1070(51KB) AllocSpace 
objects, 44(3MB) LOS objects, 27% free, 8MB/11MB, paused 27.450ms total 132.688ms
I/art: Background partial concurrent mark sweep GC freed 1638(66KB) AllocSpace 
objects, 36(3MB) LOS objects, 29% free, 9MB/13MB, paused 13.982ms total 184.900ms
I/art: Background sticky concurrent mark sweep GC freed 916(44KB) AllocSpace objects, 
37(3MB) LOS objects, 16% free, 11MB/13MB, paused 17.710ms total 127.963ms
**I/System.out: TIME IT TOOK TO PROCESS >> 2254155160**
I/art: Background partial concurrent mark sweep GC freed 1780(77KB) AllocSpace 
objects, 208(8MB) LOS objects, 38% free, 6MB/10MB, paused 22.850ms total 193.625ms
I/art: WaitForGcToComplete blocked for 5.262ms for cause Background
I/art: Background sticky concurrent mark sweep GC freed 959(46KB) AllocSpace objects, 
39(3MB) LOS objects, 24% free, 7MB/10MB, paused 15.160ms total 101.055ms
I/art: Background partial concurrent mark sweep GC freed 1873(71KB) AllocSpace 
objects, 32(2MB) LOS objects, 32% free, 8MB/12MB, paused 17.253ms total 154.302ms
I/art: Background sticky concurrent mark sweep GC freed 888(42KB) AllocSpace objects, 
36(3MB) LOS objects, 17% free, 10MB/12MB, paused 42.191ms total 179.613ms
I/art: Background partial concurrent mark sweep GC freed 1243(50KB) AllocSpace 
objects, 30(2MB) LOS objects, 27% free, 10MB/14MB, paused 29.423ms total 283.968ms
**I/System.out: TIME IT TOOK TO PROCESS >> 3079467060**
I/art: Background sticky concurrent mark sweep GC freed 343(16KB) AllocSpace objects, 
14(1232KB) LOS objects, 0% free, 21MB/21MB, paused 20.481ms total 162.576ms
I/art: Background partial concurrent mark sweep GC freed 396(13KB) AllocSpace 
objects, 4(280KB) LOS objects, 15% free, 21MB/25MB, paused 21.971ms total 243.764ms
I/art: Background sticky concurrent mark sweep GC freed 471(166KB) AllocSpace 
objects, 0(0B) LOS objects, 0% free, 37MB/37MB, paused 26.350ms total 133.655ms
I/art: Background partial concurrent mark sweep GC freed 356(10KB) AllocSpace 
objects, 1(10MB) LOS objects, 12% free, 27MB/31MB, paused 41.909ms total 299.517ms

Я не знаю о вас, но я увеличу производительность (у).

1 голос
/ 20 сентября 2011

Регулярная отправка контекстов в качестве параметров и их запоминание опасны, читайте здесь: http://developer.android.com/resources/articles/avoiding-memory-leaks.html

Намного лучше подклассифицировать Application и создать синглтон с ним (объект приложения тоже является контекстом).Такое растворение не имеет существенных недостатков.

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