创建型模式的特点和分类

  |   0 评论   |   198 浏览

关注点

怎样创建对象?主要特点就是"将对象的创建与使用分离",降低系统耦合性,不关注对象创建的细节。对象创建由工厂来完成。就像商品购物, 无需关心生产

创建型模式:

  • 单例模式 (Singleton) 生成一个对象,提供全局访问点
  • 原型模式(Prototype) 将一个对象作为原型,通过复制或克隆多个和原型类似的新实例
  • 工厂方法模式(FactoryMethod) 定义一个创建产品的接口,由子类决定生产什么产品
  • 抽象工厂模式(AbstractFactory)提供创建产品族的,每个子类可以生产一系列的相关产品
  • 建造者模式(Builder) 将一个复杂的对象分解成多个相对简单的部分,根据需要创建,最后构建复杂的对象

除了工厂方法模式属于类创建模式, 其他的都属于对象创建型模式

单例模式

节省内存资源,保证数据一致性, 某些类只能创建一个实例,这就是所谓的单例模式

单例模式的定义和特点

一个类只有一个实例,且该类能自行创建这个实例的一种模式

  1. 单例类只有一个实例对象
  2. 单例对象必须要由单例类来创建
  3. 单例类对外提供一个访问该单例的全局访问点

单例模式的结构和实现

  1. 单例模式的结构

主要角色

  • 单例类:包含一个实例且能自行创建这个实例的类
  • 访问类:使用单例的类

单例模式的实现

有八种方式,建议使用静态内部类方式和枚举方式

应用场景

  • 某类只要求生成一个对象。 如一个班的班长,每个人的身份证号
  • 当对象需要被共享的场合。如配置对象, 数据库连接池等。
  • 当类需要频繁创建和销毁的时候。 如多线程连接池,网络连接池等。

扩展

单例模式可以扩展为有限的多例模式,这种模式可以生成有限的对象保存在arraylist中,客户随机获取

有限的多例模式的结构图

原型模式

定义和特点

用一个已经创建的对象做为原型,通过复制该对象来创建一个和原型相同或相似的新对象。这种方式创建对象高效

结构和实现

java提供clone()的方法,实现原型模式很简单

  1. 模式的结构
  • 抽象原型类:规定了原型对象必须要实现的接口
  • 具体原型类:实现抽象原型类的clone()方法,它是可被复制的对象
  • 访问类:使用具体原型类中的clone()方法来复制新的对象

原型结构图

  1. 模式的实现
  • 浅克隆

    java中提供的浅克隆clone()方法,具体的原型类只要实现了Cloneable接口就可实现对象的浅克隆,这里的Cloneable接口就是抽象原型类。

    //具体原型类
    class Realizetype implements Cloneable
    {
        Realizetype()
        {
            System.out.println("具体原型创建成功!");
        }
        public Object clone() throws CloneNotSupportedException
        {
            System.out.println("具体原型复制成功!");
            return (Realizetype)super.clone();
        }
    }
    //原型模式的测试类
    public class PrototypeTest
    {
        public static void main(String[] args)throws CloneNotSupportedException
        {
            Realizetype obj1=new Realizetype();
            Realizetype obj2=(Realizetype)obj1.clone();
            System.out.println("obj1==obj2?"+(obj1==obj2));
        }
    }
  • 深克隆

应用实例

  1. 复制自己
  2. 相似对象的复制 (复制自己,修改部分属性)

应用场景

  • 对象之间相同或相似,只有个别属性不同
  • 对象创建过程比较麻烦,但复制简单

扩展

可以扩展为带原型管理器的原型模式,在原型模式上增加一个原型管理器类(PrototypeManager),用HashMap保存多个复制原型,通过get(id)方法获取复制的原型。

工厂方法模式

定义和特点

定义一个创建产品对象的工厂接口,将产品对象实际创建工作推迟具体子工厂类当中。满足"创建和使用分离"的特点

被创建对象的成为"产品",创建产品的对象成为"工厂"。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫做"简单工厂模式",不属于23种经典设计模式,缺点就是增加新产品的时候, 会违背"开闭原则"

工厂方法模式是对简单工厂模式进一步抽象化,满足开闭原则

优点:

  • 用户只需要知道工厂的名称就可得到所要的产品,无须知道产品的具体创建过程。
  • 系统增加新产品的时候,只需要增加具体的产品类和对应的具体工厂类,满足开闭原则

缺点:

  • 增加一个产品的时候,要增加具体的产品类和一个对应的具体工厂类,增加了系统的复杂度

结构和实现

主要角色

  • 抽象工厂:提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法newProduct()来创建产品
  • 具体工厂:主要实现抽象工厂的抽象方法,完成具体产品的创建
  • 抽象产品:定义产品的规范,描述了产品的主要特性和功能
  • 具体产品:实现了抽象产品定义的接口,由具体工厂来创建同具体工厂一一对应

工厂方法模式的结构图

模式的实现

package FactoryMethod;
public class AbstractFactoryTest
{
    public static void main(String[] args)
    {
        try
        {
            Product a;
            AbstractFactory af;
            af=(AbstractFactory) ReadXML1.getObject();
            a=af.newProduct();
            a.show();
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
    }
}
//抽象产品:提供了产品的接口
interface Product
{
    public void show();
}
//具体产品1:实现抽象产品中的抽象方法
class ConcreteProduct1 implements Product
{
    public void show()
    {
        System.out.println("具体产品1显示...");
    }
}
//具体产品2:实现抽象产品中的抽象方法
class ConcreteProduct2 implements Product
{
    public void show()
    {
        System.out.println("具体产品2显示...");
    }
}
//抽象工厂:提供了厂品的生成方法
interface AbstractFactory
{
    public Product newProduct();
}
//具体工厂1:实现了厂品的生成方法
class ConcreteFactory1 implements AbstractFactory
{
    public Product newProduct()
    {
        System.out.println("具体工厂1生成-->具体产品1...");
        return new ConcreteProduct1();
    }
}
//具体工厂2:实现了厂品的生成方法
class ConcreteFactory2 implements AbstractFactory
{
    public Product newProduct()
    {
        System.out.println("具体工厂2生成-->具体产品2...");
        return new ConcreteProduct2();
    }
}
package FactoryMethod;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
class ReadXML1
{
    //该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
    public static Object getObject()
    {
        try
        {
            //创建文档对象
            DocumentBuilderFactory dFactory=DocumentBuilderFactory.newInstance();
            DocumentBuilder builder=dFactory.newDocumentBuilder();
            Document doc;                           
            doc=builder.parse(new File("src/FactoryMethod/config1.xml"));        
            //获取包含类名的文本节点
            NodeList nl=doc.getElementsByTagName("className");
            Node classNode=nl.item(0).getFirstChild();
            String cName="FactoryMethod."+classNode.getNodeValue();
            //System.out.println("新类名:"+cName);
            //通过类名生成实例对象并将其返回
            Class<?> c=Class.forName(cName);
              Object obj=c.newInstance();
            return obj;
         }  
         catch(Exception e)
         {
                   e.printStackTrace();
                   return null;
         }
    }
}

Config1.xmln内容

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<className>ConcreteFactory1</className>
</config>

应用场景

  1. 客户只知道创建产品的工厂名,而不知道具体产品名
  2. 创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口
  3. 客户不关心创建产品的细节,只关心产品的品牌

扩展

当需要生成的产品不多且不会增加,一个具体的工厂类就可以完成任务时,可删除抽象工厂类,这是工厂方法模式退化成简单工厂模式。

简单工厂模式的结构图

评论

发表评论

validate