在Java中是否可以有一种方法,根据条件返回不同的类对象?

huangapple go评论63阅读模式
英文:

Is it possible to have a method that can return different class objects in Java depending on the condition?

问题

public class ArriveEvent {
    private final List<Server> list;
    private final Customer cust;

    ArriveEvent(Customer ppl, List<Server> listing){
        this.list = listing;
        this.cust = ppl;
    }

    public interface EventOutcome {
        String toString();
    }

    public class ServedBy implements EventOutcome {
        private final Server server;

        ServedBy(Server server) {
            this.server = server;
        }

        @Override
        public String toString() {
            return String.format("%.3f %d served by %d", cust.giveArrival(), cust.giveID(), server.getServerID());
        }
    }

    public class Wait implements EventOutcome {
        private final Server server;

        Wait(Server server) {
            this.server = server;
        }

        @Override
        public String toString() {
            return String.format("%.3f %d waits to be served by %d", cust.giveArrival(), cust.giveID(), server.getServerID());
        }
    }

    public class DoneServing implements EventOutcome {
        private final Server server;

        DoneServing(Server server) {
            this.server = server;
        }

        @Override
        public String toString() {
            return String.format("%.3f %d done serving by %d", cust.giveArrival(), cust.giveID(), server.getServerID());
        }
    }

    public class Leave implements EventOutcome {
        Leave() {}

        @Override
        public String toString() {
            return String.format("%.3f %d leaves", cust.giveArrival(), cust.giveID());
        }
    }

    public EventOutcome execute() {
        for (Server server : list) {
            if (server.isAvailable() && !server.hasWaitingCustomer()) {
                server.serveCustomer(cust);
                return new ServedBy(server);
            } else if (!server.isAvailable() && !server.hasWaitingCustomer()) {
                server.addWaitingCustomer(cust);
                return new Wait(server);
            } else if (!server.isAvailable() && server.hasWaitingCustomer()) {
                return new Leave();
            }
        }
        return null;
    }

    public String toString() {
        return String.format("%.3f %d arrives", cust.giveArrival(), cust.giveID());
    }
}

Please note that the provided code assumes that you have appropriately defined the methods and attributes in the Server and Customer classes. The execute() method in the ArriveEvent class iterates through the list of servers and implements the logic to determine the appropriate outcome based on server availability and waiting customers. It returns an instance of the respective inner class based on the outcome.

英文:

How can I make a method to return different immutable class objects depending on some conditions?

If it is not possible, is there an alternative to tackle this question?

public class ArriveEvent {
    private final List&lt;Server&gt; list;
    private final Customer cust;

    ArriveEvent(Customer ppl, List&lt;Server&gt; listing){
        this.list = listing;
        this.cust = ppl;
    }

    PutSomethingHere? execute(){
    }

    public String toString() {
        return String.format(&quot;%.3f %d arrives&quot;, cust.giveArrival(), cust.giveID());
    }
}

The main question is for execute() to return different statements depending on the condition of an immutable class Server, in the list, which have different attributes, such as availability or if there is another customer in line.

private final boolean avail;
private final boolean anyoneWaitingInLine;

This is the requirement:

jshell&gt; new ArriveEvent(new Customer(1, 0.5), Arrays.asList(new Server(1, false, false, 0), new Server(2, true, false, 0))).execute() // Two servers: (1) busy; (2) free
$.. ==&gt; 0.500 1 served by 2
jshell&gt; new ArriveEvent(new Customer(1, 0.5), Arrays.asList(new Server(1, false, false, 0), new Server(2, true, false, 0))).execute().execute()
$.. ==&gt; 1.500 1 done serving by 2
jshell&gt; new ArriveEvent(new Customer(1, 0.5), Arrays.asList(new Server(1, false, true, 5.0), new Server(2, false, false, 10.0))).execute() // Both servers busy, (1) has waiting customers
$.. ==&gt; 0.500 1 waits to be served by 2
jshell&gt; new ArriveEvent(new Customer(1, 0.5), Arrays.asList(new Server(1, false, true, 5.0), new Server(2, false, false, 10.0))).execute().execute()
$.. ==&gt; 10.000 1 served by 2
jshell&gt; new ArriveEvent(new Customer(1, 0.5), Arrays.asList(new Server(1, false, true, 5.0), new Server(2, false, false, 10.0))).execute().execute().execute()
$.. ==&gt; 11.000 1 done serving by 2
jshell&gt; new ArriveEvent(new Customer(1, 0.5), Arrays.asList(new Server(1, false, true, 5.0), new Server(2, false, true, 10.0))).execute() // Both busy with waiting customer
$.. ==&gt; 0.500 1 leaves

