java二十三种设计模式(一)——创建型(五种)

276 阅读6分钟

java设计模式共23种,分为创建型(5种)、行为型(11种)、结构型(7种)三大类。

此篇浅谈创建型的5种:工厂方法、抽象工厂、建造者、单例、原型。

直奔主题:

1、工厂方法模式(Factory Method Pattern)

简介:核心是封装不变部分,提取善变部分作为独立类,通过依赖注入达到解耦、复用和后期维护拓展的目的。
该模式定义创建产品的抽象工厂,不再负责产品创建,仅负责提供具体工厂必须实现的接口。

核心结构:抽象工厂;具体工厂;抽象产品;具体产品。
优点:可使系统不修改原具体工厂的情况下拓展新产品;即遵循开闭原则,实现了可扩展。

角色:
抽象工厂(Creator)角色:具体工厂对象接口
具体工厂(Concrete Creator)角色:实现抽象工厂接口
抽象产品(Product)角色:具体产品对象的共同父类或共有接口
具体产品(Concrete Product)角色:实现抽象产品接口。由具体工厂创建,且一一对应。

示例:

public interface IPhone{//抽象产品
    void customFun();//产品共有行为
}

public interface IPhoneFactory{//抽象工厂
    IPhone createPhone();
}

public class XiaoMiPhone implements IPhone{//具体产品
    @Override
    public void customFun() {}//自行实现
}

public class XiaoMiPhoneFactory implements IPhoneFactory{//具体工厂
    @Override
    public MobilePhone createPhone(){
        return new XiaoMiPhone();
    }
}

main(){
    //自行扩展其他机型
    IPhoneFactory xioamiFactory = new XiaoMiPhoneFactory();
    IPhone xiaomiPhone = xioamiFactory.createPhone();
    xiaomiPhone.customFun(); 
}

应用场景:

1、对某产品,调用者知道应该使用哪个具体工厂。如Java Collection中的iterator() 方法

2、只是需要一种产品,不关心哪个具体工厂生产,最终调用哪个具体工厂的决定权在生产者一方,这个决策过程
对使用者透明。(个人理解:项目框架抽象业务逻辑时可用,如某处需要调用IPhone.call()且并不关心是哪个
牌子时可用)。

注:该模式常与简单工厂模式对比,此处不再赘述,自行查阅。

2、抽象工厂模式(Abstract Factory Pattern)

定义:为一组相关或相互依赖的对象提供一个接口,无需指定他们的具体类。
简单说,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结构。

优点:功能分离,有利于产品的一致性(工厂行为规范),针对多个产品。

该模式过于简单,直接上代码:

public interface IPhone{//产品类型1
    void customPhoneFun();//产品1共有行为
}

public interface IComputer{//产品类型2
    void customComputerFun();//产品2共有行为
}

public interface IElectronicFactory{//抽象工厂
    IPhone createPhone();
    IComputer createComputer();
}

public class XiaoMiPhone implements IPhone{//实现
    @Override
    public void customPhoneFun(){}//自行定义
}

public class XiaoMiComputer implements IComputer{//实现
    @Override
    public void customComputerFun(){}//自行定义
}

public class XiaoMiFactory implements IElectronicFactory{//实现
    @Override
    public IPhone createPhone(){
        return new XiaoMiPhone();
    }
    
    @Override
    public IComputer createComputer(){
        return new XiaoMiComputer();
    }
}

main(){
    //自行扩展友商工厂
    IElectronicFactory xioamiFactory = new XiaoMiFactory();
    IPhone xiaomiPhone = xioamiFactory.createPhone();
    xiaomiPhone.customPhoneFun(); 
    IComputer xiaomiComputer = xioamiFactory.createComputer();
    xiaomiComputer.customComputerFun(); 
}

与其他设计模式配合:

1、具体工厂类可用单例实现;
2、工厂的工厂,即使用简单工厂、工厂方法、抽象工厂模式实现工厂的创建。

3、建造者模式(Builder Pattern)

定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
适用场景:复杂对象,建造顺序稳定,对象内部的构建需要发生变化。

角色:
Builder(建造者):创建产品对象需要指定各个部件的抽象接口。
ConcreteBuilder:实现Builder的接口,定义它所创建的表示,并提供一个检索产品的接口。
Director(指挥者):构造一个使用Builder接口的对象。
Product:被构造的复杂产品对象。ConcreteBuilder创建其各组件并定义装配过程,
    即定义组成部件的类和将这些部件装配成最终产品的接口。

示例:

