2013-12-16 6 views
9

У меня есть приложение, готовое и запущенное в магазине Google Play, теперь я реализую фрагменты.Лучший способ избежать дублирования кода при использовании фрагментов

Итак, у меня уже есть класс A, который расширяет B с помощью некоторых методов, теперь у меня есть класс, который C расширяет FragmentActivity, поэтому теперь мне нужно использовать те же методы, что и в классе A, но здесь, поскольку я расширяю FragmentActivity, я не могу сделать использование класса B, поэтому здесь существуют повторяющиеся методы, которые аналогичны классу A, но мне нужно повторно использовать методы.

Это ниже пример показывает мою ситуацию:

Например:

Текущая реализация

class A extends B{ 

one(); 
two(); 

} 

После интегрирующих фрагментов,

Например:

class C extends FragmentActivity{ 

one();// same methods as in class A 
two();// same methods as in class A 

} 

1) Каков наилучший способ повторного использования методов в этом случае и как?

2) У меня есть подход, как создание класса, и статические методы и методы повторного использования в классах A и C, но мой подход хорош, и я могу сделать методы статичными и это хороший подход?

3) Еще один подход, который я подумал о «Шаблон стратегии».

Eg: 
class A extends ApiClass { 
    private ClassContainingDupMethod strategy; 
} 

class N extends AnotherApiClass { 
    private ClassContainingDupMethod strategy; 

    public methodCallingDupMethod(){ 
     strategy.dupMethod(); 
    } 
} 

class ClassContainingDupMethod{ 
    public dupMethod(){;} 
} 

Является "Стратегия Pattern". хороший подход? поскольку мне нужно создать объект общего класса в обоих классах.

Любые предложения по этому вопросу будут оценены.

+1

Сделайте свой вопрос более ясным, это поможет нам лучше понять его. –

+0

@ VipulPurohit см. Мое редактирование – Goofy

+0

, вы должны дать больше информации о роли/цели методов один и два. Их можно извлечь как служебные методы, сделать их статическими или использовать «Композицию», где вы включаете ссылку на класс (который имеет эти методы) во всех ваших классах, где вы хотите использовать эти методы. – hovanessyan

ответ

13

Его более простой, чем вы описываете. Все, что вам нужно сделать, это создать D так:

public class D{ 
    one(); 
    two(); 
} 

Изменить класс A для использования класса D.

public Class A{ 
     public D dLogic; 
    } 

То же с классом С.

public Class C extends FragmentActivity{ 
     public D dLogic; 
    } 

Это некоторые вещи очень основной в объектно-ориентированном программировании он вызывает composition.

3

Я подозреваю, что у вас есть некоторые утилиты, просто поместите их в класс Utils, сделайте их статичными и вызовите их туда, где вы хотите. У меня много полезных классов в моем приложении, например WifiUtils, LogUtils, NumberUtils и так далее.

3

Если вы хотите, чтобы один и тот же API, вы можете попробовать добавить интерфейс для обоих A и C классов, сохраняя при этом экземпляр A как поле C. C будет действовать как класс обертки A.

Класс A:

class A extends B implements CommonApi { 
    public void one() { 
     ... 
    } 

    public boolean two() { 
     ... 
    } 
} 

Класс C:

class C extends FragmentActivity implements CommonApi { 
    private A a; 

    public void one() { 
     a.one(); 
    } 

    public boolean two() { 
     return a.two(); 
    } 
} 
1

Вы должны начать с того, что сказал Babibu - простой состав.

Когда вы овладеете этим, есть и другая техника. Например, инъекция зависимостей выглядит как нечто, что можно использовать здесь. Простой случай будет похож на это. Определите интерфейс B вместо класса B. Пропустите интерфейс B как параметр во время инициализации C, используйте его как внутреннюю переменную b и вызовите b.one() и b.two(). Вам нужно будет создать объект A, который реализует B вне области C и передает его во время инициализации активности C. Преимущество: C не нужно знать, как создать A, вы можете изменить его позже на AA или AAA и никогда не прикасаться к своей активности снова, пока AA и AAA реализуют B. Вам не нужно повторять C.

1

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

0

Стратегический шаблон или «обертка» - лучший выбор. И я думаю, что решение Хуана Санчеса лучше, чем у Бабибу. Как и в коде Babibu, класс A не должен зависеть от D. Быть зависимым от интерфейса лучше. В вашем коде, если класс А содержит некоторые атрибуты или некоторые действия, которые не нужны классу C, вы можете реорганизовать свой код, как показано ниже. В противном случае достаточно решения Хуана. Я нарисовал UML изображение для этой ситуации, но у меня нет достаточно репутации, чтобы разместить его :-( кода выглядит так:

interface IAction 
{ 
    public void actionA(); 
} 

class A extends B implements IAction 
{ 
    private IAction action; 
    public void actionA() { 
     action.actionA(); 
    } 
} 

class C extends FragmentActivity implements IAction 
{ 
    private IAction action; 
    public void actionA() { 
     action.actionA(); 
    } 
} 

class D implements IAction 
{ 
    public void actionA() { 
    // put implementation here 
    } 
} 
0

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

При чтении старых шаблонов дизайна от Gamma et al., Имейте в виду, что они были написаны для мира, где C++ и Pascal были доминирующими языками OO. Java все еще была в зачаточном состоянии и ввела новизна (интерфейсы), которые ни один из этих языков не имел. Таким образом, вы должны мысленно заменить множество применений расширений с помощью инструментов, и в итоге вы получите лучший код.

В принципе, поддержание когерентности высоко, а связь низкая - хорошая идея в объектно-ориентированном дизайне. Наследование классов может легко привести к высокосвязным классам с низкой связностью (много не связанных функций в одном классе). Причина в том, что базовый класс заканчивается тем, что функциональность не нужна всем подклассам или кодам, которые имеют отношение только к некоторым. Кроме того, по мере развития вашего дизайна вы заканчиваете множеством классов, которые наследуют друг от друга и очень тесно связаны. Я лично ненавижу иметь дело с кодом с несколькими уровнями наследования. Трудно читать, и семантика наследования делает тестирование более болезненным. Я никогда не использую расширения, отличные от интерфейсов, и я занимаюсь Java с середины девяностых.

@ Предложение Бабибу по использованию композиции и делегирования является гораздо лучшей альтернативой по этой причине. Это приводит к более когерентным классам, которые гораздо менее тесно связаны. Легче поддерживать, легче перекомпоновать, легче тестировать и т. Д.

Смежные вопросы