避免使用检查实例相关和原始类型 [英] Avoid using checks for instance-relating and raw types

查看:98
本文介绍了避免使用检查实例相关和原始类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在stackoverflow.com上重新检查了一些关于树结构的文档以及关于这个主题的一些相关答案,例如这个他们大多使用原始类型或只使用一种不适用于我的问题的特定类型。我有一个将meta存储为XML的文件,因此解析不是问题,但我仍然需要一个干净的数据结构来存储实际信息。

I recheck some documentation on tree structures and some relating answers on the subject here on stackoverflow.com, for example this one and they mostly use raw types or just one specific type which does not work for my problem. I have a file which stores meta as an XML, so parsing wasn't a problem but I still need a clean data structure to store the actual information.

文件的实际部分

<File>
  <Meta>
    <Generator>default</Generator>
    <HeaderHash>110EbosCOut9ooqtIza4yHdT9xx+wUAp1VMfPqpQKwM=</HeaderHash>
    <Color/>
    <MemoryProtection>
      <ProtectTitle>False</ProtectTitle>
      <ProtectUserName>False</ProtectUserName>
      <ProtectPassword>True</ProtectPassword>
      <ProtectURL>False</ProtectURL>
      <ProtectNotes>False</ProtectNotes>
    </MemoryProtection>
    <CustomIcons/>
    <Binaries />
    <CustomData/>
  </Meta>
</<File>

我提出的数据结构

public class MetadataEntry {

    public MetadataEntry() {
        this.entity = new Entry();
    }

    private class Entry<T> {
        private String name;
        private T value;
        private boolean isGroup;

        private void setValue(T value) {

            if (value instanceof String) {
                this.value = value;
                this.isGroup = false;
            }

            if (value instanceof MetadataEntry) {
                if (isGroup()) {
                    ((List<MetadataEntry>) this.value).add((MetadataEntry) value);
                } else {
                    this.value = (T) new ArrayList<MetadataEntry>();
                    this.isGroup = true;
                    setValue(value);
                }
            }
        }

    }

    private Entry entity;


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

    public String getName() {
        return this.entity.name;
    }

    public void setValue(String value) {
        entity.setValue(value);
    }

    public void setValue(MetadataEntry value) {
        entity.setValue(value);
    }

    public boolean isGroup() {
        return this.entity.isGroup;
    }

    public List<MetadataEntity> getChildNodes() {
        if (isGroup()) {
            return (List<MetadataEntry>) this.entity.value;
        }

        return null;
    }

    public String getValue() {
        if (!isGroup()) {
            return (String) this.entity.value;
        }

        return null;
    }
}

所以,你能否建议如何让它更清洁,如果显然没有必要使用原始类型并避免使用 instanceof ?或者更好地指出我,请在哪里阅读更多相关内容。

So, could you suggest how to make it cleaner, without using raw types if it is clearly not necessary and avoid using instanceof? Or even better point me out please where to read more about it.

如果出于某种原因,如果出于某种原因,我会更加赞赏议价评论而非投票不感兴趣。

推荐答案

复合模式将适合您的情况,引用设计模式 GoF

Composite Pattern will be suitable for your case, citing 《Design Patterns》GoF


将对象组合成树结构以表示部分整体层次结构。
Composite允许客户端统一处理对象的单个对象和组合

Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

以下代码组合了您的树结构已应用复合模式

The following code composites your tree structure with Composite Pattern applied.

/**
 * declares the interface for objects in the composition
 * @param <T>
 */
interface MetaEntry<T> extends Iterable<MetaEntry<T>> {
    T getName();
    MetaEntry<T> setName(T name);
    T getValue();
    MetaEntry<T> setValue(T name);
    MetaEntry<T> add(MetaEntry<T> entry);
    MetaEntry<T> remove(MetaEntry<T> entry);
}
/**
 * represents leaf objects in the composition. A leaf has no children.
 * @param <T>
 */
class SimpleMetaEntry<T> implements MetaEntry<T> {
    T name;
    T value;
    @Override
    public T getName() {
        return name;
    }

    @Override
    public MetaEntry<T> setName(T name) {
        this.name = name;
        return this;
    }

    @Override
    public T getValue() {
        return value;
    }

    @Override
    public MetaEntry<T> setValue(T value) {
        this.value = value;
        return this;
    }

    @Override
    public MetaEntry<T> add(MetaEntry<T> entry) {
        throw new UnsupportedOperationException();
    }

    @Override
    public MetaEntry<T> remove(MetaEntry<T> entry) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Iterator<MetaEntry<T>> iterator() {

        // we want to treat all objects uniformly.
        return  new Iterator<MetaEntry<T>>() {
            @Override
            public boolean hasNext() {
                return false;
            }

            @Override
            public MetaEntry<T> next() {
                return null;
            }
        };
    }

    @Override
    public String toString() {
        return "<" + name + (value == null ? "/>" : ">" + value + "</" + name + ">\n");
    }
}

/**
 * defines behavior for components having children.
 * @param <T>
 */
class CompositeMetaEntry<T> implements MetaEntry<T> {
    T name;
    T value;
    List<MetaEntry<T>> list = new ArrayList<MetaEntry<T>>();
    @Override
    public T getName() {
        return name;
    }

    @Override
    public MetaEntry<T> setName(T name) {
        this.name = name;
        return this;
    }

    @Override
    public T getValue() {
        return value;
    }

    @Override
    public MetaEntry<T> setValue(T value) {
        this.value = value;
        return this;
    }

    @Override
    public MetaEntry<T> add(MetaEntry<T> entry) {
       list.add(entry);
        return this;
    }

    @Override
    public MetaEntry<T> remove(MetaEntry<T> entry) {
        list.remove(entry);
        return this;
    }

    @Override
    public Iterator<MetaEntry<T>> iterator() {
        return  list.iterator();
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();

        builder.append("<" + name + ">");

        for(MetaEntry<T> metaEntry : this) {
            builder.append(metaEntry.toString());
        }
        builder.append("</" + name + ">");

        return builder.toString();
    }
}

public static void main(String[] args) throws Exception {
        MetaEntry<String> compositeMetaEntry = new CompositeMetaEntry<String>();
        compositeMetaEntry.setName("File");
        compositeMetaEntry.add(
                new CompositeMetaEntry<String>().setName("Meta").add(
                        new SimpleMetaEntry<String>().setName("Generator").setValue("default")
                ).add(
                        new SimpleMetaEntry<String>().setName("HeaderHash").setValue("110EbosCOut9ooqtIza4yHdT9xx+wUAp1VMfPqpQKwM=")
                ).add(
                        new SimpleMetaEntry<String>().setName("Color")
                ).add(
                        new CompositeMetaEntry<String>().setName("MemoryProtection").add(
                                new SimpleMetaEntry<String>().setName("ProtectTitle").setValue("False")
                        ).add(
                                new SimpleMetaEntry<String>().setName("ProtectUserName").setValue("False")
                        ).add(
                                new SimpleMetaEntry<String>().setName("ProtectPassword").setValue("True")
                        ).add(
                                new SimpleMetaEntry<String>().setName("ProtectURL").setValue("False")
                        ).add(
                                new SimpleMetaEntry<String>().setName("ProtectNotes").setValue("false")
                        )
                ).add(
                        new SimpleMetaEntry<String>().setName("CustomIcons")
                ).add(
                        new SimpleMetaEntry<String>().setName("Binaries")
                ).add(
                        new SimpleMetaEntry<String>().setName("CustomData")
                )
        );

        System.out.println(compositeMetaEntry);

}

这篇关于避免使用检查实例相关和原始类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