设计模式 - 一个利用许多隐藏类的公共类

时间:2015-02-28 20:12:39

标签: java c# design-patterns

我已经通过http://www.dofactory.com/net/design-patterns试图找出最有效的方法来创建一个设计模式,其中“一个可见类利用许多隐藏的类”来创建一个流畅的API。以下是我目前的代码:

public class VisibleClass {
    Private OrderClass order;
    private ReceiptClass receipt;

    public VisibleClass makeOrder() {
        if (!(order instanceof OrderClass))
            order = new OrderClass();

        order.make();
        return this;
    }

    public VisibleClass printReceipt() {
        if (!(receipt instanceof ReceiptClass))
            receipt = new ReceiptClass();

        receipt.print();
        return this;
    }
}

class OrderClass implements IOrder {
    public void make() {}
}

class ReceiptClass implements IReceipt {
    public void print() {}
}

interface IOrder { void make(); }
interface IReceipt { void print(); }

以下是我目前使用API​​的方式:

public static void main(String[] args) {
    VisibleClass x = new VisibleClass();
    x.makeOrder().printReceipt();
}

这是一个好方法吗?可以使用更好的方法吗?

*编辑:另外,我应该补充一点,VisibleClass将实现隐藏类的所有方法。

3 个答案:

答案 0 :(得分:1)

你的方法非常好。这里有一些建议:

1将类成员类型更改为其接口,如“程序到接口,而不是实现”原则:

public class VisibleClass {
    private IOrder order;
    private IReceipt receipt;

2您真的需要在makeOrderprintReceipt方法中检查班级类型吗?在null检查后创建实例似乎足够了:

public VisibleClass makeOrder() {
    if (null == order)
        order = new OrderClass();

    order.make();
    return this;
}

public VisibleClass printReceipt() {
    if (null == receipt)
        receipt = new ReceiptClass();

    receipt.print();
    return this;
}

3此方法在单个线程调用VisibleClass的方法之前有效。如果您要将其放在多线程程序中,则应确保每个OrderClassReceiptClass只有一个实例。有三种方法可以遵循:

一个。在构造函数中创建OrderClassReceiptClass的实例,并使VisibleClass单例。

湾制作OrderClassReceiptClass单身并删除new行。

℃。使用synchronizedmakeOrder方法中的printReceipt块创建实例。

答案 1 :(得分:0)

您可以尝试使用Facade Design pattern

或者可以尝试使用Decorator Pattern

答案 2 :(得分:0)

  

一个可见类使用许多隐藏类

不要对业务类这样做。流畅的语法非常适合配置等,但不适用于普通的业务代码。

原因是类本身失去对其状态的控制,这可能使其处于不一致状态(即产生错误结果)。

甚至有一个名为Law of Demeter的原则就是这样。

如果您的业务要求应在新订单上打印收据,则应将其作为退货值返回。

var receipt = visibleClass.makeOrder();

至于使用实体/业务类的接口,为什么这样做?你为什么要抽象那些?通常没有任何其他依赖项或不同类型的实现。