public class XiaoMiPhone{//复杂产品
    private String cpu;
    private String battery;
    private String store;
    set()//省略get/set方法
    get()
}

public interface IPhoneBuilder{//建造者builder抽象
    void buildCpu();
    void buildBattery();
    void buildStore();
    XiaoMiPhone buildPhone();
}

public class Mi9Builder implements IPhoneBuilder{//建造者builder实现
    XiaoMiPhone mi9Phone;
    public Mi9Builder{
        mi9Phone = new XiaoMiPhone();
    }
    public void buildCpu(){
        mi9Phone.setCpu("骁龙855");
    }
    public void buildBattery(){
        mi9Phone.setBattery("3300mA");
    }
    public void buildStore(){
        mi9Phone.setStore("8+256g");
    }
    public XiaoMiPhone buildPhone(){
        return mi9Phone;
    }
}

public class XiaoMiDirector{//指挥者director
	public XiaoMiPhone constructPhone(IPhoneBuilder pb){
    	    pb.buildCpu();
    	    pb.buildBattery();
    	    pb.buildStore();
    	    return pb.buildPhone();
	}
}

main(){
    XiaoMiDirector md = new XiaoMiDirector();
    XiaoMiPhone mi9Phone = md.constructPhone(new Mi9Builder());
}

该模式实战中可演化多种形式:

1、省略建造者接口:如果系统中只需要一个具体的建造者,可省略抽象建造者。
2、省略建造者接口+指导者角色:即Builder扮演建造者和指导者双重角色。

Dialog的建造者模式:Dialog即复杂产品,Builder扮演建造者,使用者(即程序员)扮演指导者角色。

4、原型模式(Prototype Pattern)

定义:用原型实例指定创建对象的种类,并通过拷贝原型对象创建新的对象。
设计目的:通过复制原型对象来获得与原型对象一模一样的对象实例。
工作原理:将原型对象传给副本对象,这个副本对象通过拷贝原型对象进行创建。
适用场景:某些结构复杂的对象的创建,这些对象面临剧烈变化,但拥有比较稳定一致的接口。

示例:

public interface ICopy{
	ICopy copy();
}

public class Mi9Phone implements ICopy{
	String cpu;
	int battery;
	int store;
	
	@Override
	public ICopy copy(){
		Mi9Phone mi9copy = new Mi9Phone();
		mi9copy.cpu = this.cpu;
		mi9copy.battery = this.battery;
		mi9copy.store = this.store;
		return mi9copy;
	}
}

main(){
	ICopy mi9Phone = new Mi9Phone();
	ICopy mi9Copy = mi9Phone.copy();
}

以上代码仅供理解原型模式,该模式实际应用请自行查阅java的cloneable接口。

另:java的深浅复制请自行百度,此处不表。

5、单例模式(Singleton Pattern)

定义:一个类仅有一个实例,并提供一个访问它的全局访问点。
设计目的:使得类的一个对象成为系统中唯一实例。
原理:“阻止”所有想要生成对象的访问,只允许生成对象类的唯一实例。

构建方式:
饿汉式:单例对象在类装载时构建
懒汉式:单例对象在第一次被使用时创建

示例:

public class HungrySingle{//饿汉式
	private static HungrySingle hs = new HungrySingle();

	public static HungrySingle getInstance(){
		return hs;
	}
}

public class LazySingle{//懒汉式
	private static LazySingle ls =null;
	public static LazySingle getInstance(){
		if(ls==null){
			synchronized(LazySingle.class){
				if(ls==null){
					ls = new LazySingle();
				}	
			}
		}
		return ls;
	}
}

main(){
	HungrySingle hs = HungrySingle.getInstance();
	LazySingle ls = LazySingle.getInstance();
}

注意:由于单例模式生命周期与app等同,所以请不要滥用,且小心内存泄漏。

另:java原子性请自行深究,涉及volatile关键字,Atomic,synchronized,lock等。

6、个人总结

总结:

综上,个人对创建型5种设计模式理解:
共同点:将new对象过程封装,隐藏对象构造细节。
不同点:
1、工厂模式针对同一族产品;
2、建造者模式针对复杂且部件稳定对象;
3、原型模式针对对象复制;
4、单例模式针对对象全局唯一。

至此,创建型5种设计模式已完结,下篇更新行为型设计模式。

注:笔者水平有限,以上均为个人理解,仅为抛砖引玉。如有疏误,还请各位不吝赐教。

资料来源:

百度百科;
大话设计模式;
其他相关博客;
以及个人理解。