代码之家  ›  专栏  ›  技术社区  ›  ryeguy

只有一个类被另一个类使用是不是设计不好?

oop
  •  1
  • ryeguy  · 技术社区  · 15 年前

    我有一个 QueueProcessor 处理工作队列的类。我想用一堆统计数据发送一封总结所有工作的电子邮件。我已经在使用邮件类了( Zend_Mail ,所以大多数电子邮件工作都是抽象出来的,但是我仍然需要弄清楚在哪里放置代码来生成摘要信息。我基本上是在处理过程中收集数据,然后我必须将数据转换成适合电子邮件的格式。

    我的问题是,我是否应该创建一个名为 QueueProcessorSummaryEmail 还是因为它与原始类紧密耦合,所以被认为是糟糕的设计?如果我 让它成为自己的类,我需要传递大量的数据给它来生成电子邮件,但是这样的分离是很好的。如果我 不要 使其成为类,所有数据都可以从 排队处理机 类,但将处理逻辑和报告生成逻辑混合在一个类中感觉很奇怪。

    对于记录,当我说“报告生成逻辑”时,我不是说我在内联生成HTML,而是使用一个视图。通过格式化,我的意思是获取数据并将其聚合成可通过电子邮件报告使用的内容。

    6 回复  |  直到 15 年前
        1
  •  4
  •   S.Lott    15 年前

    Ryeguy

    我的建议是创建一个decorator类(比如summarizedqueryprocessor)来扩展queueprocessor的功能。这将允许更高程度的关注点分离,并将简化单元测试。

    特德

        2
  •  4
  •   S.Lott    15 年前

    这是否被认为是糟糕的设计,因为它与原始类的耦合非常紧密?

    不,这不是问题。子类超类设计也是紧密耦合的。

    将处理逻辑和报告生成逻辑混合在一个类中感觉很奇怪。

    报告/总结的授权通常是有意义的。报告更改和扩展比处理更快。

        3
  •  1
  •   Community Mohan Dere    8 年前

    一种帮助设计脱偶的方法是使用 界面 . 例如,可以创建一个名为 ISummaryDataProvider 并拥有 QueueProcessor 使用属性和方法实现该接口,这些属性和方法将需要为处理摘要数据的另一个类提供数据。

    然后,您可以为 QueueProcessorSummaryEmail 收容 I摘要数据提供程序 作为参数。这样的话,如果你决定从除 排队处理机 ,您只需确保新数据源实现 I摘要数据提供程序 这样它就可以被 队列处理程序或摘要电子邮件 .


    在我的问题中,我探讨了类似的面向对象设计问题。 How should I model my code to maximize code re-use in this specific situation? . 建议使用的答案之一 依赖注入 我以前不太明白。您可以在我的问题的底部看到我如何以松散耦合的方式实现这个解决方案。你可能会发现那里的信息对你的情况有帮助。

        4
  •  0
  •   djna    15 年前

    结构很重要。如果有一组逻辑实际上不属于某个类,那么在其他地方重构它可以真正帮助将来的mainatable。

    在支持内部类的语言中,您可以将其作为内部类。可能是稍后分离并重用它,然后需要将数据传递给它,此时您可以定义一个邮件类接受的接口,以及哪个队列处理器实现的接口。

        5
  •  0
  •   jim tollan    15 年前

    莱伊盖

    我很想 QueueProcessor 类基本抽象类,然后扩展该类以创建 QueueProcessorSummaryMail 班级。

    好的,基本示例:

    class QueueProcessor
    {
         // all your methods and properties
    }
    
    class QueueProcessorSummaryMail extends QueueProcessor
    {
         // add your custom properties and methods here
    }
    

    希望,这给了你主要的想法。

    吉姆

    [编辑]当然是针对PHP的。对于C,您仍然可以使用抽象类或接口。

        6
  •  0
  •   Heath Lilley    15 年前

    像这样的东西怎么样?

    public interface WorkProcessorI {
        public void process( WorkQueue queue ); // could also be something like "process( Task[] queue )"
    }
    
    public interface SummaryGeneratorI () {
        public String[][] generateSummary(); // returns subscripted string array of name/values or whatever
    }
    
    public class QueueProcessor implements WorkProcessorI, SummaryGeneratorI {
        public void process( WorkQueue queue ) {
            // process queue populating member values that will be used to generate the summary.
         }
    
         public String[][] generateSummary() {
            // read values that were populated by the process( WorkQueue ) method.
         }
    }
    
    public class SummaryMail {
        private String[][] summary = null;
        public void setSummary( String[][] argSummary ) {
            this.summary = argSummary;
        }
        // to, from, server, cc, bcc, subject, Additional body text, ...
    
        public void send() {
            // sends email via whatever api you want.
        }
    }