创建型模式:用户创建对象。
- 工厂方法模式:Factory Method,定义一个用于创建对象的接口,让子类决定将哪一个类实例化。使一个类的实例化延迟到其子类。
- 抽象工厂模式:Abstract Factory,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
- 建造者模式:Builder Factory,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。分步骤构建一个复杂对象,内容不一样,步骤一样。
- 原型模式:Prototype,用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。
- 单例模式:Singleton,保证一个类仅有一个实例,并提供一个访问它的全局访问点。
1.工厂方法模式:
是对简单工厂模式的延伸,简单工厂模式,又称作静态工厂方法模式,有三个角色:
- 工厂类(Creator),负责根据参数创建实例;
- 抽象产品类(Product),所有产品类的父类;
- 具体产品类(ConcreateProduct)。
工厂方法模式,在简单工厂模式上对工厂类也提供一个抽象接口,可以支持多个工厂实现,四个角色:
(1) Product(产品角色):定义产品的接口。
(2) ConcreteProduct(真实的产品):实现接口的Product的类。
(3) Creator(工厂角色):声明工厂方法(FactoryMethod),返回一个产品。
(4) ConcreteCreator(真实的工厂):实现FactoryMethod工厂方法,由客户调用,返回一个产品的实例。
实现
//抽象电子付款类
abstract class EFT {
abstract void process();
}
//具体子类,虚拟支票
class VirtualCheck extends EFT {
@Override
public void process() {
System.out.println("虚拟支票处理中");
}
}
//具体子类,万事达卡
class MasterCard extends EFT {
@Override
public void process() {
System.out.println("万事达卡处理中");
}
}
//简单工厂类
class EFTFactory {
public EFT createEFT(String type) {
switch (type.toLowerCase()) {
case "virtualcheck":
return new VirtualCheck();
case "mastercard":
return new MasterCard();
default:
return null;
}
}
}
//客户应用测试
class Client {
public static void main(String[] args) {
EFT eft;
EFTFactory eftFactory = new EFTFactory();
eft = eftFactory.createEFT("VirtualCheck");
eft.process();
eft = eftFactory.createEFT("MasterCard");
eft.process();
}
}
2.工厂方法模式
//手机接口
interface Mobile {
public void Call();
}
//手机工厂接口
interface MobileFactory {
//工厂方法
Mobile produceMobile();
}
//摩托罗拉手机:实现手机接口
class Motorola implements Mobile {
@Override
public void Call() {
System.out.println("摩托罗拉手机");
}
}
//诺基亚手机:实现手机接口
class Nokia implements Mobile {
@Override
public void Call() {
System.out.println("诺基亚手机");
}
}
//摩托罗拉工厂:实现生产手机的方法,返回摩托罗拉手机
class MotorolaFactory implements MobileFactory {
@Override
public Mobile produceMobile() {
System.out.println("摩托罗拉工厂制造了");
return new Motorola();
}
}
//诺基亚工厂:实现生产手机的方法,返回诺基亚手机
class NokiaFactory implements MobileFactory {
@Override
public Mobile produceMobile() {
System.out.println("诺基亚工厂制造了");
return new Nokia();
}
}
//客户应用测试
class ClientForTest {
public static void main(String[] args) {
MobileFactory mf;
Mobile m;
mf = new MotorolaFactory();
m = mf.produceMobile();
m.Call();
mf = new NokiaFactory();
m = mf.produceMobile();
m.Call();
}
}
2. 抽象工厂模式:
抽象工厂模式在工厂模式上,对两个接口再进行抽象,可以实现一系列工厂和一系列产品实现。
(1) AbstractFactory(抽象工厂):声明生成抽象产品的方法。
(2) ConcreteFactory(具体工厂):执行生成抽象产品的方法,生成一个具体的产品。
(3) AbstractProduct(抽象产品):为一种产品声明接口。
(4) Product(具体产品):定义具体工厂生成的具体产品的对象,实现产品接口。
(5) Client(客户):我们的应用程序,使用抽象产品和抽象工厂生成对象。
3.抽象工厂模式
package com.demo.designpattern;
//定义CPU接口
interface CPU {
String designCPU();
}
//定义AMD类,实现CPU接口
class AMD implements CPU {
@Override
public String designCPU() {
return "Athlon XP 2800+";
}
}
//定义Intel类,实现CPU接口
class Intel implements CPU {
@Override
public String designCPU() {
return "奔腾4 3.2C";
}
}
//定义硬盘接口
interface HardDisc {
String designHardDisc();
}
//定义Maxtor类,实现硬盘接口
class Maxtor implements HardDisc {
@Override
public String designHardDisc() {
return "MaXLine Plus II 200G";
}
}
//定义WestDigit类,实现硬盘接口
class WestDigit implements HardDisc {
@Override
public String designHardDisc() {
return "WD2500JD 250G";
}
}
//定义主板接口,包含参数为CPU的公共方法Attach()
interface MainBoard {
void Attach(CPU cpu) throws Exception;
}
//主板微星MSI865PE,支持Intel的CPU
class MSI865PE implements MainBoard {
@Override
public void Attach(CPU icpu) throws Exception {
if ("com.demo.designpattern.intel".equals(icpu.getClass().getName().toLowerCase())) {
System.out.println("MSI865PE");
} else {
throw new Exception("主板MSI865PE只能配Intel的CPU");
}
}
}
//主板微星MSIK7N2G,支持AMD的CPU
class MSIK7N2G implements MainBoard {
@Override
public void Attach(CPU icpu) throws Exception {
if ("com.demo.designpattern.amd".equals(icpu.getClass().getName().toLowerCase())) {
System.out.println("MSIK7N2G");
} else {
throw new Exception("主板MSIK7N2G只能配AMD的CPU");
}
}
}
//定义抽象电脑工厂类
abstract class ComputerFactory {
protected CPU icpu;
protected HardDisc iHD;
protected MainBoard iMB;
public void Show() {
try {
System.out.println(this.getClass().getName() + "生产的电脑配置");
System.out.println("CPU: " + icpu.designCPU());
System.out.println("HardDisk: " + iHD.designHardDisc());
System.out.print("MainBoard: ");
iMB.Attach(icpu);
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
//抽象电脑工厂类派生类IBM,定义其返回的系列配件产品
class IBM extends ComputerFactory {
public IBM() {
icpu = new Intel();
iHD = new WestDigit();
iMB = new MSI865PE();
}
}
//抽象电脑工厂类派生类DELL,定义其返回的系列配件产品
class Dell extends ComputerFactory {
public Dell() {
icpu = new AMD();
iHD = new Maxtor();
iMB = new MSIK7N2G();
}
}
//客户应用测试
class ClientComputer {
public static void main(String[] args) {
IBM ibm = new IBM();
ibm.Show();
Dell dell = new Dell();
dell.Show();
}
}
3.建造者模式
建造模式是建造者在指导者的协调下,根据组成部分一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象各组成部分的类型和内容就可以构建它们,用户不知道内部的具体构建细节。
(1) Builder(抽象建造者接口)角色:为创建一个Product对象的各个部件指定抽象接口。这个角色用来规范产品对象的各个组成成分的建造。一般而言,此角色独立于应用程序的商业逻辑。
(2) ConcreteBuilder(具体建造者)角色:担任这个角色的是于应用程序紧密相关的类,它们在指导者的调用下创建产品实例。这个角色在实现Build接口提供的方法,定义并明确它所创建的表示,提供一个返回这个产品的接口。从而达到完成产品组装,提供成品的功能。
(3) Director(指导者)角色:调用具体建造者角色以创建产品对象。指导者并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者对象。
(4) Product(产品)角色:待创建的复杂对象。它要包含那些定义组件的类,包括将这些组件装配成产品的接口。
4.建造者模式
import java.util.ArrayList;
//产品建造者接口:规范产品对象各组成成分的建造
interface Builder {
public void buildPartA();
public void buildPartB();
public void buildPartC();
public Product getProduct();
}
//产品角色:待创建的复杂对象
class Product {
private ArrayList<String> parts = new ArrayList<>();
public void add(String part) {
parts.add(part);
}
public void show() {
System.out.println("Product有以下几部分构成:");
for (String s : parts) {
System.out.println(s);
}
}
}
//具体建造者:在指导者的调用下创建产品的各个部分
class Worker implements Builder {
private Product product = new Product();
@Override
public void buildPartA() {
product.add("A部分");
}
@Override
public void buildPartB() {
product.add("B部分");
}
@Override
public void buildPartC() {
product.add("C部分");
}
@Override
public Product getProduct() {
return product;
}
}
//指导者:调用具体建造者建造产品,指导者相当于完成组装功能
class Designer {
public void order(Builder builder) {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
}
}
public class Test {
public static void main(String[] args) {
Designer designer = new Designer();
Builder builder = new Worker();
designer.order(builder);
Product product = builder.getProduct();
product.show();
}
}
4.原型模式
定义的类实现了Cloneable接口,并且重写clone()方法。
(1) 客户(Client)角色:客户端类向原型管理器提出创建对象的请求。
(2) 抽象原型(Prototype)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体原型类所需的接口。在Java中,抽象原型角色通常实现了Cloneable接口。
(3) 具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。
(4) 原型管理器(Prototype Manager)角色:创建具体原型类的对象,并记录每一个被创建的对象。
两个需要理解的概念:
- ==和equals,对于基本类型,只能用==,对于基本类型的封装类以及其他类对象,包括String,==判断地址,equals比较值。
- 浅克隆:被复制的所有变量都与原来对象的值相同,所有修改都指向原来的对象。
深克隆:clone之后产生新的对象,修改指向clone之后的对象。
使用Object.clone()方法只能浅层次的克隆,即只能对那些成员变量是基本类型或String类型的对象进行克隆,对那些成员变量是类类型的对象进行克隆要使用到对象的序列化(例如:List、Map),不然克隆出来的Prototype对象都共享同一个temp实例。
5.原型模式
package com.demo.designpattern;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class Prototype implements Cloneable, Serializable {
private String str;
private Temp temp;
//浅克隆
@Override
public Object clone() throws CloneNotSupportedException {
//调用超类的克隆方法实现浅克隆
Prototype prototype = (Prototype) super.clone();
return prototype;
}
//深克隆
public Object deepClone() throws IOException, ClassNotFoundException {
//把本类的对象串行化地写到字节流中,再串行化地从字节流中读入,实现深克隆
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return oi.readObject();
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public Temp getTemp() {
return temp;
}
public void setTemp(Temp temp) {
this.temp = temp;
}
}
class Temp implements Serializable {
}
public class PrototypeTest {
public static void main(String[] args) throws
CloneNotSupportedException, ClassNotFoundException, IOException {
Prototype pt = new Prototype();
Temp temp = new Temp();
pt.setTemp(temp);
pt.setStr("Hello World");
System.out.println("使用浅克隆方法进行创建对象");
Prototype pt1 = (Prototype) pt.clone();
System.out.println("=============================");
System.out.println("比较pt和pt1的str的值:");
System.out.println(pt.getStr());
System.out.println(pt1.getStr());
System.out.println("修改pt1对象中str的值后,比较pt和pt1的str的值:");
pt1.setStr("你好,世界");
System.out.println(pt.getStr());
System.out.println(pt1.getStr());
System.out.println("============================");
System.out.println("比较pt和pt1中temp对象的值");
System.out.println(pt.getTemp());
System.out.println(pt1.getTemp());
System.out.println("使用深克隆方法进行创建对象");
System.out.println("============================");
pt1 = (Prototype) pt.deepClone();
System.out.println(pt.getTemp());
System.out.println(pt1.getTemp());
}
}
5.单例模式
保证一个类只有一个实例,并提供一个访问它的全局访问点。
饿汉式
- 私有的静态自身类对象
- 私有的构造方法
- 公有的静态获得实例方法getInstance()
懒汉式
- 不会在类初始化的时候就实例化其对象,而是在外部调用公有方法时才判断是否需要实例化。
- 多线程的懒汉式
1.synchronized同步
2.内部类方法
代码:
6.单例模式
饿汉式
public class Singleton{
//私有的静态的自身变量
private static final Singleton singleton = new Singleton();
//私有构造方法
private Singleton(){}
//公有的静态获得实例方法
public static Singleton getInstance(){return singleton;}
}
懒汉式
public class Singleton1 {
private static Singleton1 instance; //保存唯一实例的static变量
//为了防止对象被创建,可以为构造函数加上private修饰符,但是这同样也防止了子类的对象被创建,因而,可以选用protected修饰符来替代private
protected Singleton1() {
}
//外部调用公用方法时才判断是否需要进行创建
public static Singleton1 getInstance() {
if (instance == null) {
instance = new Singleton1(); //if模块可能会几个线程同时访问
}
return instance;
}
}
多线程实现1:synchronized
public class Singleton2 {
private static Singleton2 instance = null;
private Singleton3() {
}
//用静态同步方法,保证只有一个线程能实例化instance,其他线程if模块会跳过
public static synchronized Singleton2 getInstance() {
if (instance==null)
instance = new Singleton2(); //使用时生成实例
return instance;
}
}
多线程实现2:静态内部类
因为Java机制规定,内部类Holder只有在getInstance()方法第一次调用的时候才会被加载(实现了lazy),而且其加载过程是线程安全的(实现线程安全)。内部类加载的时候实例化一次instance。
public class Singleton3 {
//用静态内部类
private static class Instance {
static final Singleton3 instance = new Singleton3();
}
private Singleton3() {
}
public static Singleton3 getInstance() {
return Instance.instance;
}
}