Здравствуйте, stenkil, Вы писали:
S>...
S>Помогите примером, а то в общем по отдельности все понятно, а вместе
1. Не надо (даже в тестовых примерах) использовать некомпилируемый код (нельзя использовать ключевые слова в качестве названий классов/полей/методов etc — метод do(); switch работает только с is-a int и enum);
2. Пример:
package com;
import javax.naming.NamingException;
import java.util.Map;
import java.util.HashMap;
/**
* @author Denis Zhdanov
* @since 27.04.2007
*/
public class AAA {
public static void main(String[] args) throws NamingException, ClassNotFoundException {
CommandFactory factory = new CommandFactory();
Service<Integer, String> service1 = factory.getService(Command.COMMAND_1);
Service<String, Boolean> service2 = factory.getService(Command.COMMAND_2);
String s = service1.doWork(1);
Boolean b = service2.doWork("asdf");
}
}
interface Service<K, V> {
V doWork(K param);
}
class Command<K, V> {
public static final Command<Integer, String> COMMAND_1 = new Command<Integer, String>();
public static final Command<String, Boolean> COMMAND_2 = new Command<String, Boolean>();
private Command() {
}
}
class CommandFactory {
private final Map<Command, Service> services = new HashMap<Command, Service>();
@SuppressWarnings("unchecked")
public <K, V> Service<K, V> getService(Command<K, V> command) throws IllegalStateException {
if (!services.containsKey(command)) {
throw new IllegalStateException("No service defined for command '" + command + "'. "
+ "Available mappings: " + services);
}
return services.get(command);
}
{
storeMapping(Command.COMMAND_1, new Service1());
// storeMapping(Command.COMMAND_1, new Service2()); // (1)
// services.put(Command.COMMAND_1, new Service2()); // (2)
storeMapping(Command.COMMAND_2, new Service2());
}
/**
* Stores mapping for given command and service. Is introuced in order to process compile-time
* type safety checking.
*
* @param command command to store
* @param service service to store
*/
private <K, V> void storeMapping(Command<K, V> command, Service<K, V> service) {
services.put(command, service);
}
}
class Service1 implements Service<Integer, String> {
public String doWork(Integer param) {
return "aasd";
}
}
class Service2 implements Service<String, Boolean> {
public Boolean doWork(String param) {
return false;
}
}
Здесь есть два тонких момента:
1. Поскольку сейчас стандартная библиотека не предлагает type-safe map, у которой entry может содержать ссылки разных типов, мы помечаем CommandFactory.getService() @SuppressWarnings("unchecked"). Т.е. мы знаем, что у нас в Map лежат корректные связки типов и просим компилятор не беспокоиться;
2. Для того, чтобы обеспечить поддержку того, что в Map лежат пары ключ-значения правильных типов (т.е. для каждой пары типу ключа соответствует правильный тип значения), мы кладем не напрямую через put(), а через storeMapping(). Здесь можно откомментировать (1) и (2) и увидеть, что при (1) получим ошибку, а при (2) нет;
Хотел сделать
interface Comandable<R, P>{
R do(P param);}
public CommandFactory{
.....
public Commandable getCommand(CommandName name){
switch(name){
case: command1: return new Command1();
...}
}
public Command1 implements Commandable<Integer, String>{
public Integer do(String str){
return Integer.valueOf(str.length());}
}
.....
Commandable command= CommandFactory.getInstance().getCommand(CommandName.command1);
Integer result= command.do("блаблабла"); // и конечно получаю Type safety: The method .... should be parameterized
Помогите примером, а то в общем по отдельности все понятно, а вместе
Здравствуйте, bolshik, Вы писали:
B>1 Каюсь, опустил объявление в CommandFactory
public static enum CommandName = {commad1, command2,...};
B>2
Как я понял решается только через дополнительную ссылку ?
Здравствуйте, stenkil, Вы писали:
S>Здравствуйте, bolshik, Вы писали:
B>>1 Каюсь, опустил объявление в CommandFactory
S>S>public static enum CommandName = {commad1, command2,...};
S>
B>>2
S>Как я понял решается только через дополнительную ссылку ?
Ну тебе же надо как-то дать компилятору информацию, необходимую для выведения нужных типов и проведения проверки.
Btw, через enum не решится, потому что enum не поддерживают типизацию на уровне класса.