创建型
单例模式
Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点
java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
单例模式有一下特点:
1、单例类只能有一个实例。
2、单例类必须自己自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。
实例一:懒汉式
package com.ruishenh.designPatter.creational.singleton;
/**
* 懒汉式,在第一次调用的时候实例化
* @author hcr
*
*/
public class LazySingleton {
private static LazySingleton uniqueInstance = null;
/**
* 私有的构造函数
*/
private LazySingleton() {
// Exists only to defeat instantiation.
}
/**
* 公有的访问模式
*
* @return
*/
public synchronized static LazySingleton getInstance() {
// 对象保持一个
if (uniqueInstance == null) {
uniqueInstance = new LazySingleton();
}
return uniqueInstance;
}
}
实例二:饿汉式
package com.ruishenh.designPatter.creational.singleton;
/**
* 饿汉式单例类.在类初始化时,已经自行实例化
*
* @author hcr
*
*/
public class SampleSingleton {
/**
* 私有的构造
*/
private SampleSingleton() {
}
/**
* 初始化对象有实例
*/
private static final SampleSingleton single = new SampleSingleton();
/**
* 静态工厂方法直接返回单例对象
*/
public static SampleSingleton getInstance() {
return single;
}
}
实例三:登记式
package com.ruishenh.designPatter.creational.singleton;
import java.util.HashMap;
import java.util.Map;
/**
* 登记式单例类. 类似Spring里面的方法,将类名注册,下次从里面直接获取。
*
* @author hcr
*
*/
public class RegisterSingleton {
/**
* 默认容器
*/
private static Map<String, RegisterSingleton> map = new HashMap<String, RegisterSingleton>();
static {
RegisterSingleton single = new RegisterSingleton();
map.put(single.getClass().getName(), single);
}
/**
* 保护的默认构造器
*/
protected RegisterSingleton() {
}
/**
* 静态工厂方法,返还此类惟一的实例
*
* @param name
* @return
*/
public static RegisterSingleton getInstance(String name) {
if (name == null) {
name = RegisterSingleton.class.getName();
System.out.println("name == null"+"--->name="+name);
}
if (map.get(name) == null) {
try {
map.put(name, (RegisterSingleton) Class.forName(name)
.newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return map.get(name);
}
public String about() {
return "Hello, I am RegSingleton.";
}
public static void main(String[] args) {
RegisterSingleton single = RegisterSingleton.getInstance("com.ruishenh.designPatter.creational.singleton.RegisterSingleton");
System.out.println(single.about());
}
}
参考:http://www.cnblogs.com/whgw/archive/2011/10/05/2199535.html
工厂模式
工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的.
简单工厂
简单工厂模式又叫静态工厂模式,顾名思义,它是用来实例化目标类的静态类。
package com.ruishenh.designPatter.creational.factory.simpleFactory;
/**
* 静态工厂
* @author hcr
*
*/
public class SimpleFactory {
//静态直接产生指定对象
static TVFactory getTV(){
return new Haier();
}
public static void main(String[] args) {
//客户端调用静态直接生成创建对象
TVFactory tv=SimpleFactory.getTV();
System.out.println(tv.about());
}
}
interface TVFactory{
String about();
}
class Haier implements TVFactory{
@Override
public String about() {
return "Haier高清彩电";
}
}
class Hisense implements TVFactory{
@Override
public String about() {
return "Hisense高清彩电";
}
}
简单工厂核心任务就是简单的返回对应的生产的产品,客户端不用去管怎么创建的,直接调用对应的工厂静态方法返回实体即可。
工厂方法
工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类。
package com.ruishenh.designPatter.creational.factory.factoryMethod;
public class FactoryMethod {
public static void main(String[] args) {
//客户端调用
TVFactory tv=new HaierFactory();
//工厂生成实例
System.out.println(tv.createFPTV().about());
}
}
//工厂
interface TVFactory{
/*
* 工厂方法
*/
FPTVProduct createFPTV();
}
//产品接口
interface FPTVProduct{
String about();
}
class HaierFactory implements TVFactory{
@Override
public FPTVProduct createFPTV() {
//创建Haier的平板电视
return new FPTVProduct() {
@Override
public String about() {
return "Haier高清平板电视";
}
};
}
}
class HisenseFactory implements TVFactory{
@Override
public FPTVProduct createFPTV() {
//创建Hisense的平板电视
return new FPTVProduct() {
@Override
public String about() {
return "Hisense高清平板电视";
}
};
}
}
工厂方法的核心任务就是通过工厂中的方法返回对应的子工厂来创建一个对象返回给客户端。
抽象工厂
Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。
package com.ruishenh.designPatter.creational.factory.abstractFactory;
public class AbstractFactory {
public static void main(String[] args) {
TVFactory factory=new HaierFactory();
System.out.println(factory.createDTV().about());
System.out.println(factory.createFPTV().about());
//
TVFactory factory2=new HisenseFactory();
System.out.println(factory2.createDTV().about());
System.out.println(factory2.createFPTV().about());
}
}
interface TVFactory{
FPTVProduct createFPTV();
DTVProduct createDTV();
}
interface FPTVProduct{
String about();
}
interface DTVProduct{
String about();
}
class HaierFactory implements TVFactory{
@Override
public FPTVProduct createFPTV() {
//创建Haier的平板电视
return new FPTVProduct() {
@Override
public String about() {
return "Haier高清平板电视,我的尺寸特别小";
}
};
}
@Override
public DTVProduct createDTV() {
return new DTVProduct() {
@Override
public String about() {
return "Haier高清数字电视,我有X个频道";
}
};
}
}
class HisenseFactory implements TVFactory{
@Override
public FPTVProduct createFPTV() {
//创建Hisense的平板电视
return new FPTVProduct() {
@Override
public String about() {
return "Hisense高清平板电视,我的尺寸特别小";
}
};
}
@Override
public DTVProduct createDTV() {
return new DTVProduct() {
@Override
public String about() {
return "Hisense高清数字电视,我有N个频道";
}
};
}
}
抽象工厂的核心任务就是通过工厂中的方法返回对应的子工厂中的多个工厂中的一个,让后这个工厂可以返回多个产品的一个产品。
建造模式
将一个复杂对象的构建与他的表示相分离,使得同样的构建过程可以创建不同的表示。
package com.ruishenh.designPatter.creational.builder;
public class Builder {
public static void main(String[] args) {
//找到小明给组装电脑
BuilderComputer builderComputer=new buildWorker();
//小明是新手,要老师指导组装
Director director =new Director(builderComputer);
//小明装电脑
director.construct();
//组装完毕
builderComputer.getComputer();
}
}
//组装步骤
interface BuilderComputer{
//组装电源
void builderPower();
//组装机箱
void builderCrate();
//组装显示器
void builderDisplay();
//返回组装的整个电脑
Computer getComputer();
}
//组装工人
class buildWorker implements BuilderComputer{
HPComputer computer =new HPComputer();
@Override
public void builderPower() {
computer.setPower("德玛牌电源");
System.out.println("组装好了电源");
}
@Override
public void builderCrate() {
computer.setCrate("剑圣牌机箱");
System.out.println("组装好了机箱");
}
@Override
public void builderDisplay() {
computer.setCrate("剑姬牌显示器");
System.out.println("组装好了显示器");
}
@Override
public Computer getComputer() {
System.out.println("组装好了一台全新的英雄联盟牌电脑");
return computer;
}
}
//实例产品
class HPComputer implements Computer{
String power;
String crate;
String display;
@Override
public String getPower() {
return power;
}
@Override
public void setPower(String power) {
this.power=power;
}
@Override
public String getCrate() {
return crate;
}
@Override
public void setCrate(String crate) {
this.crate=crate;
}
@Override
public String getDisplay() {
return display;
}
@Override
public void setDisplay(String display) {
this.display=display;
}
}
//产品概念
interface Computer{
public String getPower();
public void setPower(String power);
public String getCrate();
public void setCrate(String crate);
public String getDisplay();
public void setDisplay(String display);
}
//指导构建者
class Director{
BuilderComputer builderComputer;
public Director(BuilderComputer builderComputer){
this.builderComputer=builderComputer;
}
public void construct() {
builderComputer.builderPower();
builderComputer.builderCrate();
builderComputer.builderDisplay();
}
}
建造者模式的核心任务就是把组装成一个(多种)复杂的对象产品放到对应的各个部分,然后用一个外壳(指导者)来把整体连接完成构建产品。最后返回一个产品(使得同样的构建过程可以创建不同的产品)
原型模式
用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。
package com.ruishenh.designPatter.creational.prototype;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Prototype {
public static void main(String[] args) throws CloneNotSupportedException {
ConcretePrototype cp = new ConcretePrototype();
cp.setName("test-1");
List list = new ArrayList();
list.add(1);
cp.setList(list);
Map<String, Object> map = new HashMap<String, Object>();
map.put("test-2", "test-2-value");
cp.setMaps(map);
ConcretePrototype cp2 = new ConcretePrototype();
cp2.setName("test-3");
cp.setConcretePrototype(cp2);
ConcretePrototype clonecp = (ConcretePrototype) cp.clone();
clonecp.setName("test-1-1");
Map<String, Object> maps = clonecp.getMaps();
maps.put("test-2", "test-2-value-2");
ConcretePrototype cp4 = clonecp.getConcretePrototype();
cp4.setName("test-3-3");
List l=clonecp.getList();
l.clear();
//确认基本类型不在是一个引用
System.out.println(cp.getName() + "<==>" + clonecp.getName());
//确认map不在是一个引用
System.out.println(cp.getMaps() + "<==>" + clonecp.getMaps());
//确认getConcretePrototype不在是一个引用
System.out.println(cp.getConcretePrototype().getName() + "<==>" + clonecp.getConcretePrototype().getName());
//确认list不在是一个引用
System.out.println("test-6-" + cp.getList() + "<==>" + "test-6-"+ clonecp.getList());
}
}
class BasePrototype implements Cloneable {
@Override
protected BasePrototype clone() throws CloneNotSupportedException {
return (BasePrototype) super.clone();
}
}
class ConcretePrototype extends BasePrototype {
private String name;
private List list;
private Map<String, Object> maps;
private ConcretePrototype concretePrototype;
public ConcretePrototype getConcretePrototype() {
return concretePrototype;
}
public void setConcretePrototype(ConcretePrototype concretePrototype) {
this.concretePrototype = concretePrototype;
}
public List getList() {
return list;
}
public Map<String, Object> getMaps() {
return maps;
}
public void setMaps(Map<String, Object> maps) {
this.maps = maps;
}
public void setList(List list) {
this.list = list;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return super.toString();
}
@Override
protected ConcretePrototype clone() throws CloneNotSupportedException {
ConcretePrototype cpBasePrototype = (ConcretePrototype) super.clone();
cpBasePrototype.list = this.list==null?null:(List) ((ArrayList)this.list).clone();
cpBasePrototype.maps = (Map<String, Object>) (this.maps == null ? null:((HashMap) this.maps).clone());
cpBasePrototype.concretePrototype = this.concretePrototype == null ? null:this.concretePrototype.clone();
return cpBasePrototype;
}
}
原型模式可以很好的copy对象而不用去new一个对象。对于复杂的数据类型资源上来讲其实是很方便的。
它的核心任务就是节省开支,方便操作返回一个同样的对象。还有好多的结识比如深度和浅度的问题。在上边的实例完全做了一个深度的clone操作。