LINUX.ORG.RU

Инициализация классов с различными параметрами

 


0

1

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

Всё круто, но в интерфейсе нельзя определять статические методы, а в абстрактном классе нужно реализовывать статический метод. Я в корне неправ в архитектуре? Или реализовать метод-заглушку в абстрактном классе, возвращающий null, а в самих классах этот метод перегружать? Второй вариант не очень всё же, хотелось бы завести всё, что работает с данным типом классов в один интерфейс. Спасибо!

Используй у классов конструктор MyClass(Map<String, Object> context). Если я тебя правильно понял.

aidan ★★★★
()
Ответ на: комментарий от aidan

Да, всё так, но мне этот context надо сначала выдрать из класса, так как для разных классов они разные будут

OldWiseCat ★★
() автор топика
Ответ на: комментарий от OldWiseCat
public static Map<String, Object> getContext() {
Map<String, Object> map = new Map();
map.add("foo", null);
map.add("bar", null);
return map;
}

MyClass(Map<String, Object> context) {}

Вот что-то такое я пытаюсь сделать и засунуть в интерфейс

OldWiseCat ★★
() автор топика

Бедная убогая жабка)

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

stevejobs ★★★★☆
()
Ответ на: комментарий от OldWiseCat

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

aidan ★★★★
()
Ответ на: комментарий от aidan

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

OldWiseCat ★★
() автор топика

Как понимаю, нужно получить объект-словарь, и, чтобы не захламлять код, его нужно привязать к интерфейсу?

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

public interface Interface {
    static class I {public static String getContext() {return "context";}}
}

Теперь его можно вызвать вот так:

Interface.I.getContext();

Вот пример на три файла, BenderInterface.java, Verter.java и Main.java. Мапу-контекст получаем при помощи вызова BenderInterface.Default.getContext()

BenderInterface.java:

import java.util.HashMap;
import java.util.Map;

public interface BenderInterface {
    String killAllHumans();
    class Default {
        static Map<String, Object> getContext() {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("foo", "turama"); // default values for all classes
            return map;
        }
    }
}

Verter.java:

import java.util.Map;

public class Verter implements BenderInterface{
    private String weapon;

    public Verter(Map<String, Object> context) {
        weapon = (String)context.get("weapon");
    }

    @Override
    public String killAllHumans() {
        String s = "blaster".equals(weapon) ? "pirates are killed": "make clean, not war";
        System.out.println(s);
        return s;
    }
}

Main.java:

import java.util.Map;

public class Main {
    public static void main(String[] args) {
        Map<String, Object> ctx = BenderInterface.Default.getContext();
        ctx.put("weapon", "blaster");
        BenderInterface robot1 = new Verter(ctx);

        Map<String, Object> ctx2 = BenderInterface.Default.getContext();
        ctx2.put("weapon", "mop");
        BenderInterface robot2 = new Verter(ctx2);

        robot1.killAllHumans();
        robot2.killAllHumans();
    }
}
anonymous
()
Ответ на: комментарий от stevejobs

Да, фигня-война вышла, совсем задачу не понял. По ней ничего минималистичней, чем абстрактный класс, не придумать.

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

anonymous
()

Ты изобретаешь шаблон «Абстрактная фабрика»?

kovrik ★★★★★
()

Тут определённо нужен Spring!

CARS ★★★★
()
Ответ на: комментарий от maxcom

А Java Beans и Apache BeanUtils это совершенно разные вещи или одно из другого выросло? Это то, что нужно, спасибо!

OldWiseCat ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.