首页 技术 利用语言特性改进代码

利用语言特性改进代码

0 1

也许这个标题有点大,但是我是想利用这篇文章来强调一个事实:设计模式不是一层不变的,它需要根据具体问题、具体语言做出具体的实现。设计模式看起来是一种代码模板,但实际并不是。也许有人说,最好的设计模式就是没有模式,这句话其实也算是说到了点子上。所谓设计模式,其实就是能够让我们的代码能够更好的工作——运行起来,或者是让别的开发者更方便使用。

举一个例子:简单工厂模式。这个设计模式并不是 GoF 提出的 23 种设计模式之一,但是在实际编码中经常会遇到。简单来说,简单工厂模式就是使用一个 static 方法,通过一定的标记位的区分,返回不同的产品实例。为了清楚起见,我们先来看一段 Java 的实现:

abstract class Product {
}

class ProductA extends Product {
    public ProductA() {
    }
}

class ProductB extends Product {
    public ProductB() {
    }
}

enum ProductType {
    A, B
}

class ProductFactory {

    public static Product createProduct(ProductType type) {
        switch(type) {
        case A:
            return new ProductA();
        case B:
            return new ProductB();
        default:
            return null;
        }
    }
}

// ...

Product p = ProductFactory.createProduct(ProductType.A);

这段代码很清楚:ProductFactory类的createProduct()方法充当了简单工厂方法,根据实际传入的参数返回具体的产品实例。

我们可以很清楚地看到简单工厂模式的缺陷:工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配的原则。它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类,增加更多的 case 语句。

下面,我们使用 C++ 语言,也要实现这么一个简单工厂模式:

class Product
{
};

class ProductA : public Product
{
};

class ProductB : public Product
{
};

enum ProductType
{
    A, B
};

class ProductFactory
{
public:
    static Product* createProduct(ProductType type);
};

Product* ProductFactory::createProduct(ProductType type)
{
    switch(type)
    {
    case A:
        return new ProductA;
    case B:
        return new ProductB;
    default:
        return 0;
    }
}

// ...
Product *p = ProductFactory::createProduct(A);

这段代码看上去和前面的 Java 代码没有什么区别。实际上,它就是没有什么区别,就像是把 Java 代码直接翻译成了 C++ 代码。这样的话,Java 代码存在的问题,同样全部到了 C++ 代码中:如果又有了一个ProductC,那就再修改ProductFactory类,再增加一个 case 吧!

有没有更好的方式呢?别忘了,我们使用的是 C++!两种不同的语言,却用了几乎一样的代码,难道不觉得难过么?C++ 比 Java 多了宏,比 Java 多了模板(哦哦,直接无视 Java 的模板吧!我们就事论事,就当没有吧!;-P)。我们不能利用 C++ 特有的语言机制,来让简单工程模式更方便使用吗?于是,我们想到了函数模板:

// ...

class ProductFactory
{
public:
    template<class T>
    static Product * createProduct()
    {
        return new T;
    }
}

// ...
Product *p = ProductFactory::createProduct<ProductA>();

这下如何?增加新的类,也无需改变任何已有代码。因为我们利用 C++ 的函数模板特性,编写了一个函数模板,每次只需将我们需要生成的类传入,就可以直接获得该类实例的指针。虽然我们按照简单工厂模式编写了代码,却解决了简单工厂模式的一些缺陷。

上面的例子很简单,却能够清楚反应我所要表达的内容。在应用设计模式,以及其它代码的时候,请注意语言特有的特性。我们编写代码,并不是要使用所有语言的最大公约数,而是要充分利用语言特性,方便我们的代码编写。

发表评论

关于我

devbean

devbean

豆子,生于山东,定居南京。毕业于山东大学软件工程专业。软件工程师,主要关注于 Qt、Angular 等界面技术。

主题 Salodad 由 PenciDesign 提供 | 静态文件存储由又拍云存储提供 | 苏ICP备13027999号-2