Java 音乐厅OOP设计

Java Concert Hall OOP design

我想Bookingclass订演唱会门票。 A ConcertHall class 有2个不同的座位,分别是VIP和Regular。我选择 Seat[][] 作为我的数据结构,其中 Seat class 包含 seat_number:Stringpreference:String。现在,贵宾席和普通席的容量有所不同。假设 VIP 的容量为 10x5 个座位​​,而 Regular 的容量为 50x100 个座位。 VIP和Regular对应的座位也有Left、Center、Right偏好。

我当前设计的问题是我有太多冗余代码。假设用户想要预订音乐会门票,he/she 将调用方法:book("VIP", "Mary", "Center")。这是我的设计和书籍方法的样子:

class Booking
{
    private ConcertHall A;

    public Booking(String name)
    {
        A = new ConcertHall(name);
    }

    public boolean book(String serviceClass, String name, String preference)
    {
        Seat seat = find(serviceClass, preference)

        if(seat != null) 
        {
            assignSeat(seat, name);
            return true;
        }

        return false;
    }
}

class ConcertHall
{
    private Seat[][] VIP;
    private Seat[][] Regular;

    public Seat findSeat(String serviceClass, String preference)
    {
        if(serviceClass.equals("VIP"))
        {
            // query VIP array
        }
        else if(serviceClass.equals("Regular"))
        {
            // query Regular array
        }
    }

    public boolean assignSeat(Seat seat, String name)
    {
        if(serviceClass.equals("VIP"))
        {
            // query VIP array
        }
        else if(serviceClass.equals("Regular"))
        {
            // query Regular array
        }
    }
}

这里已经有一个问题,即对于 ConcertHall 中的几乎每个方法,我都必须对 VIP class 和常规 class 进行 2 次相同的检查。现在我卡住了。由于 2 个相同的检查,我的代码看起来又长又笨。

===================================更新========= ========================== 我忘了说,还有一个额外的要求。我必须跟踪座位的位置。比方说一群人要订演唱会门票,我们必须在同一排找到可用的座位。所以,我认为 HashMap 在这里不起作用。

您的 ConcertHall 中可以有一张地图。在您的检查中,只需执行地图上的获取、查询和分配。所以你可以这样做

class ConcertHall{
    private Map<String, Seat[][]> seatMap;

    public Seat findSeat(String serviceClass, String preference){   
        Seat[][] seats = seatMap.get(serviceClass);
        //query on seats    
    }

要使用它,您需要在地图中适当地放置座位。此外,您可以将枚举用于 VIPRegular

等值

将相同的数组检查代码分解成它自己的方法,然后将正确的查找数组传递给它。像

public Seat findSeat(String serviceClass, String preference)
{
    if(serviceClass.equals("VIP"))
    {
        return findSeatIn(VIP, preference);
    }
    else if(serviceClass.equals("Regular"))
    {
        return findSeatIn(Regular, preference);
    }
}

public Seat findSeatIn(Seat[][] seatArray, String preference)
{
     // query seatArray for preference
}

然后用 assignSeat()assignSeatIn() 重复此操作。

此外,findSeat() 理想情况下应该 findSeats() 返回符合用户偏好的座位列表。然后用户应该能够选择一个 s/he 最喜欢的,然后应该由 assignSeat() 分配。只是一个想法。

在我看来,还有空间(如果我可以这么说的话)额外 class 代表大厅的各个区域;说:

class Zone {
    Seat[][] seats;

    public Zone(int rows, int columns) {
        seats = new Seat[rows][columns];
    }

    public Seat findSeat(String preference) {
        ...
    }

    public boolean assignSeat(Seat seat, String name) {
        ...
    }
}

如果不同的服务 class 需要不同的行为,则可以对 class 进行子class编辑。

音乐厅 class 可以更简单:

class ConcertHall{
    private Map<String, Zone> zoneMap = new HashMap<String, Zone>();
    {
        zoneMap.put("VIP", new Zone(5,10));
        zoneMap.put("Regular", new Zone(50,100));
    }

    public Seat findSeat(String serviceClass, String preference) {
        return zoneMap.get(serviceClass).findSeat(preference);
    }

    ...
}

您需要良好的初始设计才能使用 oop。这是您可能要考虑的替代实现:

class Booking {

    public Booking(String personName, Seat seat) {
        ...
    }

    // getter and setters...blah blah
}

class ConcertHall {

    // Making it protected allows for easy subclassing
    protected List<Booking> vipSeating;
    protected List<Booking> regularSeating;    

    public ConcertHall(String name, int capVip, int capReg) {
        vip = new ArrayList<>();
        regular = new ArrayList<>();

        // initialise capacity, etc
    }

    public void addVipBooking(Booking b) throws ArrayIndexOutOfBoundsException {

        // If there is room, add the person, else throw an exception
    }

    public void addRegularBooking(Booking b) throws ArrayIndexOutOfBoundsException {

        // If there is room, add the person, else throw an exception
    }

    public boolean vipIsFull() {
        // is the vip section full??
    }

    public boolean regularIsFull() {
        // is the regular section full??
    }
}