面向对象设计/如何设置类结构

3

我对面向对象编程还比较新,我很好奇如何高层次地解决这个问题。

假设我有一个不同的日历列表,例如工作日历,个人日历,运动日历等,每个日历都有自己的事件。我想要显示所有日历上的所有事件,我认为我需要一个日历类,然后嵌套的类将是事件类。由于我想在一个列表中显示所有日历的事件,它们会全部放入一个已排序的数组中。但是,假设我想删除其中一个日历,比如我的工作日历,如何确保从此列表/数组中删除了所有工作事件?我很好奇这个类结构如何高层次地设置。任何帮助将不胜感激。


在我的看法中,你应该从日历和事件的基本概念开始。然后我会为每组事件(例如工作、个人等)创建一个新的日历。接下来需要定义一些“可视”组件,能够显示一个或多个日历。这样,当你删除一个日历时,只需删除不再需要的实例,其余部分将保留不变。 - MadProgrammer
1
看一下组合设计模式。 - Jordão
4个回答

1
如果我要满足您的需求,我将会有以下的排列方式:
interface Calendar 
class DefaultCalendar implements Calendar //<- default implementation for calendar. will hold the implementation for the common behavior for all the calendars
class PersonalCalendar implements Calendar //<- implementation for calendar that holds personal events, decorator for DefaultCalendar
class SportsCalendar implements Calendar //<- implementation for calendar that holds sports events, decorator for DefaultCalendar
class WorkCalendar implements Calendar //<- implementation for calendar that holds work events, decorator for DefaultCalendar
class Event //<- the event object, setters & getters
class CalendarManager //<- object for adding, removing calendars

我将使用TreeMap,它是SortedMap的一种实现,以利用事件的自然顺序进行排序。

Map<String, Calendar> calendars = new TreeMap<String, Calendar>();

我还将在事件名称前添加特定于日历的单词,以按日历类型(因此是事件类型)对事件进行分组显示。

@Override public void addEvent(Event event){
    //event.setName("Work Event : " + event.getEventName()); for work event
    //event.setName("Sports Event : " + event.getEventName()); for sports event
    //event.setName("Personal Event : " + event.getEventName()); for personal event
    calendar.addEvent(event);
}

因此,当经理被要求显示所有事件时,将会导致该结果。
Personal Event : blah blah blah abc 123
Personal Event : blah blah blah abc 123
Sports Event : blah blah blah abc 123
Work Event : blah blah blah abc 123

现在,为了证明我所说的,这里是我的可以运行的代码。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;

/* the demo class */

public class CalendarDemo {
    public static void main(String[] args) throws ParseException{
        CalendarManager manager = new CalendarManager();

        Calendar mySportsCalendar = new SportsCalendar(new DefaultCalendar());
        Calendar myWorkCalendar = new WorkCalendar(new DefaultCalendar());
        Calendar myPersonalCalendar = new PersonalCalendar(new DefaultCalendar());

        Event myBirthday = new Event("My 23rd Birthday Celebration", "September 17, 2013", "This marks my 23rd birthday celebration!");
        Event myMothersBirthday = new Event("My Mother's 50th Birthday Celebration", "December 19, 2013", "This marks my mothers 50th birthday celebration!");

        Event tennisGame = new Event("Tennis Game With Denver", "August 11, 2013", "3rd tennis game with my nephew.");

        Event newProjectMeeting = new Event("New Project Meeting", "August 11, 2013", "Meeting with our new project.");

        myPersonalCalendar.addEvent(myBirthday);
        myPersonalCalendar.addEvent(myMothersBirthday);
        myWorkCalendar.addEvent(newProjectMeeting);
        mySportsCalendar.addEvent(tennisGame);

        manager.addCalendar("sportsCalendar", mySportsCalendar);
        manager.addCalendar("workCalendar", myWorkCalendar);
        manager.addCalendar("personalCalendar", myPersonalCalendar);

        System.out.println("Before the removal of personal calendar : ");
        System.out.println("--------------------------------------------------------------------------------");
        System.out.println(manager.displayAllCalendarEvents());

        manager.removeCalendar("personalCalendar"); //<- will delete all the events in personalCalendar;

        System.out.println("After the removal of personal calendar : ");
        System.out.println("--------------------------------------------------------------------------------");
        System.out.println(manager.displayAllCalendarEvents());
    }
}

/* the calendar interface */

interface Calendar{
    Event getEvent(String eventName);
    List<Event> getEvents();
    void addEvent(Event event);
    String getDescription();
    void setDescription(String desc);
}

/* the default implementation of calendar */

class DefaultCalendar implements Calendar{

    private List<Event> events;
    private String description;

    public DefaultCalendar(){
        events = new ArrayList<Event>();
    }

    @Override public Event getEvent(String eventName) {

        for(Event event : events){
            if(event.getEventName().equals(eventName))
                return event;
        }

        throw new IllegalArgumentException("Event name does not exist in the event list.");
    }

    @Override public void addEvent(Event event) {
        events.add(event);
    }

    @Override public String getDescription(){
        return description;
    }

    @Override public void setDescription(String desc){
        description = desc;
    }

    @Override public List<Event> getEvents() {
        return events;
    }
}

/* decorators for defaultcalendar. If you want
 * specific behavior for a specific calendar, you can
 * specify it in these classes.
 * ---------------------------------------------- */

class SportsCalendar implements Calendar{

    private Calendar calendar;

    public SportsCalendar(Calendar baseCalendar){
        calendar = baseCalendar;
    }

    @Override public String getDescription(){
        return calendar.getDescription();
    }

