一 工厂方法模式
1.解决的问题
将创建具体类的工作统一交给工厂来做,别的类概不负责。
2.类图
3.对应类图源码
/**
* 蛋糕接口
*/
public interface Cake {
}
/**
* 奶油蛋糕
*/
public class CreamCake implements Cake {
}
/**
* 水果蛋糕
*/
public class FruitCake implements Cake {
}
/**
* 蛋糕工厂
*/
public class CakeFactory {
/*
* 创建水果蛋糕
*/
public Cake createFruitCake(){
return new FruitCake();
}
/*
* 创建奶油蛋糕
*/
public Cake createCreamCake(){
return new CreamCake();
}
}
/**
*客户端调用
*/
public class Client {
public static void main(String[] args) {
CakeFactory factory = new CakeFactory();
Cake fruitcake = factory.createFruitCake();
Cake creamCake = factory.createCreamCake();
}
}
4.变体:静态工厂方法
将工厂中的方法修改为静态的,则变体为静态工厂方法。
/**
* 蛋糕工厂
*/
public class CakeFactory {
/*
* 创建水果蛋糕
*/
public static Cake createFruitCake(){
return new FruitCake();
}
/*
* 创建奶油蛋糕
*/
public static Cake createCreamCake(){
return new CreamCake();
}
}
/**
*客户端调用
*/
public class Client {
public static void main(String[] args) {
Cake fruitcake = CakeFactory.createFruitCake();
Cake creamCake = CakeFactory.createCreamCake();
}
}
二 抽象工厂模式
1.解决的问题
在遵守开闭原则的情况下,使用工厂方法,可以动态的创建新的产品而不需要改动工厂类。
2.类图
3.对应类图源码
注:蛋糕、水果蛋糕、奶油蛋糕与工厂方法相同。
/**
* 蛋糕工厂
*/
public interface AbstractCakeFactory {
/*
* 制造蛋糕
*/
public Cake makeCake();
}
/**
* 水果蛋糕工厂
*/
public class FruitCakeFactory implements AbstractCakeFactory {
@Override
public Cake makeCake() {
/*
* 创建水果蛋糕
*/
return new FruitCake();
}
}
/**
* 奶油蛋糕工厂
*/
public class CreamCakeFactory implements AbstractCakeFactory {
@Override
public Cake makeCake() {
/*
* 创建奶油蛋糕
*/
return new CreamCake();
}
}
public class Client {
public static void main(String[] args) {
//想要水果蛋糕,先造一个水果蛋糕工厂,制出来的就是水果蛋糕
AbstractCakeFactory fruitfactory = new FruitCakeFactory();
fruitfactory.makeCake();
//想要奶油蛋糕,先造一个奶油蛋糕工厂,制出来的就是奶油蛋糕
AbstractCakeFactory creamfactory = new CreamCakeFactory();
creamfactory.makeCake();
}
}
三 单例模式
1.解决的问题
让整个系统中只有一个实例,就像一个国家只能有一个皇帝。
2.源码一(双重锁检查写法)
/**
* 皇帝单例
*/
public class Emperor {
//构造器私有
private Emperor(){}
//实例私有
private static Emperor instance;
public static Emperor getEmperor(){
if(null == instance){
synchronized(instance){
if(null == instance){
instance = new Emperor();
}
}
}
return instance;
}
}
注:也有人把同步块抽取出一个方法来,这里不加赘述。
3.源码二(内部类写法)
/**
* 皇帝单例
*/
public class Emperor {
//构造器私有
private Emperor(){}
//私有内部类
private static class EmperorVoter{
private static Emperor instance = new Emperor();
}
public static Emperor getEmperor(){
return EmperorVoter.instance;
}
}
4.源码三(枚举写法)
/**
* 皇帝单例
*/
public enum Emperor {
INSTANCE
}
四 建造者模式
1.解决的问题
使用建造者可以实现产品的定制化功能。
2.类图
3.源码
/**
* 可定制的蛋糕
*/
public class ChosenCake {
//豆沙
private String dousha;
//水果块
private String shuiguo;
public String getDousha() {
return dousha;
}
public void setDousha(String dousha) {
this.dousha = dousha;
}
public String getShuiguo() {
return shuiguo;
}
public void setShuiguo(String shuiguo) {
this.shuiguo = shuiguo;
}
}
/**
* 蛋糕制作者
*/
public interface CakeMaker {
/*
* 加豆沙
*/
public void addDousha();
/*
* 加水果块儿
*/
public void addShuiguo();
/*
* 交付蛋糕
*/
public ChosenCake finishCake();
}
/**
* 蛋糕师傅
*/
public class CakeMaster implements CakeMaker {
//默认制作一个什么都不加的蛋糕
private ChosenCake cake = new ChosenCake();
@Override
public void addDousha() {
cake.setDousha("按您的要求加入了===豆沙===");
}
@Override
public void addShuiguo() {
cake.setShuiguo("按您的要求加入了===水果块儿===");
}
@Override
public ChosenCake finishCake(){
return cake;
}
}
/**
* 客人
*/
public class Guest {
public static void main(String[] args) {
//选一个蛋糕师傅
CakeMaker maker = new CakeMaster();
//给我加点儿豆沙
maker.addDousha();
//给我加点儿水果块
maker.addShuiguo();
//把蛋糕给我吧
ChosenCake cake = maker.finishCake();
}
}
五 原型模式
1.解决的问题
不同程度的来复用已有的对象(深复用、潜复用)。
2.类图
3.对应类图源码
/**
* 开保险箱的方法
*/
public interface OpenBox extends Cloneable{
/*
* 告诉你密码你就可以开(浅复制)
*/
public Object getPassword();
/*
* 配钥匙才可以开(深复制)
*/
public Object copyKey();
}
/**
* 会开保险箱的人
*/
public class BoxOpener implements OpenBox{
/*
* 浅复制,相当于你知道密码了,大家使用的都是同一串密码
*/
@Override
public Object getPassword() {
BoxOpener opener = null;
try {
opener = (BoxOpener)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return opener;
}
/*
* 深复制,相当于你配了一把钥匙,用的不是一个东西
*/
@Override
public Object copyKey() {
BoxOpener opener = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
opener = (BoxOpener) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return opener;
}
}
/**
* 测试流程
*/
public class Test {
public static void main(String[] args) {
//保险箱有一个管理者
OpenBox boxKeeper = new BoxOpener();
//领导要开保险箱(浅复制)
OpenBox leader = (OpenBox)boxKeeper.getPassword();
//来了一个新管理员,配把钥匙(深复制)
OpenBox newKeeper = (OpenBox)boxKeeper.copyKey();
}
}
六 适配器模式
1.解决的问题
用来消除由于接口不匹配所造成的类的兼容性问题。
2.类扩展适配器
3.类扩展适配器源码
public class TriphaseBoard {
/*
* 有三相插口
*/
public boolean hasTriphase(){
System.out.println("==三相插板自带三相输出==");
return true;
}
}
/**
* 多功能插口
*/
public interface MultiSocket {
/*
* 有三相插口
*/
public boolean hasTriphase();
/*
* 有两相插口
*/
public boolean hasTwoPhase();
}
public class MultiPhaseBoard extends TriphaseBoard implements MultiSocket{
/*
* 有两相插口
*/
public boolean hasTwoPhase(){
System.out.println("==多功能插板实现两口的功能==");
return true;
}
}
/**
* 测试流程
*/
public class Test {
public static void main(String[] args) {
MultiSocket board = new MultiPhaseBoard();
board.hasTriphase();
board.hasTwoPhase();
}
}
4.对象扩展适配器
5.对象扩展适配器源码
/**
* 功能要求
*/
public interface FunctionInterface {
/*
* 能做软件
*/
public boolean canDoSoft();
/*
* 能修硬件
*/
public boolean canFixhardward();
}
/**
* 软件公司
*/
public class SoftwareCompany {
public boolean canDoSoft(){
System.out.println("软件公司专业做软件");
return true;
}
}
/**
* 硬件公司
*/
public class HardwareCompany implements FunctionInterface{
//外包一家软件公司
private SoftwareCompany softwareCompany;
public HardwareCompany(SoftwareCompany softwareCompany){
this.softwareCompany = softwareCompany;
}
/*
* 用软件公司做软件
*/
@Override
public boolean canDoSoft() {
return softwareCompany.canDoSoft();
}
/*
* 自己修硬件
*/
@Override
public boolean canFixhardward() {
System.out.println("我是硬件公司修硬件没问题");
return true;
}
}
/**
* 测试流程
*/
public class Test {
public static void main(String[] args) {
FunctionInterface function = new HardwareCompany(new SoftwareCompany());
function.canDoSoft();
function.canFixhardward();
}
}
6.接口适配器
7.接口适配器源码
/**
* 多方法接口
*/
public interface MultiMethod {
public void method1();
public void method2();
public void method3();
public void methodN();
}
/**
* 抽象类为所有接口方法提供空实现
*/
public class AbstractMultiMethod implements MultiMethod {
@Override
public void method1() {}
@Override
public void method2() {}
@Override
public void method3() {}
@Override
public void methodN() {}
}
/**
* 只用方法1的类
*/
public class UserMethod1 extends AbstractMultiMethod{
@Override
public void method1() {
System.out.println("我只用这个方法,我就重写这个方法就可以了");
}
}
/**
* 只用方法N的类
*/
public class UserMethodN extends AbstractMultiMethod{
@Override
public void methodN() {
System.out.println("我只用这个方法,我就重写这个方法就可以了");
}
}