有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java软件设计原则:将您的收藏与处理对象分开?

在OOP设计中与一个小组合作一个小组成员和我有分歧,我在网上找不到答案

创建一个类似于非营利组织的软件,该组织有捐助者和他们的信用卡

process diagram

一种方法是creditCardList(集合类)应该只存储和返回creditCard对象。然后当返回它们时Organization类应该为每个对象运行processCard(),作为creditCard对象的方法

另一方面是CreditCardList应该处理所有项目,并包含在集合中所有项目上运行的循环

一般来说,什么是更好的软件设计


共 (4) 个答案

  1. # 1 楼答案

    这是另一种设计理念。与其专注于完成目标所需的步骤,不如先对问题进行建模,然后使用问题的为事物命名

    显然有Organization接受Donation的。好的,让我们试试这个:

    public interface Organization {
        void accept(Donation donation);
    }
    
    public interface Donation {
    }
    

    现在,捐赠的资金可能需要在accept()方法中的某个点转移到组织中,因此让我们将此作为Donation对象的责任:

    public interface Donation {
        void transferTo(BankReference target);
    }
    

    在本例中,您一次处理多个捐赠。这是您询问的迭代。这将是在这个类中:

    public final class Donations implements Donation {
        ...
        public Donations(Donation... donations) {
            ...
        }
    
        @Override
        public void transferTo(BankReference target) {
            donations.forEach(donation -> donation.transferTo(target));
        }
    }
    

    接下来,你想用信用卡进行捐赠。您可以通过提供特定的捐赠类型来做到这一点

    public final class CreditCardDonation implements Donation {
        ...
        @Override
        public void transferTo(BankReference target) {
            // Here is the credit card processing logic
        }
    }
    

    我显然不知道您需求的所有细节,但我的观点是从您拥有的东西开始,而不是需要进行的技术步骤(如信用卡处理)。这也适用于方法名,而不仅仅是类名

  2. # 2 楼答案

    首先,对于图表中的每个调用,我都感到好奇:为什么组织调用CreditCard方法。processCard并将creditCard实例作为参数传递

    “处理信用卡”首先意味着什么?信用卡实例是否能够处理它? 我要做的第一个设计决策是,CreditCard对象不应该依赖于某些外部服务。处理信用卡听起来像是处理外部事务。 我会保持信用卡逻辑的纯洁。此处仅将逻辑操作放在本地字段和属性上

    CreditCardList有一个主要任务。持有一套信用卡。您想要检索和存储信用卡列表的方式可能会改变,因此最好将关注点分开,并将处理逻辑排除在该类之外。 在CreditCardList中运行循环的一个原因可能是,您不想公开信用卡的具体列表。但这可以用一种更优雅的方式来处理。定义接口ICardProcessor并将其作为构造函数参数注入CreditCardList。 然后,foreach可以留在类中并调用ICardProcessor。在每个实例上处理(卡片)

  3. # 3 楼答案

    很抱歉,对于职责分离原则,我不会选择这两种方法中的任何一种。如果我正确理解该要求,则组织对象是代表接受捐赠的慈善组织的实体。CreditCardList是用于支付处理的所有信用卡的集合。它们都不是保存支付处理逻辑的好地方

    相反,我将引入一个新的helper类,其名称类似于PaymentProcessor。这个类将有一个名为processPayment(List<CreditCard> creditCards)的方法。此方法应包含处理信用卡付款的逻辑。在这个设计中,您还可以在这个类中引入其他方法来使用其他方式处理付款,例如从银行帐户或PayPal直接借记

    根据OO设计原则,我们应该有一个类或接口用于一个目的,以便更好地维护

    我希望这可能有助于解决您与同事之间的建设性分歧。:)

  4. # 4 楼答案

    我会选择第一个选项

    由于您已经将CreditCardList用作存储,因此该类不应承担任何其他职责。此类的功能仅限于提供卡片(全部/部分,有条件/按条件)

    第二个选项提出了将存储器与卡处理机制耦合的问题。存储库现在取决于处理系统以及系统可能需要的输入参数。此外,存储确实知道它不应该知道的所有进程