创建型模式(一)

2020-06-02 09:47:40 浏览数 (1)

在我的公众号中,关于七种结构型设计模式已经全部讲完了:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。而十一种行为型模式我们说了4种:策略模式、模板方法模式、观察者模式、责任链模式。关于创建型设计模式我们还没有聊过,所以今天我们来聊一聊创建型模式,创建型模式一共有五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。今天我们先回顾一下工厂方法模式和抽象工厂模式。

先了解一些简单的概念:

工厂方法模式(Factory Pattern)中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。

那么首先我们来看工厂方法模式:

概念上说创建对象时不会对客户端暴露创建的逻辑,这样的好处很明显,你不暴漏创建的逻辑,客户端就不用去关心你的创建逻辑了,就可以直接调用了,同时扩展性也高(为什么扩展性高我们待会看)。其实工厂方法模式就好像小商店和大广场的感觉一样,如果你住在郊区:你买菜要去菜市场,你买零食要去小商店,反正你要去很多地方,但是如果你住在购物广场旁边那就不一样了,买啥都去这里面溜达一下,大多数都能找到。所以说如果没有工厂方法模式,你创建对象首先要知道这个对象是干嘛的,不然就好像去菜市场买家具一样,但是有了工厂方法模式,你只需要知道你要创建哪一类对象就可以了。

那如何来实现一个工厂方法模式呢?既然是工厂,那首先这个工厂里面要有一些东西,这些东西肯定就是对象了,而且这些对象都有一个公共的接口(概念上说通过共同的接口只想新创建的对象)。所以我们要先定义一个公共的接口:

代码语言:javascript复制
interface TopInter{
代码语言:javascript复制
    void Common();
}
代码语言:javascript复制
 有了接口我们再去搞几个对象出来:
代码语言:javascript复制


class C1 implements TopInter{

    @Override
    public void Common() {
        System.out.println("我是类1");
    }
}

class C2 implements TopInter{

    @Override
    public void Common() {
        System.out.println("我是类2");
    }
}

有了公共的接口,有了对象,那工厂就该出来了吧。

代码语言:javascript复制
class FactoryTop {
    public TopInter getShape(String type) {
        if (type == null) {
            return null;
        }
        if (type.equalsIgnoreCase("家具")) {
            return new C1();
        } else if (type.equalsIgnoreCase("零食")) {
            return new C2();
        }
        return null;
    }
}

看懂了吗?有了工厂方法模式,我们每次建了新的类之后,只需要在这个方法中加入一个判断返回新的实例就可以了,而不用像以往一样,自己挨个的创建类,还有可能创建错误。这就是我们开始所说容易扩展。

抽象工厂模式:

抽象工厂模式,名字和工厂方法模式很像,都和工厂有关,那么他们有什么区别呢?抽象工厂模式,是对工厂进行抽象,也就是说

他是创建工厂的的工厂。就好比一个总部的酒厂下面有很多分部的酒厂,这些分部的酒厂创建不同型号的酒。这个就是抽象工厂模式。概念上来说:

工厂方法创建 "一种" 产品,他的着重点在于"怎么创建",也就是说如果你开发,你的大量代码很可能围绕着这种产品的构造,初始化这些细节上面。也因为如此,类似的产品之间有很多可以复用的特征,所以会和模版方法相随。 抽象工厂需要创建一些列产品,着重点在于"创建哪些"产品上,也就是说,如果你开发,你的主要任务是划分不同差异的产品线,并且尽量保持每条产品线接口一致,从而可以从同一个抽象工厂继承。

如果我描述的还是很晦涩,那么我希望下面这个例子能帮到你:

在上面我们创建了一个TopInter的接口,他的下面有两个类分别是C1和C2。现在我们再创建一个接口SecInter和他的两个实现类S1和S2

代码语言:javascript复制
interface SecInter{
    void write();
}
class S1 implements SecInter{

    @Override
    public void write() {
        System.out.println("我是S1");
    }
}

class S2 implements SecInter{

    @Override
    public void write() {
        System.out.println("我是S2");
    }
}

然后我们来写抽象工厂类:

代码语言:javascript复制
abstract class FactoryTop {
    abstract TopInter getTop();

    abstract SecInter getSec();

}

既然抽象工厂是创建工厂的工厂,那么实现这个抽象类的类肯定也是工厂,只不过这些工厂所做的事情有所区别:

代码语言:javascript复制


class Top extends FactoryTop{


    @Override
    TopInter getTop(String s) {
        if (s=="家具"){
            return new C1();
        }else {
            return new C2();
        }
    }

    @Override
    SecInter getSec(String s) {
        return null;
    }
}


class Sec extends FactoryTop{


    @Override
    TopInter getTop(String s) {
        return null;
    }

    @Override
    SecInter getSec(String s) {
        if (s=="82年拉菲"){
            return new S1();
        }else {
            return new S2();
        }
    }
}

抽象工厂类有了,工厂类也有了,那么我们怎么去获取工厂呢?这就需要我们提供一个生产商,让他们给你生产出来你想要的工厂:

代码语言:javascript复制
public class FactoryProducer {
    public static FactoryTop getFactory(String choice){
        if(choice.equalsIgnoreCase("top")){
            return new Top();
        } else if(choice.equalsIgnoreCase("sec")){
            return new Sec();
        }
        return null;
    }
}

0 人点赞