У меня есть три класса: AbstractContext, ContextA и ContextB, которые я хочу обобщить с точки зрения создания, но я хочу получить доступ к конкретным методам каждого из них в разных контекстах.Получить специализированный класс от Abstract Factory
AbstractContext:
public abstract class AbstractContext {
public abstract void print();
}
ContextA:
public class ContextA extends AbstractContext {
@Override
public void print() {
System.out.println("In context A");
}
public void doSomeA(){
System.out.println("Do some A");
}
}
ContextB:
public class ContextB extends AbstractContext {
@Override
public void print() {
}
public void doSomeB(){
int a=1;
System.out.println(a);
}
}
Я реализовал абстрактную модель фабрики, так что я мог бы обобщать создание этих классов:
AbstractFactory:
public abstract class AbstractFactory {
public abstract AbstractContext createContext();
}
FactoryA:
public class FactoryA extends AbstractFactory {
@Override
public AbstractContext createContext() {
AbstractContext newClass = new ContextA();
return newClass;
}
}
FactoryB
public class FactoryB extends AbstractFactory {
@Override
public AbstractContext createContext() {
AbstractContext newClass = new ContextB();
return newClass;
}
}
FactoryMaker
public class FactoryMaker {
private static AbstractFactory factory = null;
public static AbstractFactory getFactory(String condition) {
if (condition == "A") {
factory = new FactoryA();
} else {
factory = new FactoryB();
}
return factory;
}
}
Проблема здесь в том, после того, как экземпляр будет создан, так как все заводы в отставке urn базового типа я не могу получить доступ к каким-либо конкретным методам каждого подкласса.
public class Main {
public static void main(String[] args) {
AbstractContext contextA = FactoryMaker.getFactory("A").createContext();
contextA.print(); //Works fine
contextA.doSomeA(); //Won't compile
AbstractContext contextB = FactoryMaker.getFactory("").createContext();
contextB.print(); //Works fine
contextB.doSomeB(); //Won't Compile
}
}
На первые попытки, я пытался создать методы с той же сигнатурой, принимающей различные подтипами класса, но потом я получил ошибку компиляции, так как базовый тип не соответствует конкретным типам методов ожидать:
public static void process(ContextA context){
context.doSomeA();
}
public static void process(ContextB context){
context.doSomeB();
}
Есть ли способ достичь того, что я пытаюсь сделать?
Чтобы предоставить вам дополнительный контекст, я создаю общую библиотеку Java (API), которая будет использоваться другими разработчиками, то, что я пытаюсь сделать, - найти способ, которым разработчики имеют контекст, который они хотят предоставить в стандартный путь от моего API. Я хочу, чтобы они запрашивали контекст, и работа с этой точки заполняет свойства, которые каждый контекст имеет, тогда api будет обрабатывать определенные части каждого контекста.
EDIT: Похоже, я должен дать вам дополнительную информацию.
Представьте, что у меня есть два веб-приложения, оба веб-приложения получают доступ к тем же бизнес-классам услуг, но могут иметь разные бизнес-правила, потому что это две разные компании. Каждая компания имеет варианты одного и того же продукта.
То, что я пытаюсь достичь, - это сделать API, который внутренне сделает тяжелый подъем и общий код для разработчиков.
Что нужно сделать разработчикам: api, например, продукт и компания, а api возвращает правильный контекст и инициализирует контекст в соответствии с бизнес-правилами.
Я хочу, чтобы они «почти» строили только gui, чтобы заполнить каждый контекст, который я возвращаю. Конечно, им нужно будет знать контекст, с которым они работают, чтобы сделать привязки между графическим интерфейсом и контекстом, который я возвращаю, но в то же время их графический интерфейс может иметь общие части пользовательского интерфейса.
Обновление вещей на моем конце тоже, на данный момент, что я сделал, это создать ContextHolder, который возвращает контекст, который хочет разработчик, но он выглядит не очень хорошо, потому что компания может расширить линейку продуктов или вариации каждого продукта.
Я привел в качестве примера различные реализации abstractContext с различными методами, потому что в каждом контексте мне нужно будет получить доступ к определенным свойствам (в конце будет одно и то же, свойства - методы, возвращающие данные). В конце концов, контексты будут только старыми различными наборами данных, общие данные будут оставаться в классе abstractContext.
Я стараюсь изо всех сил объяснить себя, это недостаточно ясно, пожалуйста, дайте мне знать.
Вы написали, что «разработчикам не нужно думать, какой контекст они создают». Но если каждый контекст имеет собственные конкретные методы, разработчики должны думать о каком-то контексте –
Единственный способ, который я вижу, - это Generics: Abstract Factory будет иметь специализированный контекст как общий параметр. Проблема с этим заключается в том, что для Factorymaker нужен специальный класс для создания специального Factory ... – Mikey
Alexey, я хочу, чтобы мой API предоставлял общий способ получить контекст, не создавая для каждого пользователя моего API фабрик на их сторонах, чтобы получить контекст, который они хотят. Вы правы, они должны думать о каком-то контексте, но я хочу, чтобы они имели это стандартным образом из моего api. То, что я пытаюсь достичь, может быть невозможным :) –