下面内容持续更新....
- 一、设计模式七大原则
- 二、设计模式
- 2.1 创建型--单例模式
- 2.2 创建型--工厂模式
- 2.3 创建型--原型模式
- 2.4 创建型--建造者模式
- 2.5 结构型--装饰者模式
- 2.6 结构型--代理模式
- 2.7 结构型--桥接模式
- 2.8 结构型--组合模式
- 2.9 结构型--适配器模式
- 2.10 结构型--外观模式
- 2.11 结构型--亨元模式
- 2.12 行为型--观察者模式
- 2.13 行为型--备忘录模式
- 2.14 行为型--解释器模式
- 2.15 行为型--命令模式
- 2.16 行为型--状态模式
- 2.17 行为型--中介者模式
- 2.18 行为型--职责链模式
- 2.19 行为型-模板方法模式
- 2.20 行为型-迭代器模式
- 2.21 行为型--访问者模式
- 2.22 行为型--策略模式
一、设计模式七大原则
参考网址“http://c.biancheng.net/view/1317.html”,主要参考上面网址的内容,结合自己的理解汇总。
七大原则总体是
各个原则详细介绍如下
二、设计模式
设计模式总共分为三大类。创建型、结构型和行为型。
备注:自己想到比较low的记忆方法。
结构型:“装饰者”找“代理”“桥接”“组合”“适配”“外观”,更“亨元”
行为型:“观察者”“备忘”“解释”到,他有下“命令”“状态”,“中介”有“职责”按照“模板”“迭代”“访问”“策略”
2.1 创建型–单例模式
2.1.1 懒汉式
public class LazySingleton {
private static LazySingleton singleton1;
//私有构造函数,所以只能类自己去实例化,外围通过
//类去调用static方法
private LazySingleton(){}
/**
* 线程不安全
* @return
*/
public static LazySingleton getSingleton1(){
//如果是多线程中,singleton1是在方法区,共有的。
//不同线程去new这个对象,在下面的时候会导致多次实例化
if(null == singleton1){
singleton1 = new LazySingleton();
}
return singleton1;
}
/**
* 线程安全,但效率低。且如果一个线程卡死,其他线程都会等待
* @return
*/
public static synchronized LazySingleton getSingleton2(){
//如果是多线程中,singleton1是在方法区,共有的。
//不同线程去new这个对象,在下面的时候会导致多次实例化
if(null == singleton1){
singleton1 = new LazySingleton();
}
return singleton1;
}
}
2.1.2 饿汉式
public class HungrySingleton {
//空间换时间,类加载时就创建好类实例,可能会占用无效的内存
private static final HungrySingleton singleton = new HungrySingleton();
private HungrySingleton(){}//禁止该类被外界实例化
public static HungrySingleton getSingleton(){
return singleton;
}
}
2.1.3 双重检验
public class DoubleCheckLockSingleton {
//volatile保证内存屏障,写入对读取可见性
//会禁止JVM指令重排,从而保证在多线程下也能正常执行
// private static DoubleCheckLockSingleton singleton; //这样没volatile修饰,会出现下面的重排序问题
private static volatile DoubleCheckLockSingleton singleton;//可以杜绝下面的重排序问题
private DoubleCheckLockSingleton(){}
public static DoubleCheckLockSingleton getSingleton(){
if(null == singleton){
synchronized (DoubleCheckLockSingleton.class){//这是类锁
//下面的先判断,然后实例化对象,看似保证多线程安全
//但是, singleton = new DoubleCheckLockSingleton();并不是原子性
//创建一个对象分为三部分:
//1.分配对象的内存空间
//2.初始化对象
//3.设置instance指向刚分配的内存地址
//实际情况中,2和3步骤会被重排序,线程A可能地址分配了,另外一个线程B调用
//发现singleton不为null,直接返回线程A还没初始化完的对象使用,会报错
if(null == singleton){
singleton = new DoubleCheckLockSingleton();
}
}
}
return singleton;
}
}
2.1.4 静态内部类
public class StaticInnerSingleton {
private StaticInnerSingleton(){} //私有构造函数
//这里加final是为了防止子类重写父类
public static final StaticInnerSingleton getSingleton(){
return InnerClass.INNER;
}
/**
* 外部类加载时并不需要立即加载内部类,内部类不被加载则不去初始化INSTANCE,故而不占内存。
* 只有调用getSingleton()方法时,才会加载InnerClass内部类
* InnerClass在StaticInnerSingleton的运行时常量池中,把符号引用替换为直接引用,
* 这时静态对象INNER也真正被创建
*
* 缺点:外界无法传参进行初始化这个类
*/
private static class InnerClass{
private static StaticInnerSingleton INNER = new StaticInnerSingleton();
}
}
2.1.5 枚举
public class EnumSingleton {
private EnumSingleton(){} //这是私有构造函数,外界不能实例化
//具体对这个外部类实例化,用枚举保证只装载一次
public static EnumSingleton getInstance(){
return InnerEnum.INNER.getSingleton();
}
/**
* 枚举类型是线程安全的,并且只会装载一次
* 下面是枚举类,枚举不是被反射,且InnerEnum构造函数只执行一次
*优点: 能避免多线程同步问题,而且还能防止反序列化重新创建新的对象
*/
private static enum InnerEnum{
INNER;
private EnumSingleton singleton;
private InnerEnum(){
singleton = new EnumSingleton();
}
public EnumSingleton getSingleton(){
return singleton;
}
}
}
2.1.6 CAS
public class CASSingleton {
private static final AtomicReference<CASSingleton> INNERCAS = new AtomicReference<CASSingleton>();
private CASSingleton(){}
/**
* CAS缺点:如果忙等待一直执行不成功(一直在死循环中),会对CPU造成较大的执行开销。
* @return
*/
public static CASSingleton getInstance(){
for(;;){
CASSingleton singleton = INNERCAS.get();
if(null != singleton){
return singleton;
}
/**
* 如果N个线程同时执行到singleton = new Singleton();的时候,会有大量对象创建,很可能导致内存溢出。
*/
singleton = new CASSingleton();
if(INNERCAS.compareAndSet(null,singleton)){
return singleton;
}
}
}
}
2.2 创建型–工厂模式
2.2.1 简单工厂模式
—抽象产品类
public abstract class Car {
private String name; //具体产品名(某种类型汽车)
public abstract void drive(); //谁来开
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
—具体产品类
public class BenzCar extends Car {
@Override
public void drive() {
System.out.println(this.getName()+"----go-------");
}
}
public class BmwCar extends Car {
@Override
public void drive() {
System.out.println(this.getName()+"----go-------");
}
}
对于简单工厂模式,一个工厂类来派生出各种产品对象。
-----工厂类
public class DriverSimpleFactory {
//这里来确定什么类型的车
public static Car createCar(String car){
Car c=null;
if("Benz".equalsIgnoreCase(car)){
c=new BenzCar();
}else if("Bmw".equalsIgnoreCase(car)){
c=new BmwCar();
}
return c;
}
}
-----客户端测试
public class SimpleFactoryMain {
public static void main(String[] args) {
Car car = DriverSimpleFactory.createCar("Benz");
car.setName("Benz");
car.drive();
}
}
2.2.2 工厂方法模式
工厂方法模式,是有抽象工厂类,每个具体的工厂类创建具体的一个产品类。
—抽象工厂类
public abstract class Driver {
public abstract Car createCar(String car);
}
—具体工厂类
public class BenzDriver extends Driver {
@Override
public Car createCar(String car) {
return new BenzCar();
}
}
public class BmwDriver extends Driver {
@Override
public Car createCar(String car) {
return new BmwCar();
}
}
—测试例子
public class FactoryMethodMain {
public static void main(String[] args) {
Driver driver = new BenzDriver();
Car car = driver.createCar(null);
car.setName("Benz汽车");
car.drive();
}
}
2.2.3 抽象工厂模式
public abstract class BenzCar {
private String name;
public abstract void drive();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class BenzBusinessCar extends BenzCar{
@Override
public void drive() {
// TODO Auto-generated method stub
System.out.println(this.getName()+"----BenzBusinessCar-----");
}
}
public class BenzSportCar extends BenzCar{
@Override
public void drive() {
// TODO Auto-generated method stub
System.out.println(this.getName()+"----BenzSportCar-----");
}
}
public abstract class BmwCar {
private String name;
public abstract void drive();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class BmwBusinessCar extends BmwCar{
@Override
public void drive() {
// TODO Auto-generated method stub
System.out.println(this.getName()+"----BmwBusinessCar-----");
}
}
public class BmwSportCar extends BmwCar{
@Override
public void drive() {
// TODO Auto-generated method stub
System.out.println(this.getName()+"----BmwSportCar-----");
}
}
public abstract class Driver3 {
public abstract BenzCar createBenzCar(String car);
public abstract BmwCar createBmwCar(String car);
}
public class BusinessDriver3 extends Driver3{
@Override
public BenzCar createBenzCar(String car){
return new BenzBusinessCar();
}
@Override
public BmwCar createBmwCar(String car){
return new BmwBusinessCar();
}
}
public class SportDriver3 extends Driver3{
public BenzCar createBenzCar(String car) {
return new BenzSportCar();
}
public BmwCar createBmwCar(String car){
return new BmwSportCar();
}
}
—测试方法
public class AbstractFactoryMain {
public static void main(String[] args) {
Driver3 d = new BusinessDriver3();
BenzCar car = d.createBenzCar(null);
car.drive();
}
}
2.3 创建型–原型模式
案例:原型模式生成"三好学生"奖状。奖状除了名字不同,其他相同,所以适合原型模式创建。
public class PrototypeAward implements Cloneable{
private String name;
private String college;
private String info;
PrototypeAward(String name,String college,String info){
this.name = name;
this.college = college;
this.info = info;
}
public Object clone() throws CloneNotSupportedException {
return (PrototypeAward) super.clone();
}
public void display(){
System.out.println(name + info + college);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCollege() {
return college;
}
public void setCollege(String college) {
this.college = college;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
—测试方法
public class PrototypeAwardMain {
public static void main(String[] args) throws CloneNotSupportedException {
PrototypeAward award = new PrototypeAward("wwy","在**大学","获得三好学生!");
award.display();
PrototypeAward award1 = (PrototypeAward)award.clone();
award1.setName("zzw");
award1.display();
}
}
2.4 创建型–建造者模式
建造者(Builder)模式的主要角色如下。
产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口
具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
接下来以具体案例来讲解:
装修客厅。客厅产品【产品角色】需要装墙、安装电视机、弄沙发等。 项目负责人【指挥者】指挥工人们【具体建造者】干活,最终完成该产品。
–客厅产品类
public class ParlourProduct {
public String wall(String name){
return name+"造好了墙";
}
public String Tv(String name){
return name+"安装好电视";
}
public String sofa(String name){
return name+"安装好沙发";
}
}
—抽象建造者类
public abstract class WorkerBuilder {
ParlourProduct product = new ParlourProduct();
public abstract String buildWall();
public abstract String buildTv();
public abstract String buildSofa();
}
—具体建造者类
public class WorkerBuilderV1 extends WorkerBuilder {
@Override
public String buildWall() {
return product.wall("wwy");
}
@Override
public String buildTv() {
return product.Tv("wwy");
}
@Override
public String buildSofa() {
return product.sofa("wwy");
}
}
public class WorkerBuilderV2 extends WorkerBuilder {
@Override
public String buildWall() {
return product.wall("zs");
}
@Override
public String buildTv() {
return product.Tv("zs");
}
@Override
public String buildSofa() {
return product.sofa("zs");
}
}
–指挥者类
public class ProjectManager {
private WorkerBuilder builder;
ProjectManager(WorkerBuilder builder){
this.builder = builder;
}
public void processProduct(){
System.out.println(builder.buildSofa()+" "+ builder.buildTv()+" "+ builder.buildWall());
}
}
–实际操作测试
public class ProjectManagerMain {
public static void main(String[] args) {
//项目管理指挥工人1对客厅进行装饰。
ProjectManager manager1 = new ProjectManager(new WorkerBuilderV1());
manager1.processProduct();
ProjectManager manager2 = new ProjectManager(new WorkerBuilderV1());
manager2.processProduct();
}
}
2.5 结构型–装饰者模式
接下来以具体案例来讲解:
—火锅锅底抽象类
public abstract class Bottom {
String description="Unknown Beverage";
public String getDescription(){return description;}
public abstract double cost(); //价钱
}
—火锅锅底1
public class BottomV1 extends Bottom{
public BottomV1(){description = "BottomV1";}
@Override
public double cost() {
return 1.0;
}
}
—火锅锅底2
public class BottomV2 extends Bottom {
public BottomV2(){description ="BottomV2";}
@Override
public double cost() {
return 2.0;
}
}
—配菜抽象类
public abstract class MenuDecorator extends Bottom {
public abstract String getDescription(); //让装饰者们重写这个方法
}
—配菜1
public class MenuDecoratorV1 extends MenuDecorator {
Bottom bottom;
MenuDecoratorV1(Bottom bottom){this.bottom=bottom;}
@Override
public String getDescription() {
return bottom.getDescription()+",MenuV1";
}
@Override
public double cost() {
return 1.1+bottom.cost();
}
}
—配菜2
public class MenuDecoratorV2 extends MenuDecorator {
Bottom bottom;
MenuDecoratorV2(Bottom bottom){this.bottom=bottom;}
@Override
public String getDescription() {
return bottom.getDescription()+",MenuV2";
}
@Override
public double cost() {
return 2.1+bottom.cost();
}
}
-----装饰者测试方法
public class DecoratorMain {
public static void main(String[] args) {
//BottomV1+两个MenuV1+MenuV2
Bottom bottom1 = new BottomV1();
bottom1 = new MenuDecoratorV1(bottom1);
bottom1 = new MenuDecoratorV1(bottom1);
bottom1 = new MenuDecoratorV2(bottom1);
}
}
2.6 结构型–代理模式
2.7 结构型–桥接模式
接下来以具体案例来讲解:
具体案例:按照用途选择包,有挎包和钱包,按照颜色维度有红色、蓝色等,按照大小维度有大、小等。—此时抓住一个维度,然后组合其他维度。
–颜色接口
public interface Color {
public String getColor();
}
–红色
public class RedColor implements Color {
@Override
public String getColor() {
return "red";
}
}
–蓝色
public class YellowColor implements Color {
@Override
public String getColor() {
return "yellow";
}
}
—尺寸接口
public interface Size {
public String getSize();
}
–大尺寸
public class BigSize implements Size {
@Override
public String getSize() {
return "big";
}
}
–小尺寸
public class SmallSize implements Size {
@Override
public String getSize() {
return "small";
}
}
–包抽象类
public abstract class Bag {
protected Color color;
protected Size size;
public void setColor(Color color) {
this.color = color;
}
public void setSize(Size size) {
this.size = size;
}
public abstract String getBagName();
}
–挎包
public class HandBag extends Bag {
@Override
public String getBagName() {
return color.getColor()+" "+size.getSize()+ " HandBag.";
}
}
–钱包
public class WalletBag extends Bag {
@Override
public String getBagName() {
return color.getColor()+" "+size.getSize()+ " WalletBag.";
}
}
—测试。 我们选择的包:钱包+红色+大尺寸。
public class BridgeMain {
public static void main(String[] args) {
Bag bag = new WalletBag();
bag.setColor(new RedColor());
bag.setSize(new BigSize());
System.out.println(bag.getBagName());
}
}
2.8 结构型–组合模式
2.9 结构型–适配器模式
接下来以具体案例来讲解:
具体案例:某人要坐汽车出行去某地区,可以选择不同汽车行驶【电动汽车、机油汽车等】。该人不能直接选择某种汽车,所以通过适配器去选择适合的行驶汽车。
—电能汽车
public class ElectricCar {
public String electricDrive(){
return "电能汽车行驶!";
}
}
—机油汽车
public class OilCar {
public String oilDrive(){
return "机油汽车行驶!";
}
}
–汽车选型接口
public interface CarDrive {
public void drive();
}
—电能汽车适配器
public class ElectricCarAdapter implements CarDrive {
ElectricCar electricCar;
ElectricCarAdapter(){
electricCar = new ElectricCar();
}
@Override
public void drive() {
electricCar.electricDrive();
}
}
—汽油汽车适配器
public class OilCarAdapter implements CarDrive {
OilCar oilCar;
OilCarAdapter(){
oilCar = new OilCar();
}
@Override
public void drive() {
oilCar.oilDrive();
}
}
—适配器测试。客户端通过“电能汽车适配器”来选择电能汽车行驶。
public class AdapterMain {
public static void main(String[] args) {
CarDrive carDrive = new ElectricCarAdapter();
carDrive.drive();
}
}
2.10 结构型–外观模式
接下来以具体案例来讲解:
具体案例:买车流程。4S店提车+车管所上牌+保险公司上保险。 可以使用一个外观类,该类将买车各个子流程封装好,向外只提供一个“买车一步成功的方法”。
—提车
public class CarGet {
public String get(){return "get car!";}
}
—上牌
public class CarLicense {
public String get(){return "get license!";}
}
—上保险
public class CarSafe {
public String get(){
return "get safe!";
}
}
–“一步买车”外观类
public class BuyCarFacade {
private CarGet carGet;
private CarLicense carLicense;
private CarSafe carSafe;
public void BuyCarFacade() {
this.carGet = new CarGet();
this.carLicense = new CarLicense();
this.carSafe = new CarSafe();
}
/**
* 给客户端调用的 “一步买车”方法
*/
public void oneStepBuyCar(){
carGet.get();
carLicense.get();
carSafe.get();
}
}
2.11 结构型–亨元模式
2.12 行为型–观察者模式
观察者模式的主要角色如下。
抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
接下来以具体案例详图来讲解:
具体案例:气象站消息。气象站【具体主题】每天接收消息【气象站任务:接收用户注册、接收用户注销、通知用户消息、接收消息变化】,及时将最新消息通知给那些需要的用户【具体观察者】。
—气象站抽象主题接口
public interface WeatherSubject {
//注册
public void registerObserver(UserObserver o);
// 注销
public void removeObserver(UserObserver o);
//通知
public void notifyObserver();
}
—气象站具体主题类
public class WeatherSubjectV1 implements WeatherSubject {
private float temperature;
private List<UserObserver> observerList;
public WeatherSubjectV1(){observerList = new ArrayList<>();}
@Override
public void registerObserver(UserObserver o) {
observerList.add(o);
}
@Override
public void removeObserver(UserObserver o) {
int i=observerList.indexOf(o);
if(i>=0){
observerList.remove(i);
}
}
@Override
public void notifyObserver() {
for(int i=0;i<observerList.size();i++){
UserObserver observer=observerList.get(i);
observer.update(temperature);
}
}
public void setWeatherInfo(float temperature){
this.temperature = temperature;
//信息变化后,里面通知所有 观察者们
notifyObserver();
}
}
—观察者接口
public interface UserObserver {
//观察者们 自动更新
void update(float temperature);
}
—具体观察者V1
public class UserObserverV1 implements UserObserver {
public WeatherSubject weatherSubject;
public UserObserverV1(WeatherSubject weatherSubject){
this.weatherSubject = weatherSubject;
//这个观察者初始化时就注册到 主题类中
weatherSubject.registerObserver(this);
}
public void removeObserver(){
//通知主题类, 该观察者注销了
weatherSubject.removeObserver(this);
}
@Override
public void update(float temperature) {
//接收到temperature变化值,进行其他业务
System.out.println("temperature: "+temperature);
}
}
—观察者测试。
public class ObserverMain {
public static void main(String[] args) {
WeatherSubjectV1 weatherSubject = new WeatherSubjectV1();
UserObserverV1 userObserverV1 = new UserObserverV1(weatherSubject);
//主题类信息变化
weatherSubject.setWeatherInfo(34f);
//观察者注销,确定主题变化,观察者是否收到信息
userObserverV1.removeObserver();
weatherSubject.setWeatherInfo(35f);
}
}
2.13 行为型–备忘录模式
备忘录模式的主要角色如下。
发起人(Originator)角色:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
备忘录(Memento)角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
管理者(Caretaker)角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。
接下来以具体案例详图来讲解:
具体案例:某个发起人想保存历史的状态,根据实际情况能够恢复历史状态。
–备忘录角色
//备忘录角色 存储发起人角色的状态
public class Memento {
private String state;
public Memento(String state){this.state = state;}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
–发起人角色
//发起人角色
public class OriginatorUser {
private String state;//当前自己的状态
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
//发起人角色 创建一个备忘录来记录状态
public Memento createMemento(){
return new Memento(state);
}
//发起人 利用备忘录的状态来恢复自己当前状态
public void restoreMemento(Memento me) {
this.setState(me.getState());
}
}
–管理者角色
//管理者角色
public class Manager {
//获取发起人角色每次创建的“备忘录”
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
–测试。
public class MementoMain {
public static void main(String[] args) {
OriginatorUser user = new OriginatorUser();
user.setState("1");
Manager manager = new Manager();
//创建一个备忘录,并交给管理者角色
manager.setMemento(user.createMemento());
//发起者状态变化了
user.setState("2");
//恢复之前状态
user.restoreMemento(manager.getMemento());
}
}
2.14 行为型–解释器模式
2.15 行为型–命令模式
2.16 行为型–状态模式
2.17 行为型–中介者模式
2.18 行为型–职责链模式
职责链模式主要包含以下角色。
抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。
具体案例:员工请假。请假单子会根据“请假天数”条件一层一层的流转,直到满足的负责人来处理审批。
–处理者抽象类
public abstract class DutyHandler {
private DutyHandler next;
//通知下一个处理
public abstract void handleRequest(int day);
public DutyHandler getNext() {
return next;
}
public void setNext(DutyHandler next) {
this.next = next;
}
}
–具体处理者V1
public class DutyHandlerV1 extends DutyHandler {
@Override
public void handleRequest(int day) {
if(day <=2){
System.out.println("v1 同意"+day+"天。");
}else{
if(getNext() != null){
getNext().handleRequest(day);
}else
System.out.println("不满足,不批准!");
}
}
}
–具体处理者V2
public class DutyHandlerV2 extends DutyHandler {
@Override
public void handleRequest(int day) {
if(day <=7){
System.out.println("v2 同意"+day+"天。");
}else{
if(getNext() != null){
getNext().handleRequest(day);
}else
System.out.println("不满足,不批准!");
}
}
}
–具体处理者V3
public class DutyHandlerV3 extends DutyHandler {
@Override
public void handleRequest(int day) {
if(day <=10){
System.out.println("v3 同意"+day+"天。");
}else{
if(getNext() != null){
getNext().handleRequest(day);
}else
System.out.println("不满足,不批准!");
}
}
}
—测试。
public class DutyMain {
public static void main(String[] args) {
DutyHandler v1 = new DutyHandlerV1();
DutyHandler v2 = new DutyHandlerV2();
DutyHandler v3 = new DutyHandlerV3();
v1.setNext(v2);
v2.setNext(v3);
//开始批假
v1.handleRequest(4);
}
}
2.19 行为型-模板方法模式
具体案例:银行办业务过程。一般银行办业务流程是:取号、排队、办业务、评分。 其中取号、排队、评分【父类实现】对于大家来说是一样的,办业务【子类实现】根据不同用户是不一样的。
—抽象类
public abstract class BankTemplate {
//银行的业务流程
public void bankWay(){
//取号
System.out.println(getNumber());
//排队
System.out.println(lineUp());
//办业务
System.out.println(processWork());
//评分
System.out.println(mark());
}
public abstract String processWork();
public String getNumber(){
return "获取到号码";
}
public String lineUp(){
return "进行排队";
}
public String mark(){
return "进行评分";
}
}
—V1办理的业务
public class BankTemplateV1 extends BankTemplate {
@Override
public String processWork() {
return "V1 用户来办理 取钱业务。";
}
}
—V2办理的业务
public class BankTemplateV2 extends BankTemplate {
@Override
public String processWork() {
return "v2 用户办理 存钱业务。";
}
}
–测试。
public class TemplateMain {
public static void main(String[] args) {
BankTemplate v1 = new BankTemplateV1();
v1.bankWay();
BankTemplate v2 = new BankTemplateV2();
v2.bankWay();
}
}
2.20 行为型-迭代器模式
2.21 行为型–访问者模式
2.22 行为型–策略模式
策略模式的主要角色如下。
抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
环境(Context)类:持有一个策略类的引用,最终给客户端调用。
具体案例:出门游玩。用户可以根据条件选择不同策略方式【汽车、飞机策略】来出门。
—出现方式接口
public interface TravelStrategy {
public String travelWay();
}
—飞机出行策略
public class AirTravelStrategy implements TravelStrategy {
@Override
public String travelWay() {
return "乘坐飞机出行...";
}
}
—汽车出行策略
public class CarTravelStrategy implements TravelStrategy {
@Override
public String travelWay() {
return "乘坐汽车出行...";
}
}
–环境类
public class Traveler {
private TravelStrategy travelStrategy;
public void setTravelStrategy(TravelStrategy travelStrategy) {
this.travelStrategy = travelStrategy;
}
public void chooseTravel(){
System.out.println(travelStrategy.travelWay());
}
}
–测试
public class TravelerMain {
public static void main(String[] args) {
//环境类持有一个策略的引用
Traveler traveler = new Traveler();
traveler.setTravelStrategy(new CarTravelStrategy());
traveler.chooseTravel();
}
}