Вопрос дизайна фабричного класса в Java - PullRequest
0 голосов
/ 02 марта 2011

У меня есть два класса

public class PrepaidPackage {

    private String name;
    private String serviceClassID;
    private boolean isTranferable;

    public boolean isTranferable() {
        return isTranferable;
    }
    public void setTranferable(boolean isTranferable) {
        this.isTranferable = isTranferable;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getServiceClassID() {
        return serviceClassID;
    }
    public void setServiceClassID(String serviceClassID) {
        this.serviceClassID = serviceClassID;
    }
}

другой класс -

public class PostpaidPackage {
    private String name;
    private boolean isTranferable;
    public boolean isTranferable() {
        return isTranferable;
    }
    public void setTranferable(boolean isTranferable) {
        this.isTranferable = isTranferable;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

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

Теперь фабрика вернет имя класса Package.Могу ли я вызывать методы, которых нет в другом классе.

Обновления

Пожалуйста, предложите, если я разобью свой пакет на два класса, например

public abstract class MyPackage {
    public abstract PackageSpec getSpec();
    public abstract PackagePrepaidDetails getDetail();
}

Теперь общие атрибуты будут в PackageSpec и предоплаченные вещи в packageDetails.

Это своего рода абстрактный шаблон фабрики.

public class PrepaidPackage extends MyPackage{
    PackageSpec spec;
    public Spec getSpec() {
      spec = new PackageSpec();
      spec.setTranferable(true)
      spec.setName("abc");
      return spec;
    }
    public PackagePrepaidDetails getDetails() {
      details = new PackagePrepaidDetails ();
      details.setServiceClassID(123)
      return details;
    }
}

public class PostpaidPackage extends MyPackage{
    PackageSpec spec;
    public Spec getSpec() {
        spec = new PackageSpec();
        spec.setTranferable(true)
        spec.setName("abc");
        return spec;
    }
}

Ответы [ 4 ]

0 голосов
/ 02 марта 2011

Два возможных варианта дизайна вы можете сделать:

  1. Продлить пакет предоплаты постоплатный пакет и ваш завод затем возвращает объекты типа постоплатный пакет, код которого называет фабрику то ответственный за проверку типа.

  2. Есть интерфейс пакета, который определяет все методы и имеют постоплатный пакет определить методы бросить UnsupportedOperationException (ala то, как коллекции определяют некоторые операции как необязательные.) или возврат какое-то значение дозорного (т. е. ноль)

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

0 голосов
/ 02 марта 2011

Ну, для абстрактного суперкласса вы должны сгруппировать все общее для обоих:

public abstract class MyPackage { // not sure you can call a class just "Package"
    private String name;
    private boolean isTranferable;

    public boolean isTranferable() {
        return isTranferable;
    }
    public void setTranferable(boolean isTranferable) {
        this.isTranferable = isTranferable;
    }
    public String getName() {
       return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

, затем оба наследуют его (первый добавляет serviceClassID, а второй ничего)

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

0 голосов
/ 02 марта 2011

Я рекомендую вам иметь интерфейс, если у вас его еще нет. Вам это не обязательно, но это хорошая практика, если они очень похожи:

public interface Package {
    public boolean isTranferable();
    public void setTranferable(boolean isTranferable);
    public String getName();
    public void setName(String name);
}

Тогда в вашем телефонном коде у вас есть пакет от вашего завода и:

Package p = myFactory.nextPackage();    // or something
if (p instanceof PrepaidPackage) {
    PrepaidPackage prepaid = (PrefpaidPackage)p;
    // and do the thing you want
} else if (p instanceof PostpaidPackage) {
    PostpaidPackage postpaid = (PostpaidPackage)p;
    // amd do the other things
}

Вещь, которую вам рекомендуется использовать, это оператор instanceof и приведение типа .

0 голосов
/ 02 марта 2011

Быстрое решение, не идеальное, - это иметь интерфейс, который представляет все методы в классе Prepaid и не применяет их в Postpaid. Это решит проблему в краткосрочной перспективе. Я хотел бы предложить вам пересмотреть классы и способы их использования, чтобы избежать нереализованных методов в коде.

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