代码之家  ›  专栏  ›  技术社区  ›  João Silva

分裂或不分裂阶级(在爪哇)

  •  3
  • João Silva  · 技术社区  · 16 年前

    我有一个分阶段分析的句子。首先,我得到一些属性(比如x,y,z):

    public class AnalyzedSentence {
        private String X;
        private String Y;
        private String Z;
    
        public AnalyzedSentence(String sentence) {
            extractX();
            extractY();
            extractZ();
        }
    
        // getters, setters
    }
    

    然后,我使用这些属性进一步分析句子以获得另一个属性,比如“xyz”,然后创建以下类:

    public class FinalSentence {
    
        private AnalyzedSentence data;
    
        private String XYZ;
    
        public FinalSentence(String XYZ, AnalyzedSentence data) {
            this.data = data;
            this.XYZ = XYZ;
        }
    
        // getters, setters
    }
    

    工作流程如下:

    public class SentenceAnalyzer {
        /// ...
        public FinalSentence analyze(String sentence) {
            AnalyzedSentence as = new AnalyzedSentence(sentence);  // every attribute of "as" can be calculated beforehand
            String XYZ = SpecialClass.extractXYZ(sentence, as); // extract XYZ (needs a special class), based on as
            return new FinalSentence(XYZ, as);
        }
    }
    

    或者,我可以让一个类保存所有信息,在提取属性时填充它们,这可能导致一些空结果。就像这样:

    public class Sentence {
    
        private String X;
        private String Y;
        private String Z;    
        private String XYZ;
    
        public Sentence(String sentence) {
            extractX();
            extractY();
            extractZ();
        }
    
        public String getXYZ() {
            // with this design, this method can be called, even if XYZ was not extracted yet.
            // remember that XYZ cannot be extracted as X,Y,Z
        }
    
        public void setXYZ(...) {...}
    
        // getters, setters
    }
    

    我的问题是:首选哪种设计,为什么?如果还有更好的方法来完成我想做的事情,我也想听听。

    6 回复  |  直到 16 年前
        1
  •  2
  •   chrisbunney Bogdan Calmac    16 年前

    您需要考虑的是,在您的问题领域中,分析结果和最终结果是否足够独特,可以拆分或合并。

    很明显,他们正在使用类似的数据,并密切合作以实现目标。

    对我来说,分析和定稿只是陈述一个句子可能存在,尽管这是基于我对你正在处理的问题的有限了解,所以我希望以某种方式将它们结合起来。

    编辑 根据进一步的信息,我想我会设计如下:

    这个 Sentence 类封装了原始语句、标记和提取的类别(或者您提取的任何内容,我假设它是基于您的描述的类别),以及设置、获取和提取该信息的操作。

    这个 句子 类存储A TagList 它包含所有标记、原始字符串和提取的类别。它还通过创建一个 Extractor 然后通过它 标签表 当数据需要提取时(我已将其放入构造函数中,但它可以进入一个方法中,调用它的位置取决于何时需要提取数据)。

    因此,用这种方式,所有需要操纵原句的东西都在 句子 类。当然,您可能知道一些我不知道的事情,这些事情使这种方法不适用,但这里有一些代码来说明我的意思:

    public class Sentence {
    
        private TagList tags    
        private String category;
        private String sentence
    
        public Sentence(String newSentence) {
            sentence = newSentence;
            Extractor<TagList> e = new Extractor<TagList>()
            tags = e.extractTags(sentence);
            category = new Category(tags);
        }
    
        public String getXYZ() {
    
        }
    
        public void setXYZ(...) {...}
    
        private extractTags(String s){ ...}
    
        // getters, setters
    }
    
    
    public class TagList{
    
        private List<String> tags;
    
        ....
        //rest of class definition
    
    }
    
        2
  •  3
  •   Darryl    16 年前

    我个人更喜欢第一个设计,一个有两个班。分析和结果之间的区别对我很有吸引力。我喜欢把类看作责任的集合,而不是数据的集合,并且使用两个不同的类使每个类的责任更加明确。

        3
  •  1
  •   PhiLho    16 年前

    我都是为了做相对较小的课程,因为我必须在工作中与超过8000行的怪物类斗争!
    现在,finalsence类似乎有点太小了,像一个空外壳,一个简单的分析实体外观,而且它的实用性似乎并不明显。

        4
  •  1
  •   Esko Luontola    16 年前

    您的问题的答案取决于您期望这些类在将来如何被修改,因为程序的需求会扩展或改变。

    确定何时拆分/加入类的一个好指南是 单一责任原则 : “类更改的原因不应超过一个。”

    开闭原理 有助于决定如何组织类,以便通过将现有类与新类组合而不是修改现有类来修改现有类的行为: 软件实体(类、模块、函数等)应打开进行扩展,但关闭进行修改。

    http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod

        5
  •  0
  •   chikak    16 年前

    我之所以选择单类,是因为我将提取XYZ视为一个包含两个步骤的逻辑操作。

    在构造函数中,可以提取x、y、z,然后使用特殊类获取x y z并返回最后一句话。

        6
  •  0
  •   Gregory Mostizky    16 年前

    为什么不只是一个基于单个字符串参数返回分析数据的方法呢?

    String analyze(String input) {...}
    

    更少的混乱,没有副作用(在堆栈上做的每件事),更少的机会有人误解API并用它做一些奇怪的事情。