My original idea was to create multiple classes servedby, wait, doneserving, leave that extends the ArrivalEvent class as I would need different toStrings() depending on the situation of the servers and customers, then when I run an execute(), it would return different classes that extended ArrivalEvent class depending on the condition of the servers and customers and have another overriding execute() which returns a class among them.

答案1

得分: 1

你可以在这里使用重构

public <T> T execute() {
    Object obj = getObject(ArriveEvent, ArriveEvent.getClass()); // 根据条件传递元素
}

public static <T> T getObject(Object o, Class<T> type) {
    if (type.isInstance(o)) {
        return type.cast(o);
    } else {
        return null;
    }
}
英文:

You may use refactoring here

public &lt;T&gt; T execute(){
Object obj = getObject(ArriveEvent, ArriveEvent.getClass()) // Pass element as per condition
}
public static &lt;T&gt; T getObject(Object o, Class&lt;T&gt; type){
if(type.isInstance(o)){
return type.cast(o)
}
else{
return null;
}
}

答案2

得分: 1

class ServedBy extends ArrivalEvenet {
    //...
}

class Wait extends ArrivalEvenet {
    //...
}

class DoneServing extends ArrivalEvenet {
    //...
}

class Leave extends ArrivalEvenet {
    //...
}

class ArrivalEvenet {

}

public class ArriveEvent {

    private final List<Server> list;
    private final Customer cust;

    ArriveEvent(Customer ppl, List<Server> listing){
        this.list = listing;
        this.cust = ppl;
    }

    public String toString() {
        return String.format("%.3f %d arrives", cust.giveArrival(), cust.giveID());
    }

    ArrivalEvenet execute(ArrivalEvenet object) {
        if (/*your condition*/) {
            return new ServedBy(); //alternatively create your object
        } else if (/*your condition*/) {
            return new Wait(); //alternatively create your object
        } else if (/*your condition*/) {
            return new DoneServing(); //alternatively create your object
        } else if (/*your condition*/) {
            return new Leave(); //alternatively create your object
        } else {
            throw new IllegalArgumentException("Wrong type has been provided");
        }
    }
}

/*your condition*/ will look something like list.get(...)==...

英文:

>Yes, my original plan is to create "servedby", "wait", "doneserving", "leave" that extends the ArrivalEvent class and execute would return one of these subclasses depending on the condition of server inside the list, how would I do so?

First of all, few notes about your existing code:

  1. Always respect Java Naming Conventions, name your classes with PascalCase and methods - with camelCase. Example from your comment would be doneserving, which should be DoneServing;
  2. According to the same convention, try your best to have Noun as your class name;
  3. your .toString() uses giveArrival() and giveID(), which are not defined in your code, so your snippet would not compile;
  4. You don't provide the class definitions for Customer and Server.

Now, after considering all this, if we assume that you have all the necessary classes in your original code (named accordingly), your working code would look like this:

class ServedBy extends ArrivalEvenet {
    //...
}

class Wait extends ArrivalEvenet {
    //...
}

class DoneServing extends ArrivalEvenet {
    //...
}

class Leave extends ArrivalEvenet {
    //...
}

class ArrivalEvenet {

}

public class ArriveEvent {

    private final List&lt;Server&gt; list;
    private final Customer cust;

    ArriveEvent(Customer ppl, List&lt;Server&gt; listing){
        this.list = listing;
        this.cust = ppl;
    }

    public String toString() {
        return String.format(&quot;%.3f %d arrives&quot;, cust.giveArrival(), cust.giveID());
    }

    ArrivalEvenet execute(ArrivalEvenet object) {
        if (/*your condition*/) {
            return new ServedBy(); //alternatively create your object
        } else if (/*your condition*/) {
            return new Wait(); //alternatively create your object
        } else if (/*your condition*/) {
            return new DoneServing(); //alternatively create your object
        } else if (/*your condition*/) {
            return new Leave(); //alternatively create your object
        } else {
            throw new IllegalArgumentException(&quot;Wrong type has been provided&quot;);
        }
    }
}

/*your condition*/ will look something like list.get(...)==...

huangapple
  • 本文由 发表于 2020年9月22日 02:01:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/63997684.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定