简体   繁体   English

改进对象格式化程序API的类层次结构设计

[英]Improve design of class hierarchy for a object formatter api

While learning object oriented design I'm judging my own design critically. 在学习面向对象的设计时,我会严格地评估自己的设计。 This framework should be able to print objects in either XML, or JSON, I've stubbed in a basic implementation to avoid getting into details of XML and Json parser apis for now. 这个框架应该能够以XML或JSON格式打印对象,我已经在一个基本实现中进行了存根,以避免现在进入XML和Json解析器api的详细信息。

So I made the Formatter be the base class. 因此,我将Formatter设为基类。 But with my current design, all derivatives of this base class would need to know that they have to call: getFormattedValue() to get output. 但是在我当前的设计中,该基类的所有派生类都需要知道它们必须调用: getFormattedValue()来获取输出。 Also I don't feel comfortable with all of those if else statements in the Formatter constructor. 另外,我对Formatter构造函数中的所有if else语句都不满意。 The clients would need to know to pass in either an "xml" or "json" in all derivatives of this class. 客户需要知道在此类的所有派生类中传递“ xml”或“ json”。 How can I improve this design to conform to all Object oriented design Principles? 如何改进此设计以使其符合所有面向对象的设计原则? Thanks in advance.. 提前致谢..

public class Formatter {

    private String output;

    public Formatter(Object object, String formatType){
        if(formatType.equals("xml")){
            output = getXMLFormat(object);
        } else if(formatType.equals("json")) {
            output = getJSONFormat(object);
        }
    }

    private String getXMLFormat(Object object){

        return "<title>"+object.toString()+"<title>"; // simplified
    }

    private String getJSONFormat(Object object){
        return "{"+object.toString()+"}"; // simplified
    }

   protected  String getFormattedValue(){
        return output;
    }
}

The derivative class: 派生类:

public class ItemFormatter extends Formatter {

    public ItemFormatter(Employee item, String formatOutput) {
        super(item, formatOutput);
    }

    public void printItem(){
        System.out.println(getFormattedValue());
    }
}

Split the formatting into multiple classes/interfaces and use a Factory/Factory method in order to get the appropriate formatter. 将格式拆分为多个类/接口,并使用Factory / Factory方法以获得适当的格式程序。 It could look something like this: 它可能看起来像这样:

public interface Formatter {
    String getFormattedValue();
}

and implement a JSonFormatter: 并实现JSonFormatter:

public class JSonFormatter implements Formatter {
    String getFormattedValue(Object object) {
        return "{"+object.toString()+"}";
    }
}

get the correct formatter: 获取正确的格式化程序:

public class FormatterFactory {
    public static Formatter getFormatter(String type) { // maybe use enum to decide
        if (type.equals("json") {
            return new JSonFormatter();
        } else if (type.equals("xml")) {
            return new XMLFormatter();
        }
        return new DefaultFormatter(); // returns toString for example
    }
}

and finally usage: 最后用法:

String formattedXML = FormatterFactory.getFormatter("xml").getFormattedValue("foobar");

I can't recommend anything for getFormattedValue() , you can probably change the method name to make it more obvious, but that's about it. 我不能为getFormattedValue()推荐任何东西,您可能可以更改方法名称以使其更明显,但是仅此而已。

With regards to the xml and json, you can probably use Enums. 关于xml和json,您可能可以使用Enums。

public Enum EnumFormatType {
    FORMAT_XML, FORMAT_JSON;
}

public Formatter(Object object, EnumFormatType formatType) {
   if(EnumFormatType.FORMAT_XML.equals(formatType)){
    // etc...
    }
}

I would start by providing a abstract class to format. 我将从提供一个抽象类进行格式化开始。

abstract class Formatter {
    String format(Object o);
}

Then we specialize two Formatter for XML and JASON 然后,我们专门研究XML和JASON的两个Formatter

class XMLFormatter extends Formatter {
    String format(Object o) {
        return "<title>"+o.toString()+"<title>";
    }
}

Now you just have to choose which formater you need and just call format on any of them to get the right string. 现在,您只需选择所需的格式化程序,然后对其中任何一个调用format以获取正确的字符串。

I think the below code looks more extensible. 我认为以下代码看起来更可扩展。

public interface IFormatter 
{
    String GetFormatted(Object object);
}

public class JSonFormatter extends IFormatter 
{
    public String GetFormatted(Object object)
    {
      return "{"+object.toString()+"}";
    }
}

public class XMLFormatter extends IFormatter 
{
    public String GetFormatted(Object object)
    {
        return "<title>"+object.toString()+"<title>";
    }
}

public class ItemFormatter 
{
    public void printItem(Employee item, IFormatter formatter)
    {    
        System.out.println(formatter.GetFormatted(item));
    }
}

And it can be called like 它可以像

itemFormatterInsatnce.printItem(empInstance, formatterInstance);

Also the formatter instance can be resolved using a formatterFactory either through code or configuration. 格式化程序实例也可以使用formatterFactory通过代码或配置来解析。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM