设计模式(三)--创建类模式

1.书本链接:前言 · 设计模式之禅(第2版) · 看云

本文引用博客:https://blog.csdn.net/zhengzhb/article/category/926691

1.单例模式

定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

要素

  • 私有的构造方法:private Singleton(){}
  • 指向自己实例的私有静态引用:private static Singleton singleton = new Singleton();//这里有new是饿汉,没new是懒汉
  • 以自己实例为返回值的静态的公有的方法:public static Singleton getInstance(){return singleton;}

注意:在java中,饿汉式单例要优于懒汉式单例。C++中则一般使用懒汉式(延迟加载)单例。懒汉式的单例模式是线程不安全的,因为要动态的new:线程安全的单例模式_用户1965325431_新浪博客,在那个方法前面加一个Synchronized就OK了,同步的代价必然会一定程度的使程序的并发度降低,上面的写法一方面实现了Lazy-Load,另一个方面也做到了并发度很好的线程安全,但初始化是需要耗费时间的,但是这个对象的地址其实已经存在了。此时线程B也执行到了第九行,它判断不为空,于是直接跳到15行得到了这个对象。但是,这个对象还没有被完整的初始化!这种方法使用内部类来做到延迟加载对象,在初始化这个内部类的时候,JLS(Java Language Sepcification)会保证这个类的线程安全。这种写法最大的美在于,完全使用了Java虚拟机的机制进行同步保证,没有一个同步的关键字
应用:有上限的多例模式,实例和实例变量。当然,如果考虑到线程安全问题可以使用Vector来代替。

2.工厂方法模式

定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
用法

  1. 缩小为简单工厂模式:一个模块仅需要一个工厂类,没有必要把它产生出来,使用静态的方法就可以了,去掉了AbstractHumanFactory抽象类,同时把createHuman方法设置为静态类型,简化了类的创建过程,变更的源码仅仅是HumanFactory和NvWa类:Human whiteHuman = HumanFactory.createHuman(WhiteHuman.class);
  2. 延迟初始化:通过定义一个Map容器,容纳所有产生的对象,如果在Map容器中已经有的对象,则直接取出返回;如果没有,则根据需要的类型产生一个对象并放入到Map容器中,限制某一个产品类的最大实例化数量,可以通过判断Map中已有的对象数量来实现

举例:女娲造人,bufferRead(new fileRead(new file())),解耦成工厂,
工厂是需要编写格外的代码类,一般简单的就可以,封装了new.

3.抽象工厂模式

定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

四个要素工厂接口。工厂接口是工厂方法模式的核心,与调用者直接交互用来提供产品。在实际编程中,有时候也会使用一个抽象类来作为与调用者交互的接口,其本质上是一样的。工厂实现。在编程中,工厂实现决定如何实例化产品,是实现扩展的途径,需要有多少种产品,就需要有多少个具体的工厂实现。产品接口。产品接口的主要目的是定义产品的规范,所有的产品实现都必须遵循产品接口定义的规范。产品接口是调用者最为关心的,产品接口定义的优劣直接决定了调用者代码的稳定性。同样,产品接口也可以用抽象类来代替,但要注意最好不要违反里氏替换原则。产品实现。实现产品接口的具体类,决定了产品在客户端中的具体行为。
区别:工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。在抽象工厂模式中,有一个产品族的概念:所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构
举例:2.0排量两厢车和2.4排量两厢车属于同一个等级结构,2.0排量三厢车和2.4排量三厢车属于另一个等级结构;而2.0排量两厢车和2.0排量三厢车属于同一个产品族,2.4排量两厢车和2.4排量三厢车属于另一个产品族。就理解工厂方法模式和抽象工厂模式的区别了,如果工厂的产品全部属于同一个等级结构,则属于工厂方法模式;如果工厂的产品来自多个等级结构,则属于抽象工厂模式
缺点:产品族扩展非常困难,加一个接口,其他都要加。
用法:一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式,需要在三个不同平台(Windows、Linux、Android(Google发布的智能终端操作系统))上运行

4.建造者模式

定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
四个要素:产品类:一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量。在本类图中,产品类是一个具体的类,而非抽象类。实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成。抽象建造者:引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现。这样更容易扩展。一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品。建造者:实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。导演类:负责调用适当的建造者来组建产品,导演类一般不与产品类发生依赖关系,与导演类直接交互的是建造者类。一般来说,导演类被用来封装程序中易变的部分。
比较:与工厂模式相比,建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的类——导演类
例子:顺序直接告诉建造者,由建造者来建造:造车演化出导演类
构造函数默认值里面,最终会调到一个最全的构造,前提都用默认值
默认构造->set->封装set成建造者类,抽象固定(隔离)->Director调用builder方法,用组合

// 太随意, 用户并不知道有哪些方法
class KFC
{
private:
    /* data */
public:
    KFC(string hamburger, string chips) {}
    ~KFC() {}

    void setCola() {}
    void setPizza() {}
};

int main ()
{
    KFC *kfc = new KFC("ham", "chip");
    kfc->setCola();
    kfc->setPizza();
    return 0;
}

class Builder
{
private:
    /* data */
protected:
    virtual void setChicken() = 0;
    virtual void setChips() = 0;
    virtual KFC *getKFC() = 0;
};

class ConcreteA : public Builder
{
public:
    ConcreteA()
    {
        kfc = new KFC("ham", "chip");
    }

protected:
    virtual void setChicken() {
        kfc->setCola();
    }
    virtual void setChips() {
        printf("A not have chips\n");
    }
    virtual KFC *getKFC() {
        return kfc;
    }

private:
    KFC *kfc;
};

class Director
{
private:
    /* data */
public:
    KFC *build(Builder *builder)
    {
        builder->setChicken();
        return builder->getKFC();
    }
};

int main ()
{
    Builder A = new ConcreteA();
    KFC k = new Director->build(A);
    return 0;
}

5.原型模式 

定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
用法:原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototyp;Prototype类需要具备以下两个条件:
实现Cloneable接口;重写Object类中的clone方法
场景:简化对象的创建,创建对象比直接new一个对象在性能上要好的多,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能提高很多
注意:单例模式与原型模式是冲突的,在使用时要特别注意,Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝;要使用clone方法,类的成员变量上不要增加final关键字
例子:发骚扰短信,对于c++来说,return new concreateprototype1(*this);

6.创建类模式总结篇

链接创建类模式总结篇_三级小野怪的专栏-CSDN博客
创建类模式主要关注对象的创建过程,将对象的创建过程进行封装,使客户端可以直接得到对象,而不用去关心如何创建对象。创建类模式有5种,分别是:

  • 单例模式:用于得到内存中的唯一对象。
  • 工厂方法模式:用于创建复杂对象。
  • 抽象工厂模式:用于创建一组相关或相互依赖的复杂对象。
  • 建造者模式:用于创建模块化的更加复杂的对象。
  • 原型模式:用于得到一个对象的拷贝

本质:创建类模式本质上都是对对象的创建过程进行封装
好处:不会增加对象间的耦合,又可以最大限度的减小客户端的负担;客户端要求的只是一个抽象的类型,具体返回什么样的对象,由创建者来决定,创建者可以对创建的过程进行优化,例如在特定条件下,如果使用单例模式或者是使用原型模式,都可以优化系统的性能
对比:如果需要详细关注一个产品部件的生产、安装步骤,则选择建造者,否则选择工厂方法模式。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值