当前位置: 首页 > 面试题库 >

OO设计建议-toString

笪建章
2023-03-14
问题内容

所以我上了Address课:

class Address 
{
    private String streetAddress;
    private int number;
    private String postalCode;
    private City city;
    private State state;
    private Country country;
}

我想让它的可读版本显示在网格列中。

什么是实现此目的的最佳和简洁的方法?

  1. toString类内部的方法Address我个人不喜欢这种方法,因为’toString’与Address没有直接关系
  2. ReadableAddressFormatter
    • ReadableAddressFormatterAddress addressToFormat
    • 上市 String getFormatted()
  3. 上一类,但getFormmated将是静态的,接收Address实例并返回字符串
  4. 其他?请提出建议。

我正在寻找一个好的设计,同时还要关注“ 干净代码” ,“ 去耦” 和“ 可维护性”


问题答案:

所有这些方法均已使用,并且无法提供“与上下文无关”的最佳实践。软件工程中最好的答案通常是“取决于情况”。就是说,让我们分析一下每个:

  1. 最好的KISS方法。我用我所有的基本“打印到控制台,确保一切正常”的方式执行此操作。如果您希望使用特定格式的地址,那么这是低挂的水果/轻松获胜解决方案。您始终可以覆盖此设置,或者在一种情况下以不同方式打印对象。
  2. 这是最可扩展的解决方案,因为它将很好地支持本地化和自定义格式。是否合适取决于您期望地址以不同格式显示的频率。您是否真的需要那颗死亡之星来击败苍蝇,或者是否能够将所有大写字母或两种语言之间的转换对您的应用程序至关重要?
  3. 我不建议采用这种方法,因为它通常开始将“视图级别”逻辑渗入到Domain中,通常最好由其他层(在类MVC方法中)来处理。有人可能会说toString()做相同的事情,但是toString()也可以被认为是对象在外部世界中的外观的“名称”或“本质”,所以我要说的不仅仅是表象。 。

希望这对您有所帮助,并从一开始就对“干净代码”,“解耦”和“可维护性”进行思考。

对于行动中的原则2的示例-使用策略模式,遵循单一职责原则,开放/封闭原则并允许通过依赖注入进行控制反转
-比较以下方法(@SteveJ慷慨提供) :

public class Address {
        private String streetAddress;
        private int number;
        private String postalCode;
        private String city;
        private String state;
        private String country;

        public String toLongFormat(){
            return null; // stitch together your long format
        }

        public String toShortFormat(){
            return null; // stitch together your short format
        }

        public String toMailingLabelFormat(){
            return null; // stitch together your mailing label format
        }

        @Override
        public String toString(){
            return toShortFormat(); // your default format
        }
    }

}

有了这个(在“最正确的” Groovy中):

public interface AddressFormatter {
   String format(Address toFormat)
}

public class LongAddressFormatter implements AddressFormatter {
    @Override
    public String format(Address toFormat){
         return String.format("%sBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAH%n%s", toFormat.streetAddress, toFormat.postalCode)
    }
}


public class ShortAddressFormatter implements AddressFormatter {
    @Override
    public String format(Address toFormat){
         return String.format("%d", toFormat.number)
    }
}

public  class Address {
        private String streetAddress;
        private int number;
        private String postalCode;
        private String city;
        private String state;
        private String country;
        public  AddressFormatter formatter = new ShortAddressFormatter(); // just to avoid NPE

        public void setFormatter(AddressFormatter fr) { this.formatter = fr; }



        @Override
        public String toString(){
            return formatter.format(this); // your default format
        }
    }

def addrr = new Address(streetAddress:"1234 fun drive", postalCode:"11223", number:1)
addr.setFormatter(new LongAddressFormatter());
println "The address is ${addrr}"
addr.setFormatter(new ShortAddressFormatter());
println "The address is ${addrr}"

正如@SteveJ观察到的:

“因此,您有不同的格式化“策略”,您可以在它们之间进行切换…我有个想法,您将设置一次格式化并坚持下去…并且如果您想添加其他格式化样式,则不要不必打开并重写地址类,而可以编写新的单独样式并在需要使用时注入它。”



 类似资料:
  • 我在客户机-服务器体系结构中使用协议缓冲区作为有线数据格式。域对象(JavaBeans)将经历以下生命周期。 用于客户端业务逻辑 转换为协议格式 传送到服务器 转换回域对象 用于服务器端业务逻辑 “协议缓冲器和O-O设计”部分在协议留档中建议在适当的域模型内包装生成的类。 我想找出最好的办法。 例如,我有一个简单的原型定义。 这就是域模型的定义方式。如您所见,数据完全存储在proto builde

  • 问题内容: 我目前在设计类时遇到循环依赖问题。 自从我了解Anemic域模型(我一直在做的事情)以来,我一直在努力摆脱创建仅仅是“ getter和setter的存储桶”的域对象,并回到我的OO根。 但是,下面的问题是我遇到的很多问题,我不确定应该如何解决。 假设我们有一个 Team 类,其中有很多 Player 。这是什么运动都没有关系:)球队可以添加和删除球员,就像球员离开球队并加入另一个球队一

  • 面试建议有: 细心准备:回归到之前说到作品集三个层级,第一步先把话讲清楚,熟练并精彩的讲述“能力故事”。其实已经可以打败70-80%的设计师了,只需要按照我梳理的步骤细心准备相信大家都可以做好。 作品集讲解的三个层级 层级一:把我做了什么讲清楚 层级二:回答针对业务上的随机提问 层级三:回答开放式随机的提问   大胆自信:为什么说大胆,面试需要我们自信的态度,落落大方的回答提问,让面试官产生信任。

  • 问题内容: 我正在重新设计一个药房数据库系统,需要输入以查看新设计是否最佳或需要调整。 这是旧系统的快照。 可以看到,药房表存储药房信息以及其地址和联系信息。出于开票目的,药店被分组在一起(药房组),或者出于销售目的,将广告用于其他目的(横幅组)。发票组可以具有不同的物理地址,不同的联系信息。 这是我的新设计。我已将地址从pharmacy和pharmacygroup表中拆分成一个自己的表,并为联系

  • 问题内容: 简要阅读以上文章后,我发现getter和setter是糟糕的OO设计,应避免使用它们,因为它们与封装和数据隐藏相反。在这种情况下,创建对象时如何避免这种情况,以及如何将一个模型对象考虑在内。 如果需要使用吸气剂或吸气剂,还可以使用其他替代方法吗? 谢谢。 问题答案: 吸气或吸气器本身并不是很糟糕的OO设计。 不好的是编码实践,它会自动为每个单个成员包括一个getter和一个setter

  • 协议设计 核心概念 EVM:以太坊虚拟机,轻量级虚拟机环境,是以太坊中智能合约的运行环境。 Account:账户,分两类:合约账户存储执行的合约代码;外部账户为以太币拥有者账户,对应到某公钥。 Transaction:交易,从一个账户到另一个账户的消息,包括以太币或者合约执行参数。 Gas:燃料,每执行一条合约指令会消耗一定的燃料,当某个交易还未执行结束,而燃料消耗完时,合约执行终止并回滚状态。