如何设计一个屏幕来处理许多(类似的,子类)对象?

时间:2015-10-25 05:31:37

标签: java inheritance static

前言:我试图在不需要样板代码的情况下解决我的问题。我可以通过复制/粘贴和重构代码轻松解决这个问题,但是这种问题应该可以用模型驱动的方法解决,因为设计明显重现。

我有一个包含四种不同对象类型的数据库应用程序,它们将用作另一个中心对象的参数。

enter image description here

所有四个字段在结构上都相同:一个自动生成的主键和一个VARCHAR字段。这些字段需要由最终用户编辑,因此我设计了这个屏幕:

enter image description here

不是为此制作四个不同的屏幕,我认为制作这个由四种不同对象类型使用的屏幕会很好。为了做到这一点,我(显然,对吗?)需要创建一个抽象的对象(我称之为)StringField,它可以通过四种子类型实现:StatusType,{{1 }和Classification。如前所述,因为每个对象在结构上都是相同的,并且以相同的方式读/写数据库,所以抽象对象似乎是合乎逻辑的。所以,我提出了这个目标:

Designation

子类实现如下(例如):

public abstract class StringField {

    private final int id;
    private final String value;
    private final String fieldname;
    private final String tablename;

    public StringField(int id, String value, String fieldname, String tablename) {
        this.id = id;
        this.value = value;
        this.fieldname = fieldname;
        this.tablename = tablename;
    }

    public String getValue() {
        return value;
    }

    public int getId() {
        return id;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 59 * hash + this.id;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        return this.id == ((StringField)obj).id;
    }

    @Override
    public String toString() {
        return value;
    }

    public int insertValue(DB db, String value) throws WrappedSQLException {

        ... // DB code here
    }

    public void updateValue(DB db, String value, int id) throws WrappedSQLException {

        ... // DB code here
    }

    public void deleteValue(DB db, int id) throws WrappedSQLException {

        ... // DB code here
    }
}
  

撇开:public class Type extends StringField { public Type(int id, String value) { super(id, value, "type", "customer_type"); } } public class Classification extends StringField { public Classification (int id, String value) { super(id, value, "classification", "customer_classification"); } } String fieldname的原因   构造函数是Java不允许静态抽象   领域。因此,它们需要由类别手动提供   使用超级类型。不幸的是,这会阻止String tablename,   insertupdate方法也被声明为delete。   如果Java允许static,我怀疑我会问这个问题   因为我只会制作static abstractinsertupdate   方法static以deletefieldname作为抽象静态   字段,将被强制由子类型实现   静态时尚,然后可以静态引用   超类,然后可以通过每个超静态调用   亚型。基本上,它可能看起来像这样:

     

超类型:

tablename
     

亚型:

public abstract class StringField {

    private final int id;
    private final String value;

    public StringField(int id, String value) {
        this.id = id;
        this.value = value;
    }

    public static abstract String fieldname;
    public static abstract String tablename;

    public static int insertValue(String value) {

        // Insert code, returns auto-generated primary key
        // ...
        // This code will use the static fields `fieldname` and `tablename`.
        // ...
        return -1;
    }

    public static void updateValue(String value, int id) {

        // Update code...
        // ...
        // This code will use the static fields `fieldname` and `tablename`.
        // ...
    }

    public static void deleteValue(int id) {

        // Delete code...
        // ...
        // This code will use the static fields `fieldname` and `tablename`.
        // ...
    }
}
     

并使用如下:

static class Type extends StringField {

    public Type(int id, String value) {
        super(id, value);
    }

    public static String fieldname = "type";
    public static String tablename = "customer_type";
}

好的,足够抱怨Java不允许Type.insertValue(newValue); 。这是我到目前为止完整的,(几乎)可编译的代码,它说明了我的方法:

static abstract

然而,这会引发错误:

@SuppressWarnings("serial")
public class StringFieldEditor extends JPanel {

    final Collection<StringField> fields;
    String fieldname;
    public StringFieldEditor(Collection<StringField> fields, String fieldname) {
        super(new GridBagLayout());
        this.fields = fields;
        this.fieldname = fieldname;
        GridBagConstraints gridBagConstraints;

        JButton addNew_button = new JButton();
        JButton delete_button = new JButton();
        JButton edit_button = new JButton();
        JLabel jLabel1 = new JLabel();
        JList<StringField> jList = new JList<>();
        jList.setModel(new DefaultListModel<>());
        jList.setListData(fields.toArray(new StringField[fields.size()]));
        JScrollPane jScrollPane1 = new JScrollPane();
        jScrollPane1.setViewportView(jList);

        jLabel1.setText("Customer " + fieldname + " Editor");
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new Insets(11, 10, 0, 0);
        add(jLabel1, gridBagConstraints);


        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 5;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.ipadx = 178;
        gridBagConstraints.ipady = 206;
        gridBagConstraints.anchor = GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new Insets(6, 10, 0, 10);
        add(jScrollPane1, gridBagConstraints);

        addNew_button.setText("Add New");
        addNew_button.addActionListener((ActionEvent evt) -> {
            // Add New Task
        });
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new Insets(6, 10, 11, 0);
        add(addNew_button, gridBagConstraints);

        edit_button.setText("Edit");
        edit_button.addActionListener((ActionEvent evt) -> {
            // Edit Task
        });
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.anchor = GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new Insets(6, 6, 11, 0);
        add(edit_button, gridBagConstraints);

        delete_button.setText("Delete");
        delete_button.addActionListener((ActionEvent evt) -> {
            // Delete Task
        });
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new Insets(6, 6, 11, 10);
        add(delete_button, gridBagConstraints);
    }

    static class Type extends StringField {

        public Type(int id, String value) {
            super(id, value, "type", "customer_type");
        }
    }

    public abstract class StringField {

        private final int id;
        private final String value;
        private final String fieldname;
        private final String tablename;

        public StringField(int id, String value, String fieldname, String tablename) {
            this.id = id;
            this.value = value;
            this.fieldname = fieldname;
            this.tablename = tablename;
        }

        public String getValue() {
            return value;
        }

        public int getId() {
            return id;
        }

        @Override
        public int hashCode() {
            int hash = 5;
            hash = 59 * hash + this.id;
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            return this.id == ((StringField)obj).id;
        }

        @Override
        public String toString() {
            return value;
        }

        public int insertValue(String value) {

            // Insert code, returns auto-generated primary key
            // ...
            // ...
            return -1;
        }

        public void updateValue(String value, int id) {

            // Update code...
            // ...
            // ...
        }

        public void deleteValue(int id) {

            // Delete code...
            // ...
            // ...
        }
    }

    public static void main(String[] args) {
        LinkedList<Type> types = new LinkedList<>();
        types.add(new Type(1, "Type 1"));
        types.add(new Type(2, "Type 2"));
        types.add(new Type(3, "Type 3"));

        JFrame frame = new JFrame();
        frame.add(new StringFieldEditor(types, "type"));
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

但改变:

incompatible types: LinkedList<Type> cannot be converted to Collection<StringFieldEditor.StringField>

    final Collection<StringField> fields;
    String fieldname;
    public StringFieldEditor(Collection<StringField> fields, String fieldname) {
尝试将数据加载到 final Collection<? extends StringField> fields; String fieldname; public StringFieldEditor(Collection<? extends StringField> fields, String fieldname) { 时,

会导致问题(JList需要toArray类型的值,但如果我不知道我正在使用的确切类型,我无法提供新的T类型数组。

另外,我预见到尝试以非子类特定方式引用非静态插入,更新和删除方法的问题。

我的问题:

  1. 这种方法可行吗?我是否过分采用这种模型驱动的开发方法?
  2. 有没有更好的方法来实现此功能而无需创建样板代码?
  3. 对于Java中没有T个方法/字段的事实,是否有一个很好的解决方法?
  4. 当您不知道要使用哪种子类型时,有没有办法为static abstract方法提供可用的数组?

0 个答案:

没有答案