    @Override public void addEvent(Event event){
        event.setEventName("Sports Event : " + event.getEventName());
        calendar.addEvent(event);
    }

    @Override public Event getEvent(String eventName) {
        return calendar.getEvent("Sports Event : " + eventName);
    }

    @Override public void setDescription(String desc) {

        //do something to the passed desc
        //...
        //then pass it to the wrapped calendar;

        calendar.setDescription(desc);
    }

    @Override public List<Event> getEvents() {
        return calendar.getEvents();
    }
}

/* another decorator */

class WorkCalendar implements Calendar{

    private Calendar calendar;

    public WorkCalendar(Calendar baseCalendar){
        calendar = baseCalendar;
    }

    @Override public String getDescription(){
        return calendar.getDescription();
    }

    @Override public void addEvent(Event event){
        event.setEventName("Work Event : " + event.getEventName());
        calendar.addEvent(event);
    }

    @Override public Event getEvent(String eventName) {
        return calendar.getEvent("Work Event : " + eventName);
    }

    @Override public void setDescription(String desc){

        //do something to the passed desc
        //...
        //then pass it to the wrapped calendar;

        calendar.setDescription(desc);
    }

    @Override public List<Event> getEvents() {
        return calendar.getEvents();
    }
}

/* another decorator */

class PersonalCalendar implements Calendar{

    private Calendar calendar;

    public PersonalCalendar(Calendar baseCalendar){
        calendar = baseCalendar;
    }

    @Override public String getDescription(){
        return calendar.getDescription();
    }

    @Override public void addEvent(Event event){
        event.setEventName("Personal Event : " + event.getEventName());
        calendar.addEvent(event);
    }

    @Override public Event getEvent(String eventName) {
        return calendar.getEvent("Personal Event : " + eventName);
    }

    @Override public void setDescription(String desc) {

        //do something to the passed desc
        //...
        //then pass it to the wrapped calendar;

        calendar.setDescription(desc);
    }

    @Override public List<Event> getEvents() {
        return calendar.getEvents();
    }
}

/* the calendar manager, for adding & removing calendars */

class CalendarManager{

    private Map<String, Calendar> calendars;

    public CalendarManager(){
        calendars = new TreeMap<String, Calendar>();
    }

    public void addCalendar(String key, Calendar calendar){
        calendars.put(key, calendar);
    }

    public void removeCalendar(String key){
        calendars.remove(key);
    }

    public String displayAllCalendarEvents(){
        StringBuilder bdr = new StringBuilder();

        for(String key : calendars.keySet()){
            for(Event event : calendars.get(key).getEvents()){
                bdr.append(event.getEventName())
                .append("\t")
                .append(event.getEventDate())
                .append("\t")
                .append(event.getEventDescription())
                .append("\n");
            }
        }

        return bdr.toString();
    }
}

/* the event object */

class Event{

    private String name;
    private Date date;
    private String description;

    public Event(String name, String date, String description){
        this.name = name;
        try {
            this.date = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse("December 19, 2013");
        } catch (ParseException e) {
            throw new IllegalArgumentException("Invalid date format!");
        }
        this.description = description;
    }

    public String getEventName() {
        return name;
    }

    public Date getEventDate() {
        return date;
    }

    public String getEventDescription() {
        return description;
    }

    public void setEventName(String name) {
        this.name = name;
    }

    public void setEventDate(String date) {
        try {
            this.date = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse("December 19, 2013");
        } catch (ParseException e) {
            throw new IllegalArgumentException("Invalid date format!");
        }
    }

    public void setEventDescription(String description) {
        this.description = description;
    }
}

1

以下是我会采取的步骤,突出部分是我会关注的:

如果我有一个不同的日历列表,例如工作日历个人日历运动日历等,每个日历都有其自己的事件。由于我想在一个列表中显示所有日历的所有事件,它们将全部进入一个排序数组中。但假设我想要删除其中一个日历,比如我的工作日历,我该如何确保从这个列表/数组中删除所有工作事件

这给了我:

emum CalendarType
{
    WORK,
    PERSONAL,
    SPORT,
}

class Event
{
    // event data, like time, place, people, etc...
    private Calendar owner;
}

class Calendar
{
    private CalendarType type; // or make this a String and get rid of the enum 
                               // if people can make their own types
    private List<Event> event;s
}

关于希望将所有事件放在一个列表中并在日历上删除它们的部分有些困难。
我认为我会在一个名为CalendarUtils的类中添加一个像这样的方法:
public static void deleteEvents(Calendar c, List<Event> events)
{
    // loop through all the events, for each one from the calendar remove it
}

我可以看到循环引用和强耦合。 - Philip Puthenvila
因为日历知道事件,而事件也知道日历?这可能有点奇怪,但并不完全错误。可以通过添加一个CalendarEvent类来消除这种关系,该类具有对两者的引用。 - TofuBeer

0
public abstract class BaseCalendar{//do some common functionality here or define the abstract methods so child class will provide the implementation }
public class WorkCalendar extends BaseCalendar{//do WorkCalendar specific functionality here}
public class PersonalCalendar extends BaseCalendar{//do Personalcalendar specific functionality here}
public class SportsCalendar extends BaseCalendar{//do Sportscalendar specific functionality here}
create another class for Events and create list of events for each calendar(use aggrgation here, once your calendar is destroyed your events will also destroyed)

如果每个日历的行为不同,这将是我采取的方法。


0
你不一定需要嵌套你的类。只需创建一个类,如MadProgrammer所建议的那样,它是一个事件,将其实现到你的日历类中,并根据需要使用它。如果你想删除一个日历,你可以包含一些方法来确保从该日历内部删除所有事件。但只需删除日历对象即可完成操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接