1. 单例模式
定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式
特点:1. 单例类只有一个实例对象;
2. 该单例对象必须由单例类自行创建;
3. 单例类对外提供一个访问该单例的全局访问点。
优点: 可以保证内存里只有一个实例,减少了内存的开销和占用。设置全局访问点,可以优化和共享资源的访问。
缺点: 一般没有接口,扩展困难。在并发测试中,单例模式不利于代码调试。
结构:通过将构造函数私有来避免外部类调用从而生成多个实例。然后定义一个静态私有实例,并向外提供一个静态的公有函数用于创建或获取该静态私有实例。
写法一:懒汉式
该模式的特点是类加载时没有生成单例,只有当第一次调用 newlnstance 方法时才去创建这个单例。
/**
* 懒汉式单例 特点,类加载时没有生成单例,只有当第一次调用的时候才会创建 问题: 如果多线程执行,那就保证不了对象唯一了,因为各个线程平行进行
*/
class Single {
private static Single single;// 方法是静态的
private Single() {// 私有化构造器
}
public static Single newInstance() {// 方法需要对象才能调用,但这个是一个创建对象的方法。所以静态化通过类名调用进而创建对象
// 要保证只创建一个对象,加判断
if (single == null) {
single = new Single();
}
return single;
}
}
ublic class SingletonDemo {
public static void main(String[] args) {
Single s1 = Single.newInstance()();
Single s2 = Single.newInstance()();
System.out.println(s1 == s2);// true
}
}
写法二,饿汉式
该模式的特点是类一旦加载就创建一个单例,保证在调用 newInstance 方法之前单例已经存在了。
class Single3{
private static Single3 single = new Single3();
private Single3() {}
public static Single3 newInstance() {
return single;
}
}
写法三,多例模式
这种方法通过预先写一个用来装Multiton实例的ArrayList列表,然后通过一个静态构造块和一个静态方法来实现生成有限个实例的效果
二. 建造者模式
定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。
它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。
优点:
- 封装性好,构建和表示分离。
- 扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
- 客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。
建造者(Builder)模式和工厂模式的关注点不同:建造者模式注重零部件的组装过程,而工厂方法模式更注重零部件的创建过程,但两者可以结合使用。
成员结构:
- 产品(Product):它是包含了多个组成部分的复杂的对象,由具体的创造者完成另加后由指挥者组装而成
- 抽象建造者(Builder):它是一个包含创建产品各个子部件的方法接口,又具体建造者继承,通常还需要包含一个返回复杂产品的方法
- 具体建造者(Concrete Builder):实现Builder接口,完成各个零部件的具体化的创建方法
- 指挥者(Director):负责调用建造者对象中的部件构造和装配的方法,从而完成复杂对象的创建
具体的代码部分
(1) 产品
class Product{
//将一个产品拆解成三个部分
private String partA;
private String partB;
private String partC;
public void setPartA(String partA)
{
this.partA=partA;
}
public void setPartB(String partB)
{
this.partB=partB;
}
public void setPartC(String partC)
{
this.partC=partC;
}
public void show() {
System.out.println(partA + partB + partC + "并组装完成");
}
}
(2) 抽象建造者
abstract class Builder{//这是一个抽象类
//创建产品对象
protected Product product=new Product();
//创建好三个用于建造零件的抽象方法
public abstract void buildPartA();
public abstract void buildPartB();
public abstract void buildPartC();
//返回产品对象
public Product getResult()
{
return product;
}
}
(3) 具体建造者
public class ConcreteBuilder extends Builder{//继承了抽象建造者
//以下是三个具体的建造方法,负责打造出产品零件
@Override
public void buildPartA()
{
product.setPartA("建造 PartA");//调用set方法
}
@Override
public void buildPartB()
{
product.setPartB("建造 PartB");
}
@Override
public void buildPartC()
{
product.setPartC("建造 PartC");
}
}
(4) 指挥者
class Director
{
private Builder builder;
//有参构造器,参数就是
public Director(Builder builder)
{
this.builder=builder;
}
//产品构建与组装方法
public Product construct(){
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return builder.getResult();//让方法返回一个产品实例从而让产品类接收
}
}
(5) 客户调用类。
public class Client{
public static void main(String[] args)
{
Builder builder=new ConcreteBuilder();//使用多态创建对象,好让之后的指挥者调用builder方法时运行的是子类方法
Director director=new Director(builder);//通过构造器让指挥者获得builder实例
Product product=director.construct();//调用指挥者拿到的builder实例的子类ConcreteBuilder中的方法,建造零件
product.show();
}
}
(6)运行结果
建造PartA 建造PartB 建造PartC 并组装完成
要点:零件的制造是发生在指挥者调用抽象建造者的建造方法(实际运行的是其子类ConcreteBuilder的方法)的时候。在指挥者调用完三个零件的建造方法后,调用抽象建造着的getResult方法,拿到一个产品对象,将三个零件赋予了对象,完成组装过程。