大话设计模式 学习笔记

大话设计模式

简单工厂模式

Ex: 写个计算机:

普通实现方式:

package design;

import java.util.Scanner;

public class Operation {
    public static double getResult(double n1,double n2,String operate){
        double res = 0d;
        switch(operate){
            case "+":
                res = n1 + n2;
                break;
            case "-":
                res = n1 - n2;
                break;
            case "*":
                res = n1*n2;
                break;
            case "/":
                res = n1 / n2;
                break;
            case "sqrt":
                res = 0d;
                break;
        }
        return res;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Input n1: ");
        double n1 = Double.parseDouble(sc.nextLine());
        System.out.println("Input operate(+ - * /): ");
        String oper = sc.nextLine();
        System.out.println("Input n2: ");
        double n2 = Double.parseDouble(sc.nextLine());

        double res = getResult(n1,n2,oper);

        System.out.println("res = "+res);
    }
}

简单工厂模式:

package design;

import java.util.Scanner;

public abstract class Operation {
    public double getResult(double n1,double n2){
        double res = 0d;
        return res;
    }
    //test
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Input n1: ");
        double n1 = Double.parseDouble(sc.nextLine());
        System.out.println("Input operate(+ - * /): ");
        String oper = sc.nextLine();
        System.out.println("Input n2: ");
        double n2 = Double.parseDouble(sc.nextLine());

        Operation operate = OperationFactory.createOperate(oper);
        double res = operate.getResult(n1,n2);

        System.out.println("res = "+res);
    }
}
class Add extends Operation{
    @Override
    public double getResult(double n1, double n2) {
        return n1+n2;
    }
}
class Sub extends Operation{
    @Override
    public double getResult(double n1, double n2) {
        return n1-n2;
    }
}
class Mul extends Operation{
    @Override
    public double getResult(double n1, double n2) {
        return n1*n2;
    }
}
class Div extends Operation{
    @Override
    public double getResult(double n1, double n2) {
        if(n2 == 0){
            System.out.println("error");
            throw new ArithmeticException();
        }
        return n1/n2;
    }
}
class OperationFactory{
    public static Operation createOperate(String operate){
        Operation oper = null;
        switch(operate){
            case "+":
                oper = new Add();
                break;
            case "-":
                oper = new Sub();
                break;
            case "*":
                oper = new Mul();
                break;
            case "/":
                oper = new Div();
                break;
        }
        return oper;
    }
}

策略模式

Ex:商场打折案例(折扣,满减 混搭):

简单工厂实现:

package design;

public abstract class CashSuper {
    public abstract double acceptCash(double price, int num);
}
class CashNormal extends CashSuper{

    @Override
    public double acceptCash(double price, int num) {
        return price*num;
    }
}
class CashRebate extends CashSuper{
    private double moneyRebate = 1d;
    public CashRebate(double moneyRebate){
        this.moneyRebate = moneyRebate;
    }
    @Override
    public double acceptCash(double price, int num) {
        return price*num*moneyRebate;
    }
}
class CashReturn extends CashSuper{
    private double moneyCondition = 0d;
    private double moneyReturn = 0d;
    public CashReturn(double moneyCondition,double moneyReturn){
        this.moneyCondition = moneyCondition;
        this.moneyReturn = moneyReturn;
    }
    @Override
    public double acceptCash(double price, int num) {
        double result = price*num;
        if(moneyCondition>0 && result>=moneyCondition){
            result = result - Math.floor(result/moneyCondition)*moneyReturn;
        }
        return result;
    }
}
class CashFactory{
    public static CashSuper createCashAccept(int cashType){
        CashSuper cs = null;
        switch(cashType){
            case 1:
                cs = new CashNormal();
                break;
            case 2:
                cs = new CashRebate(0.8d);
                break;
            case 3:
                cs = new CashRebate(0.7d);
                break;
            case 4:
                cs = new CashReturn(300d,100d);
                break;
        }
        return cs;
    }
}
class CashSuperTest{
    public static void main(String[] args) {
        double total=0d;
        double price=1d;
        int num=2;
        
        CashSuper cashSuper = CashFactory.createCashAccept(1);
        double totalPrices = cashSuper.acceptCash(price, num);
        total += totalPrices;
    }
}

策略模式实现:

package design;

public abstract class CashSuper {
    public abstract double acceptCash(double price, int num);
}
class CashNormal extends CashSuper{

    @Override
    public double acceptCash(double price, int num) {
        return price*num;
    }
}
class CashRebate extends CashSuper{
    private double moneyRebate = 1d;
    public CashRebate(double moneyRebate){
        this.moneyRebate = moneyRebate;
    }
    @Override
    public double acceptCash(double price, int num) {
        return price*num*moneyRebate;
    }
}
class CashReturn extends CashSuper{
    private double moneyCondition = 0d;
    private double moneyReturn = 0d;
    public CashReturn(double moneyCondition,double moneyReturn){
        this.moneyCondition = moneyCondition;
        this.moneyReturn = moneyReturn;
    }
    @Override
    public double acceptCash(double price, int num) {
        double result = price*num;
        if(moneyCondition>0 && result>=moneyCondition){
            result = result - Math.floor(result/moneyCondition)*moneyReturn;
        }
        return result;
    }
}

class CashContext{
    private CashSuper cs;
    public CashContext(CashSuper csuper){
        this.cs = csuper;
    }
    public double getResult(double price, int num){
        return cs.acceptCash(price,num);
    }
}
class CashSuperTest{
    public static void main(String[] args) {
        double total=0d;
        double price=1d;
        int num=2;

        CashContext cc = null;
        switch(1){
            case 1:
                cc = new CashContext(new CashNormal());
                break;
            case 2:
                cc = new CashContext(new CashRebate(0.8d));
                break;
            case 3:
                cc = new CashContext(new CashRebate(0.7d));
                break;
            case 4:
                cc = new CashContext(new CashReturn(300d,100d));
                break;
        }
        double totalPrices = cc.getResult(price, num);
        total += totalPrices;

    }
}

策略与简单工厂结合:

package design;

public abstract class CashSuper {
    public abstract double acceptCash(double price, int num);
}
class CashNormal extends CashSuper{

    @Override
    public double acceptCash(double price, int num) {
        return price*num;
    }
}
class CashRebate extends CashSuper{
    private double moneyRebate = 1d;
    public CashRebate(double moneyRebate){
        this.moneyRebate = moneyRebate;
    }
    @Override
    public double acceptCash(double price, int num) {
        return price*num*moneyRebate;
    }
}
class CashReturn extends CashSuper{
    private double moneyCondition = 0d;
    private double moneyReturn = 0d;
    public CashReturn(double moneyCondition,double moneyReturn){
        this.moneyCondition = moneyCondition;
        this.moneyReturn = moneyReturn;
    }
    @Override
    public double acceptCash(double price, int num) {
        double result = price*num;
        if(moneyCondition>0 && result>=moneyCondition){
            result = result - Math.floor(result/moneyCondition)*moneyReturn;
        }
        return result;
    }
}
class CashFactory{
    public static CashSuper createCashAccept(int cashType){
        CashSuper cs = null;
        switch(cashType){
            case 1:
                cs = new CashNormal();
                break;
            case 2:
                cs = new CashRebate(0.8d);
                break;
            case 3:
                cs = new CashRebate(0.7d);
                break;
            case 4:
                cs = new CashReturn(300d,100d);
                break;
        }
        return cs;
    }
}
class CashContext{
    private CashSuper cs;
    public CashContext(int cashType){
        switch(cashType){
            case 1:
                cs = new CashNormal();
                break;
            case 2:
                cs = new CashRebate(0.8d);
                break;
            case 3:
                cs = new CashRebate(0.7d);
                break;
            case 4:
                cs = new CashReturn(300d,100d);
                break;
        }
    }
    public double getResult(double price, int num){
        return cs.acceptCash(price,num);
    }
}
class CashSuperTest{
    public static void main(String[] args) {
        double total=0d;
        double price=1d;
        int num=2;
        double totalPrices;

        //简单工厂模式的用法
        CashSuper cashSuper = CashFactory.createCashAccept(1);
        totalPrices = cashSuper.acceptCash(price, num);

        //策略模式和简单工厂模式结合的用法
        CashContext cc = new CashContext(1);
        totalPrices = cc.getResult(price, num);

        total += totalPrices;

    }
}

简单工厂模式让客户端认识两个类
策略模式和简单工厂模式结合的用法,客户端只需要认识一个类

单一职责原则

开放-封闭原则

对于扩展是开放的,对于修改是封闭的

依赖倒转原则

针对接口编程。

  1. 高层模块不应该依赖底层模块。两个都应该依赖抽象
  2. 抽象不应该依赖细节。细节应该依赖抽象

装饰模式(hard)

EX: 穿衣案例

package design;

//Component
interface ICharacter{
    public void show();
}

//ConcreteComponent
class Person implements ICharacter{
    private String name;
    public Person(String name){
        this.name = name;
    }
    @Override
    public void show() {
        System.out.println("装扮的"+name);
    }
}

//Decorator
class Finery implements ICharacter{
    protected ICharacter component;
    public void decorate(ICharacter component){////////关键点、、、、、
        this.component = component;
    }
    @Override
    public void show() {
        if(this.component != null){
            this.component.show();
        }
    }
}

//ConcreteDecorator
class TShirts extends Finery{
    public void show(){
        System.out.print("大T恤");
        super.show();
    }
}
class Sneakers extends Finery{
    public void show(){
        System.out.print("球鞋");
        super.show();
    }
}
class BigTrouser extends Finery{
    public void show(){
        System.out.print("垮裤");
        super.show();
    }
}

public class Decorate {
    public static void main(String[] args) {
        Person xc = new Person("小菜");
        System.out.println("====one====");

        Sneakers sneakers = new Sneakers();
        sneakers.decorate(xc);
        BigTrouser bigTrouser = new BigTrouser();
        bigTrouser.decorate(sneakers);
        TShirts tShirts = new TShirts();
        tShirts.decorate(bigTrouser);

        tShirts.show();//大T恤垮裤球鞋装扮的小菜
    }
}

简单工厂+策略+装饰模式:

Ex:商场打折案例(折扣,满减 混搭):升级

package design;

import com.sun.xml.internal.ws.addressing.WsaActionUtil;

interface ISale{
    public double acceptCash(double price, int num);
}
public class CashSuper implements ISale {
    protected ISale component;
    public void decorate(ISale component){////////关键点、、、、、
        this.component = component;
    }
    public double acceptCash(double price, int num){
        double result = 0d;
        if(this.component!=null){
            result = this.component.acceptCash(price,num);
        }
        return result;
    }
}
class CashNormal implements ISale{

    @Override
    public double acceptCash(double price, int num) {
        return price*num;
    }
}
class CashRebate extends CashSuper{
    private double moneyRebate = 1d;
    public CashRebate(double moneyRebate){
        this.moneyRebate = moneyRebate;
    }
    @Override
    public double acceptCash(double price, int num) {
        double result = price*num*moneyRebate;
        return super.acceptCash(result,1);
    }
}
class CashReturn extends CashSuper{
    private double moneyCondition = 0d;
    private double moneyReturn = 0d;
    public CashReturn(double moneyCondition,double moneyReturn){
        this.moneyCondition = moneyCondition;
        this.moneyReturn = moneyReturn;
    }
    @Override
    public double acceptCash(double price, int num) {
        double result = price*num;
        if(moneyCondition>0 && result>=moneyCondition){
            result = result - Math.floor(result/moneyCondition)*moneyReturn;
        }
        return super.acceptCash(result,1);
    }
}
class CashFactory{
    public static ISale createCashAccept(int cashType){
        ISale cs = null;
        switch(cashType){
            case 1:
                cs = new CashNormal();
                break;
            case 2:
                cs = new CashRebate(0.8d);
                break;
            case 3:
                cs = new CashRebate(0.7d);
                break;
            case 4:
                cs = new CashReturn(300d,100d);
                break;
            case 5:
                //先打八折,再满300-100
                CashNormal cn = new CashNormal();
                CashReturn cr1 = new CashReturn(300d,100d);
                CashRebate cr2 = new CashRebate(0.8d);
                cr1.decorate(cn);
                cr2.decorate(cr1);
                cs = cr2;
                break;
        }
        return cs;
    }
}
class CashContext{
    private ISale cs;
    public CashContext(int cashType){
        switch(cashType){
            case 1:
                cs = new CashNormal();
                break;
            case 2:
                cs = new CashRebate(0.8d);
                break;
            case 3:
                cs = new CashRebate(0.7d);
                break;
            case 4:
                cs = new CashReturn(300d,100d);
                break;
            case 5:
                //先打八折,再满300-100
                CashNormal cn = new CashNormal();
                CashReturn cr1 = new CashReturn(300d,100d);
                CashRebate cr2 = new CashRebate(0.8d);
                cr1.decorate(cn);
                cr2.decorate(cr1);
                this.cs = cr2;
                break;
            case 6:
                //先满200-50,再打七折
                CashNormal cn2 = new CashNormal();
                CashReturn cr3 = new CashReturn(200d, 50d);
                CashRebate cr4 = new CashRebate(0.7d);
                cr4.decorate(cn2);
                cr3.decorate(cr4);
                this.cs = cr3;
                break;
        }
    }
    public double getResult(double price, int num){
        return cs.acceptCash(price,num);
    }
}
class CashSuperTest{
    public static void main(String[] args) {
        double total=0d;
        double price=200d;
        int num=2;
        double totalPrices;

        //简单工厂模式的用法 + 装饰
        ISale cashSuper = CashFactory.createCashAccept(5);
        totalPrices = cashSuper.acceptCash(price, num);//220

        //策略模式和简单工厂模式结合的用法 + 装饰
        CashContext cc = new CashContext(6);
        totalPrices = cc.getResult(price, num);//210

        total += totalPrices;

        System.out.println(total);//210

    }
}

优点:把类中的装饰功能从类中搬移去除(不懂),这样可以简化原有的类。有效的把类的核心职责和装饰功能区分开。而且可以去除相关中重复的装饰逻辑。

代理模式

Ex:追求者找代理送礼物

package design;

//被追求者类
class SchoolGirl{
    private String name;
    public SchoolGirl(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

//送礼物接口
interface IGiveGift{
    void giveDolls();
    void giveFlowers();
    void giveChocolate();
}

//追求者类
class Pursuit implements IGiveGift{
    private SchoolGirl mm;
    public Pursuit(SchoolGirl mm){
        this.mm = mm;
    }
    @Override
    public void giveDolls() {
        System.out.println(mm.getName()+", hi! give dolls");
    }

    @Override
    public void giveFlowers() {
        System.out.println(mm.getName()+", hi! give flowers");
    }

    @Override
    public void giveChocolate() {
        System.out.println(mm.getName()+", hi! give chocolate");
    }
}

//代理类
class Proxy implements IGiveGift{
    private Pursuit gg;//认识追求者
    public Proxy(SchoolGirl mm){//也认识追求者
        this.gg = new Pursuit(mm);//代理初始化的过程,实际是追求者的初始化的过程
    }
    @Override
    public void giveDolls() {//代理在送礼物
        gg.giveDolls();     //实质是追求者在送礼物
    }

    @Override
    public void giveFlowers() {
        gg.giveFlowers();
    }

    @Override
    public void giveChocolate() {
        gg.giveChocolate();
    }
}
public class ProxyTest {
    public static void main(String[] args) {
        SchoolGirl girl = new SchoolGirl("小美");

        Proxy proxy = new Proxy(girl);
        proxy.giveDolls();
        proxy.giveFlowers();
        proxy.giveChocolate();
    }
}

应用场景:

  1. 远程代理:为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实
  2. 虚拟代理:根据需要创建开销很大的对象。通过他来存放实例化需要很长时间的真实对象
  3. 安全代理:用来控制真实对象访问时的权限
  4. 智能指引,是指当调用真实的对象时,代理处理另外一些事。

工厂方法模式

Ex:计算机升级:

package design;

import java.util.Scanner;

public abstract class Operation {
    public double getResult(double n1,double n2){
        double res = 0d;
        return res;
    }
    //test
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Input n1: ");
        double n1 = Double.parseDouble(sc.nextLine());
        System.out.println("Input operate(+ - * /): ");
        String oper = sc.nextLine();
        System.out.println("Input n2: ");
        double n2 = Double.parseDouble(sc.nextLine());

        Operation operate = OperationFactory.createOperate(oper);
        double res = operate.getResult(n1,n2);

        System.out.println("res = "+res);
    }
}
class Add extends Operation{
    @Override
    public double getResult(double n1, double n2) {
        return n1+n2;
    }
}
class Sub extends Operation{
    @Override
    public double getResult(double n1, double n2) {
        return n1-n2;
    }
}
class Mul extends Operation{
    @Override
    public double getResult(double n1, double n2) {
        return n1*n2;
    }
}
class Div extends Operation{
    @Override
    public double getResult(double n1, double n2) {
        if(n2 == 0){
            System.out.println("error");
            throw new ArithmeticException();
        }
        return n1/n2;
    }
}
class Pow extends Operation{
    public double getResult(double a,double b){
        return Math.pow(a,b);
    }
}
class Log extends Operation{
    public double getResult(double a,double b){
        return Math.log(b)/Math.log(a);
    }
}
interface IFactory{
    public Operation createOperation(String operType);
}
//基础运算工厂
class FactoryBasic implements IFactory{
    @Override
    public Operation createOperation(String operType) {
        Operation oper = null;
        switch(operType){
            case "+":
                oper = new Add();
                break;
            case "-":
                oper = new Sub();
                break;
            case "*":
                oper = new Mul();
                break;
            case "/":
                oper = new Div();
                break;
        }
        return oper;
    }
}
//高级运算工厂
class FactoryAdvanced implements IFactory{
    @Override
    public Operation createOperation(String operType) {
        Operation oper = null;
        switch(operType){
            case "pow":
                oper = new Pow();
                break;
            case "log":
                oper = new Log();
                break;
        }
        return oper;
    }
}
class OperationFactory{
    public static Operation createOperate(String operate){
        Operation oper = null;
        IFactory factory = null;
        switch(operate){
            case "+":
            case "-":
            case "*":
            case "/":
                factory = new FactoryBasic();
                break;
            case "pow":
            case "log":
                factory = new FactoryAdvanced();
                break;
        }
        oper = factory.createOperation(operate);
        return oper;
    }
}


当只有一个工厂时,是简单工厂模式。
当有多个工厂时,就是工厂方法模式。

简单工厂+策略+装饰+工厂方法:

Ex:打折满减案例:

package design;

import com.sun.xml.internal.ws.addressing.WsaActionUtil;

interface ISale{
    public double acceptCash(double price, int num);
}
public class CashSuper implements ISale {
    protected ISale component;
    public void decorate(ISale component){
        this.component = component;
    }
    public double acceptCash(double price, int num){
        double result = 0d;
        if(this.component!=null){
            result = this.component.acceptCash(price,num);
        }
        return result;
    }
}
class CashNormal implements ISale{

    @Override
    public double acceptCash(double price, int num) {
        return price*num;
    }
}
class CashRebate extends CashSuper{
    private double moneyRebate = 1d;
    public CashRebate(double moneyRebate){
        this.moneyRebate = moneyRebate;
    }
    @Override
    public double acceptCash(double price, int num) {
        double result = price*num*moneyRebate;
        return super.acceptCash(result,1);
    }
}
class CashReturn extends CashSuper{
    private double moneyCondition = 0d;
    private double moneyReturn = 0d;
    public CashReturn(double moneyCondition,double moneyReturn){
        this.moneyCondition = moneyCondition;
        this.moneyReturn = moneyReturn;
    }
    @Override
    public double acceptCash(double price, int num) {
        double result = price*num;
        if(moneyCondition>0 && result>=moneyCondition){
            result = result - Math.floor(result/moneyCondition)*moneyReturn;
        }
        return super.acceptCash(result,1);
    }
}
class CashFactory{
    public static ISale createCashAccept(int cashType){
        ISale cs = null;
        switch(cashType){
            case 1:
                cs = new CashNormal();
                break;
            case 2:
                cs = new CashRebate(0.8d);
                break;
            case 3:
                cs = new CashRebate(0.7d);
                break;
            case 4:
                cs = new CashReturn(300d,100d);
                break;
            case 5:
                //先打八折,再满300-100
                CashNormal cn = new CashNormal();
                CashReturn cr1 = new CashReturn(300d,100d);
                CashRebate cr2 = new CashRebate(0.8d);
                cr1.decorate(cn);
                cr2.decorate(cr1);
                cs = cr2;
                break;
        }
        return cs;
    }
}
class CashContext{
    private ISale cs;
    public CashContext(int cashType){
        switch(cashType){
            case 1:
                cs = new CashNormal();
                break;
            case 2:
                cs = new CashRebate(0.8d);
                break;
            case 3:
                cs = new CashRebate(0.7d);
                break;
            case 4:
                cs = new CashReturn(300d,100d);
                break;
            case 5:
                //先打八折,再满300-100
                CashNormal cn = new CashNormal();
                CashReturn cr1 = new CashReturn(300d,100d);
                CashRebate cr2 = new CashRebate(0.8d);
                cr1.decorate(cn);
                cr2.decorate(cr1);
                this.cs = cr2;
                break;
            case 6:
                //先满200-50,再打七折
                CashNormal cn2 = new CashNormal();
                CashReturn cr3 = new CashReturn(200d, 50d);
                CashRebate cr4 = new CashRebate(0.7d);
                cr4.decorate(cn2);
                cr3.decorate(cr4);
                this.cs = cr3;
                break;
        }
    }
    public double getResult(double price, int num){
        return cs.acceptCash(price,num);
    }
}
interface IFactory2{
    public ISale createSalesModel();
}
//先打折再满减类
class CashRebateReturnFactory implements IFactory2{
    private double moneyRebate = 1d;
    private double moneyCondition = 0d;
    private double moneyReturn = 0d;
    public CashRebateReturnFactory(double moneyRebate,
                                   double moneyCondition,
                                   double moneyReturn){
        this.moneyRebate = moneyRebate;
        this.moneyCondition = moneyCondition;
        this.moneyReturn = moneyReturn;
    }
    @Override
    public ISale createSalesModel() {
        CashNormal cn = new CashNormal();
        CashReturn cr1 = new CashReturn(moneyCondition,moneyReturn);
        CashRebate cr2 = new CashRebate(moneyRebate);
        cr1.decorate(cn);
        cr2.decorate(cr1);
        return cr2;
    }
}
//先满减再打折类
class CashReturnRebateFactory implements IFactory2{
    private double moneyRebate = 1d;
    private double moneyCondition = 0d;
    private double moneyReturn = 0d;
    public CashReturnRebateFactory(double moneyRebate,
                                   double moneyCondition,
                                   double moneyReturn){
        this.moneyRebate = moneyRebate;
        this.moneyCondition = moneyCondition;
        this.moneyReturn = moneyReturn;
    }
    @Override
    public ISale createSalesModel() {
        CashNormal cn = new CashNormal();
        CashReturn cr1 = new CashReturn(moneyCondition,moneyReturn);
        CashRebate cr2 = new CashRebate(moneyRebate);
        cr2.decorate(cn);
        cr1.decorate(cr2);
        return cr1;
    }
}
class CashContext2{
    private ISale cs;
    public CashContext2(int cashType){
        IFactory2 fs = null;
        switch(cashType){
            case 1:
                fs = new CashRebateReturnFactory(1d,0d,0d);
                break;
            case 2:
                fs = new CashRebateReturnFactory(0.8d,0d,0d);
                break;
            case 3:
                fs = new CashRebateReturnFactory(0.7d,0d,0d);
                break;
            case 4:
                fs = new CashRebateReturnFactory(1d,300d,100d);
                break;
            case 5:
                //先打八折,再满300-100
                fs = new CashRebateReturnFactory(0.8d,300d,100d);
                break;
            case 6:
                //先满200-50,再打七折
                fs = new CashReturnRebateFactory(0.7d,200d,50d);
                break;
        }
        this.cs = fs.createSalesModel();
    }
    public double getResult(double price, int num){
        return cs.acceptCash(price,num);
    }
}
class CashSuperTest{
    public static void main(String[] args) {
        double total=0d;
        double price=200d;
        int num=2;
        double totalPrices;

        //简单工厂模式的用法 + 装饰
        ISale cashSuper = CashFactory.createCashAccept(5);
        totalPrices = cashSuper.acceptCash(price, num);

        //策略模式和简单工厂模式结合的用法 + 装饰
        CashContext cc = new CashContext(6);
        totalPrices = cc.getResult(price, num);

        //策略模式和简单工厂模式结合的用法 + 装饰 + 工厂方法
        CashContext2 cc2 = new CashContext2(6);
        totalPrices = cc2.getResult(price, num);

        total += totalPrices;

        System.out.println(total);

    }
}

原型模式

Ex:复制简历

package design;
class Resume implements Cloneable{//不继承会报错
    public String name;
    public Resume(String name){
        this.name = name;
    }

    public Resume clone(){
        Resume object = null;
        try {
            object = (Resume) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
        return object;
    }
}
public class Prototype {
    public static void main(String[] args) {
        Resume r1 = new Resume("one");
        Resume r2 = r1.clone();
        Resume r3 = r1.clone();
        System.out.println(r1.name);
        System.out.println(r2.name);
        System.out.println(r3.name);
    }
}

浅复制与深复制

如果字段是值类型的,则对改字段执行逐位复制,
如果字段是引用类型,则复制引用但不复制引用的对象。因此原始对象及副本引用同一对象。

package design;

class Resume implements Cloneable{
    public String name;
    public WorkExperience work;
    public Resume(String name){
        this.name = name;
    }

    public Resume clone(){
        Resume object = null;
        try {
            object = (Resume) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
        return object;
    }
}
class WorkExperience{
    public String timeArea;
    public String company;
    public WorkExperience(String t,String c){
        timeArea = t;
        company = c;
    }
    public String toString(){
        return timeArea+":"+company;
    }
}
public class Prototype {
    public static void main(String[] args) {
        Resume r1 = new Resume("one");
        WorkExperience work = new WorkExperience("2022", "baidu");
        r1.work  = work;

        Resume r2 = r1.clone();

        System.out.println(r1.name+" "+r1.work);//one 2022:baidu
        System.out.println(r2.name+" "+r1.work);//one 2022:baidu

        //change
        r1.name = "two";
        r1.work.timeArea = "2023";
        r1.work.company = "ali";

        System.out.println(r1.name+" "+r1.work);//two 2023:ali
        System.out.println(r2.name+" "+r1.work);//one 2023:ali

    }
}

深复制实现

package design;

class Resume implements Cloneable{
    public String name;
    public WorkExperience work;
    public Resume(String name){
        this.name = name;
    }

    public Resume clone(){
        Resume object = null;
        try {
            object = (Resume) super.clone();
            object.work = this.work.clone(); //////////// 2
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
        return object;
    }
}
class WorkExperience implements Cloneable{ ///////////// 1
    public String timeArea;
    public String company;
    public WorkExperience(String t,String c){
        timeArea = t;
        company = c;
    }
    public String toString(){
        return timeArea+":"+company;
    }
    public WorkExperience clone(){
        WorkExperience object = null;
        try {
            object = (WorkExperience) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
        return object;
    }
}
public class Prototype {
    public static void main(String[] args) {
        Resume r1 = new Resume("one");
        WorkExperience work = new WorkExperience("2022", "baidu");
        r1.work  = work;

        Resume r2 = r1.clone();

        System.out.println(r1.name+" "+r1.work);//one 2022:baidu
        System.out.println(r2.name+" "+r2.work);//one 2022:baidu

        //change
        r1.name = "two";
        r1.work.timeArea = "2023";
        r1.work.company = "ali";

        System.out.println(r1.name+" "+r1.work);//two 2023:ali
        System.out.println(r2.name+" "+r2.work);//one 2022:baidu

    }
}

模版方法模式

定义一个操作中的骨架,而将一些步骤延迟到子类中。模版方法是的子类可以不改变一个算法的结构即可重定义改算法的某些特定步骤。

Ex:同套试卷两个学生答题:

package design;
abstract class TestPaper{
    public void testQuestion1(){
        System.out.println("queation1:...");
        System.out.println("answer:"+this.answer1());
    }
    protected abstract String answer1();

    public void testQuestion2(){
        System.out.println("queation2:...");
        System.out.println("answer:"+this.answer2());
    }
    protected abstract String answer2();
}
class TestPaperA extends TestPaper{
    @Override
    protected String answer1() {
        return "a";
    }
    @Override
    protected String answer2() {
        return "b";
    }
}
class TestPaperB extends TestPaper{
    @Override
    protected String answer1() {
        return "c";
    }
    @Override
    protected String answer2() {
        return "d";
    }
}
public class PaperTest {
    public static void main(String[] args) {
        System.out.println("student A test paper:");
        TestPaper studentA = new TestPaperA();
        studentA.testQuestion1();
        studentA.testQuestion2();
        System.out.println("student B test paper:");
        TestPaper studentB = new TestPaperB();
        studentB.testQuestion1();
        studentB.testQuestion2();
    }
}

  • 模版方法模式通过把不变的行为搬移到超类,取出子类中重复代码来体现他的优势
  • 提供了一个很好的代码复用平台。

迪米特法则

如果两个类不必彼此直接通信,那么这两个类就不应该发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

  • 在类的结构设计上,每一个类都应当尽量降低成员的访问权限
  • 强调类之间的松耦合
  • 类之间的耦合越弱,越有利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成波及。

外观模式

外观模式,为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

package design;
class Stock1{
    public void sell(){
        System.out.println("stock1 sell");
    }
    public void buy(){
        System.out.println("stock1 buy");
    }
}
class Stock2{
    public void sell(){
        System.out.println("stock2 sell");
    }
    public void buy(){
        System.out.println("stock2 buy");
    }
}
class NationalDebt1{
    public void sell(){
        System.out.println("nationaldebt1 sell");
    }
    public void buy(){
        System.out.println("nationaldebt1 buy");
    }
}
class Realty1{
    public void sell(){
        System.out.println("Realty1 sell");
    }
    public void buy(){
        System.out.println("Realty1 buy");
    }
}
class Fund{
    Stock1 stock1;
    Stock2 stock2;
    NationalDebt1 nd1;
    Realty1 rt1;
    public Fund(){
        stock1 = new Stock1();
        stock2 = new Stock2();
        nd1 = new NationalDebt1();
        rt1 = new Realty1();
    }
    public void sellFund(){
        stock1.sell();
        stock2.sell();
        nd1.sell();
        rt1.sell();
    }
    public void buyFund(){
        stock1.buy();
        stock2.buy();
        nd1.buy();
        rt1.buy();
    }
}

public class StockTest {
    public static void main(String[] args) {
        Fund fund = new Fund();
        fund.buyFund();
        fund.sellFund();
    }
}

建造者模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

Ex:画个瘦子,画个胖子

package design;

import com.sun.corba.se.impl.orbutil.graph.Graph;

import javax.swing.*;
import java.awt.*;

abstract class PersonBuilder{
    protected Graphics g;
    public PersonBuilder(Graphics g){
        this.g = g;
    }
    public abstract void buildHead();
    public abstract void buildBody();
    public abstract void buildArmLeft();
    public abstract void buildArmRight();
    public abstract void buildLegLeft();
    public abstract void buildLegRight();
}

//瘦子
class PersonThinBuilder extends PersonBuilder{

    public PersonThinBuilder(Graphics g){
        super(g);
    }
    @Override
    public void buildHead() {
        g.drawOval(150,120,30,30);//head
    }
    @Override
    public void buildBody() {
        g.drawRect(160,150,10,50);//body
    }
    @Override
    public void buildArmLeft() {
        g.drawLine(160,150,140,200);
    }
    @Override
    public void buildArmRight() {
        g.drawLine(170,150,190,200);
    }
    @Override
    public void buildLegLeft() {
        g.drawLine(160,200,145,250);
    }
    @Override
    public void buildLegRight() {
        g.drawLine(170,200,185,250);
    }
}

//胖子
class PersonFatBuilder extends PersonBuilder{

    public PersonFatBuilder(Graphics g){
        super(g);
    }
    @Override
    public void buildHead() {
        g.drawOval(150,120,30,30);//head
    }
    @Override
    public void buildBody() {
        g.drawOval(160,150,10,50);//body
    }
    @Override
    public void buildArmLeft() {
        g.drawLine(160,150,140,200);
    }
    @Override
    public void buildArmRight() {
        g.drawLine(170,150,190,200);
    }
    @Override
    public void buildLegLeft() {
        g.drawLine(160,200,145,250);
    }
    @Override
    public void buildLegRight() {
        g.drawLine(170,200,185,250);
    }
}

//指挥者
class PersonDirector{
    private PersonBuilder pb;
    public PersonDirector(PersonBuilder pb){
        this.pb = pb;
    }
    public void CreatePerson(){
        pb.buildHead();
        pb.buildBody();
        pb.buildArmLeft();
        pb.buildArmRight();
        pb.buildLegLeft();
        pb.buildLegRight();
    }
}
public class CreaterTest extends JFrame {
    public CreaterTest(){
        setSize(400,400);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }
    public void paint(Graphics g){
//        PersonThinBuilder gThin = new PersonThinBuilder(g);
//        PersonDirector pdThin = new PersonDirector(gThin);
//        pdThin.CreatePerson();

        PersonFatBuilder gFat = new PersonFatBuilder(g);
        PersonDirector pdFat = new PersonDirector(gFat);
        pdFat.CreatePerson();
    }

    public static void main(String[] args) {
        new CreaterTest().setVisible(true);
    }
}

观察者模式

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。

package design;

import java.util.ArrayList;
//import java.util.Observer;

//通知者接口
abstract class Subject{
    protected String name;
    public Subject(String name){
        this.name = name;
    }
    //同事列表
    private ArrayList<Observer> list = new ArrayList<Observer>();
    private String action;
    public void attach(Observer observer){
        list.add(observer);
    }
    public void detach(Observer observer){
        list.remove(observer);
    }
    public void notifyEmployee(){
        //给所有登记过的同事发通知
        for(Observer item:list){
            item.update();
        }
    }
    //得到状态
    public String getAction(){
        return action;
    }
    //设置状态,就是设置具体通知的话
    public void setAction(String value){
        action = value;
    }
}
//老板
class Boss extends Subject{
    public Boss(String name) {
        super(name);
    }
}
//前台类
class Secretary extends Subject{
    public Secretary(String name) {
        super(name);
    }
}

//抽象观察者
abstract class Observer{
    protected String name;
    protected Subject sub;
    public Observer(String name,Subject sub){
        this.name = name;
        this.sub = sub;
    }
    public abstract void update();
}
//看股票同事类
class StockObserver extends Observer{
    public StockObserver(String name,Subject sub){
        super(name,sub);
    }
    public void update(){
        System.out.println(sub.name+": "+sub.getAction()+"! "+name+",close stock and working!");
    }
}
//看nba同事类
class NBAObserver extends Observer{
    public NBAObserver(String name,Subject sub){
        super(name,sub);
    }
    public void update(){
        System.out.println(sub.name+": "+sub.getAction()+"! "+name+",close NBS and working!");
    }
}
public class ObserverTest {
    public static void main(String[] args) {
        Boss boss = new Boss("wang");

        StockObserver liu = new StockObserver("liu", boss);
        NBAObserver dong = new NBAObserver("dong", boss);

        boss.attach(liu);
        boss.attach(dong);

        boss.setAction("i am come back");
        boss.notifyEmployee();
    }
}

jdk提供了接口

import java.util.Observable; //可被观察
import java.util.Observer; //观察者

package design;

import java.util.Observable;
import java.util.Observer;

class Boss2 extends Observable{
    protected String name;
    private String action;
    public Boss2(String name){
        this.name = name;
    }
    public String getAction(){
        return action;
    }
    public void setAction(String action){
        this.action = action;
        //改变通知者的状态
        super.setChanged();
        //调用父类Observable方法,通知所有观察者
        super.notifyObservers();
    }
}
class StockObserver2 implements Observer{
    protected String name;
    public StockObserver2(String name){
        this.name = name;
    }
    @Override
    public void update(Observable o, Object arg) {
        Boss2 b = (Boss2)o;
        System.out.println(b.name+": "+b.getAction()+"! "+this.name+",close stock and working");
    }
}
public class JDKObserverTest {
    public static void main(String[] args) {
        Boss2 boss2 = new Boss2("Wang");
        StockObserver2 liu = new StockObserver2("liu");
        boss2.addObserver(liu);
        boss2.setAction("i am come back");
    }
}

抽象工厂模式

提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类

package design;
class User{
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
class Department{
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
interface IUser{
    public void insert(User user);
    public User getUser(int id);
}
interface IDepartment{
    public void insert(Department department);
    public Department getDepartment(int id);
}
//user
class SqlserverUser implements IUser{

    @Override
    public void insert(User user) {
        System.out.println("sqlserver add user list");
    }

    @Override
    public User getUser(int id) {
        System.out.println("sqlserver get user list");
        return null;
    }
}
class AccessUser implements IUser{

    @Override
    public void insert(User user) {
        System.out.println("access add user list");
    }

    @Override
    public User getUser(int id) {
        System.out.println("access get user list");
        return null;
    }
}

//department
class SqlserverDepartment implements IDepartment{

    @Override
    public void insert(Department department) {
        System.out.println("sqlserver add Department list");
    }

    @Override
    public Department getDepartment(int id) {
        System.out.println("sqlserver get Department list");
        return null;
    }
}
class AccessDepartment implements IDepartment{

    @Override
    public void insert(Department department) {
        System.out.println("Access add Department list");
    }

    @Override
    public Department getDepartment(int id) {
        System.out.println("Access get Department list");
        return null;
    }
}

interface IFactory3{
    public IUser createUser();
    public IDepartment createDepartment();
}
class SqlserverFactory implements IFactory3{

    @Override
    public IUser createUser() {
        return new SqlserverUser();
    }

    @Override
    public IDepartment createDepartment() {
        return new SqlserverDepartment();
    }
}
class AccessFactory implements IFactory3{

    @Override
    public IUser createUser() {
        return new AccessUser();
    }

    @Override
    public IDepartment createDepartment() {
        return new AccessDepartment();
    }
}
public class AbstractFactoryTest {
    public static void main(String[] args) {
        User user = new User();
        Department department1 = new Department();
        IFactory3 factory = new SqlserverFactory();

        IUser iu = factory.createUser();
        iu.insert(user);
        iu.getUser(1);

        IDepartment department = factory.createDepartment();
        department.insert(department1);
        department.getDepartment(1);
    }
}

用简单工厂来改进抽象工厂模式

package design;
class User{
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
class Department{
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
interface IUser{
    public void insert(User user);
    public User getUser(int id);
}
interface IDepartment{
    public void insert(Department department);
    public Department getDepartment(int id);
}
//user
class SqlserverUser implements IUser{

    @Override
    public void insert(User user) {
        System.out.println("sqlserver add user list");
    }

    @Override
    public User getUser(int id) {
        System.out.println("sqlserver get user list");
        return null;
    }
}
class AccessUser implements IUser{

    @Override
    public void insert(User user) {
        System.out.println("access add user list");
    }

    @Override
    public User getUser(int id) {
        System.out.println("access get user list");
        return null;
    }
}

//department
class SqlserverDepartment implements IDepartment{

    @Override
    public void insert(Department department) {
        System.out.println("sqlserver add Department list");
    }

    @Override
    public Department getDepartment(int id) {
        System.out.println("sqlserver get Department list");
        return null;
    }
}
class AccessDepartment implements IDepartment{

    @Override
    public void insert(Department department) {
        System.out.println("Access add Department list");
    }

    @Override
    public Department getDepartment(int id) {
        System.out.println("Access get Department list");
        return null;
    }
}
class DataAccess{
    private static String db = "Sqlserver";
    public static IUser createUser(){
        IUser result = null;
        switch(db){
            case "Sqlserver":
                result = new SqlserverUser();
                break;
            case "Access":
                result = new AccessUser();
                break;
        }
        return result;
    }
    public static IDepartment createDepartment(){
        IDepartment result = null;
        switch(db){
            case "Sqlserver":
                result = new SqlserverDepartment();
                break;
            case "Access":
                result = new AccessDepartment();
                break;
        }
        return result;
    }
}
public class AbstractFactoryTest {
    public static void main(String[] args) {
        User user = new User();
        Department department1 = new Department();

        IUser iu = DataAccess.createUser();
        iu.insert(user);
        iu.getUser(1);

        IDepartment department = DataAccess.createDepartment();
        department.insert(department1);
        department.getDepartment(1);
    }
}

反射+抽象工厂的数据访问程序

不带参数的反射案例:

反射写法:

Object result = Class.forName("com.design.abstractfactory.SqlserverUser").getDeclaredConstructor().newInstance();
import java.lang.reflect.InvocationTargetException;

class DataAccess{
    private static String assemblyName = "com.design.abstractfactory.";//包名-前缀
    private static String db = "Access";
    public static IUser createUser(){
        return (IUser)getInstance(assemblyName+db+"User");
    }
    public static IDepartment createDepartment(){
        return (IDepartment)getInstance(assemblyName+db+"Department");
    }
    public static Object getInstance(String className){
        Object result = null;
        try {
            //反射
            result = Class.forName(className).getDeclaredConstructor().newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return result;
    }
}

反射+配置文件实现数据访问程序

添加一个db.properties文件到目录下

db=Sqlserver
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;

class DataAccess{
    private static String assemblyName = "design.";
//    private static String db = "Access";
    private static String db = getDb();
    public static IUser createUser(){
        return (IUser)getInstance(assemblyName+db+"User");
    }
    public static IDepartment createDepartment(){
        return (IDepartment)getInstance(assemblyName+db+"Department");
    }
    public static Object getInstance(String className){
        Object result = null;
        try {
            //反射
            result = Class.forName(className).getDeclaredConstructor().newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return result;
    }
    
    //读取配置文件
    public static String getDb(){
        String result = null;
        try{
            Properties properties = new Properties();
            String path = System.getProperty("user.dir")+ "\\src\\design\\db.properties";
//            path = "design/db.properties";
            System.out.println(path);
            BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
            properties.load(bufferedReader);
            result = properties.getProperty("db");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return result;
    }
}

所有在用简单工厂的地方,都可以考虑用反射技术来去除 switch 或 if ,解除分支判断带来的耦合。

商店收银程序再升级

带参数的反射案例:

原来的:

class CashContext2{
    private ISale cs;
    public CashContext2(int cashType){
        IFactory2 fs = null;
        switch(cashType){
            case 1:
                fs = new CashRebateReturnFactory(1d,0d,0d);
                break;
            case 2:
                fs = new CashRebateReturnFactory(0.8d,0d,0d);
                break;
            case 3:
                fs = new CashRebateReturnFactory(0.7d,0d,0d);
                break;
            case 4:
                fs = new CashRebateReturnFactory(1d,300d,100d);
                break;
            case 5:
                //先打八折,再满300-100
                fs = new CashRebateReturnFactory(0.8d,300d,100d);
                break;
            case 6:
                //先满200-50,再打七折
                fs = new CashReturnRebateFactory(0.7d,200d,50d);
                break;
        }
        this.cs = fs.createSalesModel();
    }
    public double getResult(double price, int num){
        return cs.acceptCash(price,num);
    }
}

改进后:

添加一个data.properties

strategy1=CashRebateReturnFactory,1d,0d,0d
strategy2=CashRebateReturnFactory,0.8d,0d,0d
strategy3=CashRebateReturnFactory,0.7d,0d,0d
strategy4=CashRebateReturnFactory,1d,300d,100d
strategy5=CashRebateReturnFactory,0.8d,300d,100d
strategy6=CashReturnRebateFactory,0.7d,200d,50d
class CashContext2{
    private static String assemblyName = "design.";
    private ISale cs;
    public CashContext2(int cashType){
        String[] config = getConfig(cashType).split(",");
        IFactory2 fs = getInstance(config[0],
                Double.parseDouble(config[1]),
                Double.parseDouble(config[2]),
                Double.parseDouble(config[3]));
        this.cs = fs.createSalesModel();
    }
    private String getConfig(int number){
        String result = "";
        try{
            Properties properties = new Properties();
            String path = System.getProperty("user.dir") + "/src/design/data.properties";
            System.out.println(path);
            BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
            properties.load(bufferedReader);
            result = properties.getProperty("strategy"+number);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return result;
    }
    private IFactory2 getInstance(String className,double a,double b,double c){
        IFactory2 result = null;
        try{
            result = (IFactory2) Class.forName(assemblyName+className)
                    .getDeclaredConstructor(new Class[]{double.class,double.class,double.class})
                    .newInstance(new Object[]{a,b,c});
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    public double getResult(double price, int num){
        return cs.acceptCash(price,num);
    }
}

状态模式

当一个对象的内在状态改变时允许改变其行动,这个对象看起来是改变了其类。

package design;
class Work{
    private int hour;
    private boolean workFinished = false;
    private State current;

    public Work(){
        current = new ForenoonState();
    }
    public void setState(State value){
        current = value;
    }
    public void writeProgram(){
        current.writeProgram(this);
    }

    public int getHour() {
        return hour;
    }
    public void setHour(int hour) {
        this.hour = hour;
    }
    public boolean isWorkFinished() {
        return workFinished;
    }
    public void setWorkFinished(boolean workFinished) {
        this.workFinished = workFinished;
    }
}
abstract class State{
    public abstract void writeProgram(Work w);
}
//上午工作状态
class ForenoonState extends State{

    @Override
    public void writeProgram(Work w) {
        if(w.getHour()<12){
            System.out.println("当前时间:"+w.getHour()+"点 上午工作,精神百倍");
        }else{
            w.setState(new NoonState());
            w.writeProgram();
        }
    }
}
//中午工作状态
class NoonState extends State{
    public void writeProgram(Work w){
        if(w.getHour()<13){
            System.out.println("当前时间:"+w.getHour()+"点 饿了,午饭;犯困,午休");
        }else{
            w.setState(new AfternoonState());
            w.writeProgram();
        }
    }
}
//下午工作状态
class AfternoonState extends State{

    @Override
    public void writeProgram(Work w) {
        if(w.getHour()<17){
            System.out.println("当前时间:"+w.getHour()+"点 下午状态还不错,继续努力");
        }else{
            w.setState(new EveningState());
            w.writeProgram();
        }
    }
}
//晚间工作状态
class EveningState extends State{

    @Override
    public void writeProgram(Work w) {
        if(w.isWorkFinished()){
            w.setState(new RestState());
            w.writeProgram();
        }else{
            if(w.getHour()<21){
                System.out.println("当前时间:"+w.getHour()+"点 加班,疲累至极");
            }else{
                w.setState(new SleepingState());
                w.writeProgram();
            }
        }

    }
}
//睡眠状态
class SleepingState extends State{
    @Override
    public void writeProgram(Work w) {
        System.out.println("当前时间:"+w.getHour()+"点 不行了,睡着了");
    }
}
//下班休息状态
class RestState extends State{
    @Override
    public void writeProgram(Work w) {
        System.out.println("当前时间:"+w.getHour()+"点 下班回家了");
    }
}
public class StateTest {
    public static void main(String[] args) {
        //紧急项目
        Work work = new Work();
        work.setHour(9);
        work.writeProgram();
        work.setHour(10);
        work.writeProgram();
        work.setHour(12);
        work.writeProgram();
        work.setHour(13);
        work.writeProgram();
        work.setHour(14);
        work.writeProgram();
        work.setHour(17);

        work.setWorkFinished(false);

        work.writeProgram();
        work.setHour(19);
        work.writeProgram();
        work.setHour(22);
        work.writeProgram();
    }
}

适配器模式

将一个类的接口转换成客户希望的另外一个接口。Adapter模式是的原本由于接口不兼容而不能一起工作的那些类可以一起工作。

package design;

//客户希望的接口
class Target{
    public void request(){
        System.out.println("normal request");
    }
}
//需要适配的接口
class Adaptee{
    public void specificRequest(){
        System.out.println("specify request");
    }
}
//适配器
class Adapter extends Target{
    private Adaptee adaptee = new Adaptee();
    @Override
    public void request() {
        adaptee.specificRequest();
    }
}

public class AdapterTest {
    public static void main(String[] args) {
        Adapter adapter = new Adapter();
        adapter.request();
    }
}

备忘录模式

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

package design;
//发起人
class Originator{
    //状态
    private String state;
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
    //显示数据
    public void show(){
        System.out.println("State:"+state);
    }
    //创建备忘录
    public Memento createMemento(){
        return new Memento(state);
    }
    //恢复备忘录
    public void recoveryMemento(Memento memento){
        setState(memento.getState());
    }
}
//备忘录
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;
    }
}
//管理者
class Caretaker{
    private Memento memento;

    public Memento getMemento() {
        return memento;
    }

    public void setMemento(Memento memento) {
        this.memento = memento;
    }
}

public class MemoTest {
    public static void main(String[] args) {
        //init
        Originator o = new Originator();
        o.setState("On");
        o.show();

        //备份
        Caretaker c = new Caretaker();
        c.setMemento(o.createMemento());

        //修改
        o.setState("Off");
        o.show();

        //还原
        o.recoveryMemento(c.getMemento());
        o.show();
    }
}

组合模式

将对象组合成树形结构表示 “部分-整体” 的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

package design;

import java.util.ArrayList;

abstract class Component{
    protected String name;
    public Component(String name){
        this.name = name;
    }
    public abstract void add(Component component);
    public abstract void remove(Component componet);
    public abstract void display(int depth);
}
class Leaf extends Component{
    public Leaf(String name){
        super(name);
    }
    @Override
    public void add(Component component) {
        System.out.println("Cannot add to a leaf.");
    }

    @Override
    public void remove(Component componet) {
        System.out.println("Cannot remove from a leaf.");
    }

    @Override
    public void display(int depth) {
        for (int i = 0; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println(name);
    }
}
class Compostite extends Component{
    private ArrayList<Component> children = new ArrayList<Component>();
    public Compostite(String name) {
        super(name);
    }

    @Override
    public void add(Component component) {
        children.add(component);
    }

    @Override
    public void remove(Component componet) {
        children.remove(componet);
    }

    @Override
    public void display(int depth) {
        //显示其枝节点名称
        for (int i = 0; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println(name);
        //对其下级进行遍历
        for(Component item:children){
            item.display(depth+2);
        }
    }
}
public class CompositeTest {
    public static void main(String[] args) {
        Compostite root = new Compostite("root");
        root.add(new Leaf("Leaf A"));
        root.add(new Leaf("Leaf B"));

        Compostite comp = new Compostite("Composite X");
        comp.add(new Leaf("Leaf XA"));
        comp.add(new Leaf("Leaf XB"));
        root.add(comp);

        Compostite comp2 = new Compostite("Composite XY");
        comp2.add(new Leaf("Leaf XYA"));
        comp2.add(new Leaf("Leaf XYB"));
        comp.add(comp2);

        Leaf leafC = new Leaf("Leaf C");
        Leaf leafD = new Leaf("Leaf D");
        root.add(leafC);
        root.add(leafD);
        root.remove(leafC);

        root.display(1);
    }
}

-root
---Leaf A
---Leaf B
---Composite X
-----Leaf XA
-----Leaf XB
-----Composite XY
-------Leaf XYA
-------Leaf XYB
---Leaf D

迭代器模式

提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。

package design;


import java.util.ArrayList;

//聚集抽象类
abstract class Aggregate{
   //创建迭代器
   public abstract Iterator createIterator();
}
//具体聚集类
class ConcreteAggregate extends Aggregate{
   //声明一个ArrayList泛型变量,用于存放聚合对象
   private ArrayList<Object> items = new ArrayList<Object>();
   @Override
   public Iterator createIterator() {
       return new ConcreteIterator(this);
   }

   //返回聚集总个数
   public int getCount(){
       return items.size();
   }
   //增加新对象
   public void add(Object o){
       items.add(o);
   }
   //得到指定索引对象
   public Object getCurrentItem(int  index){
       return items.get(index);
   }
}

//迭代器抽象类
abstract class Iterator{
   public abstract Object first();
   public abstract Object next();
   public abstract boolean isDone();
   public abstract Object currentItem();
}
//具体迭代器类,
class ConcreteIterator extends Iterator{
   private ConcreteAggregate aggregate;
   private int current = 0;

   //初始化时将具体的聚集对象传入
   public ConcreteIterator(ConcreteAggregate aggregate){
       this.aggregate = aggregate;
   }
   //得到第一个对象
   @Override
   public Object first() {
       return aggregate.getCurrentItem(0);
   }
   //得到下一个对象
   @Override
   public Object next() {
       Object ret = null;
       current++;
       if(current < aggregate.getCount()){
           ret = aggregate.getCurrentItem(current);
       }
       return ret;
   }
   //判断当前是否遍历到结尾,到结尾返回true
   @Override
   public boolean isDone() {
       return current>=aggregate.getCount()?true:false;
   }
   //返回当前的聚集对象
   @Override
   public Object currentItem() {
       return aggregate.getCurrentItem(current);
   }
}

public class IteratorTest {
   public static void main(String[] args) {
       ConcreteAggregate bus = new ConcreteAggregate();
       bus.add("big");
       bus.add("small");
       bus.add("luggage");
       bus.add("foreigner");
       bus.add("thief");

       Iterator conductor = new ConcreteIterator(bus);
       conductor.first();
       while(!conductor.isDone()){
           System.out.println(conductor.currentItem()+",buy ticket please");
           conductor.next();
       }
   }
}

倒序遍历:

//具体迭代器类,倒序
class ConcreteIteratorDesc extends Iterator{
    private ConcreteAggregate aggregate;
    private int current = 0;

    //初始化时将具体的聚集对象传入
    public ConcreteIteratorDesc(ConcreteAggregate aggregate){
        this.aggregate = aggregate;
        current = aggregate.getCount()-1;
    }
    //得到第一个对象
    @Override
    public Object first() {
        return aggregate.getCurrentItem(aggregate.getCount()-1);
    }
    //得到下一个对象
    @Override
    public Object next() {
        Object ret = null;
        current--;
        if(current >= 0 ){
            ret = aggregate.getCurrentItem(current);
        }
        return ret;
    }
    //判断当前是否遍历到结尾,到结尾返回true
    @Override
    public boolean isDone() {
        return current<0?true:false;
    }
    //返回当前的聚集对象
    @Override
    public Object currentItem() {
        return aggregate.getCurrentItem(current);
    }
}

java的迭代器实现

List<String> bus = new  ArrayList<String>();
for(String item : bus){
    ...
}

单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

懒汉式单例类

class Singleton{
    private static Singleton instance;
    //构造方法私有化
    private Singleton(){}
    //得到Singleton的实例(唯一途径)synchronized 保证每个线程都不一起进入
    public static synchronized Singleton getInstance(){
        if(instance==null){
            instance = new Singleton();
        }
        return instance;
    }
}

静态初始化:

饿汉式单例类

class Singleton{
    private static Singleton instance = new Singleton();
    private Singleton(){}
    public static Singleton getInstance(){
        return instance;
    }
}

桥接模式

将抽象部分与它的实现部分分离,使它们都可以独立的变化。

package design;

abstract class Implementor{
    public abstract void operation();
}
class ConcreteImplementorA extends Implementor{
    public void operation(){
        System.out.println("a....");
    }
}
class ConcreteImplementorB extends Implementor{
    public void operation(){
        System.out.println("b....");
    }
}

abstract class Abstraction{
    protected Implementor implementor;
    public void setImplementor(Implementor implementor){
        this.implementor = implementor;
    }
    public abstract void operation();
}
class RefinedAbstract extends Abstraction{
    public void operation(){
        System.out.println("abstraction");
        implementor.operation();
    }
}

public class BridgeTest {
    public static void main(String[] args) {
        Abstraction ab;
        ab = new RefinedAbstract();
        
        ab.setImplementor(new ConcreteImplementorA());
        ab.operation();

        ab.setImplementor(new ConcreteImplementorB());
        ab.operation();
    }
}

命令模式

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。

package design;

abstract class Command{
    protected Receiver2 receiver;
    public Command(Receiver2 receiver){
        this.receiver = receiver;
    }
    public abstract void excuteCommand();
}
class ConcreteCommand extends Command{
    public ConcreteCommand(Receiver2 receiver){
        super(receiver);
    }
    public void excuteCommand(){
        receiver.action();
    }
}
class Invoker{
    private Command command;
    public void setCommand(Command command){
        this.command = command;
    }
    public void executeCommand(){
        command.excuteCommand();
    }
}
class Receiver2{
    public void action(){
        System.out.println("执行请求");
    }
}
public class CommandTest {
    public static void main(String[] args) {
        Receiver2 receiver = new Receiver2();
        ConcreteCommand command = new ConcreteCommand(receiver);
        Invoker invoker = new Invoker();

        invoker.setCommand(command);
        invoker.executeCommand();
    }
}

Ex: 烧烤

package design;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

//烤肉串者
class Barbecuer{
    //烤羊肉
    public void bakeMutton(){
        System.out.println("烤羊肉串");
    }
    //烤鸡翅
    public void bakeChickenWing(){
        System.out.println("烤鸡翅");
    }
}
//抽象命令类
abstract class Command2{
    protected Barbecuer receiver;
    public Command2(Barbecuer receiver){
        this.receiver = receiver;
    }
    //执行命令
    public abstract void excuteCommand();
}
//烤羊肉命令类
class BakeMuttonCommand extends Command2{
    public BakeMuttonCommand(Barbecuer receiver) {
        super(receiver);
    }
    @Override
    public void excuteCommand() {
        receiver.bakeMutton();
    }
}
//烤鸡翅命令类
class BakeChickenWingCommand extends Command2{
    public BakeChickenWingCommand(Barbecuer receiver) {
        super(receiver);
    }
    @Override
    public void excuteCommand() {
        receiver.bakeChickenWing();
    }
}

//服务员类
class Waiter{
    private ArrayList<Command2> orders = new ArrayList<>();
    //设置订单
    public void setOrder(Command2 command){
        String className = command.getClass().getSimpleName();
        if(className.equals("BakeChickenWingCommand")){
            System.out.println("服务员:鸡翅没有了,请点其他烧烤");
        }else{
            orders.add(command);
            System.out.println("增加订单:"+className+" 时间:"+getNowTime());
        }
    }
    //取消订单
    public void cancelOrder(Command2 command){
        String className = command.getClass().getSimpleName();
        orders.remove(command);
        System.out.println("取消订单:"+className+" 时间:"+getNowTime());
    }
    //通知执行
    public void notifyCommand(){
        for(Command2 command: orders){
            command.excuteCommand();
        }
    }

    private String getNowTime(){
        SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
        return format.format(new Date()).toString();
    }
}
public class CommandTest2 {
    public static void main(String[] args) {
        //开店前的准备
        Barbecuer boy = new Barbecuer();//烤肉厨师
        BakeMuttonCommand bakeMuttonCommand = new BakeMuttonCommand(boy);//烤羊肉串
        BakeChickenWingCommand bakeChickenWingCommand = new BakeChickenWingCommand(boy);//烤鸡翅
        Waiter girl = new Waiter();//服务员

        //开门营业
        System.out.println("开门营业");
        girl.setOrder(bakeMuttonCommand);//下单烤羊肉串
        girl.setOrder(bakeMuttonCommand);//下单烤羊肉串
        girl.setOrder(bakeMuttonCommand);//下单烤羊肉串

        girl.cancelOrder(bakeMuttonCommand);//取消一单

        girl.setOrder(bakeChickenWingCommand);//下单烤鸡翅

        System.out.println("点菜完毕");
        girl.notifyCommand();//通知厨师烤肉


    }
}

开门营业
增加订单:BakeMuttonCommand 时间:11:31:30
增加订单:BakeMuttonCommand 时间:11:31:30
增加订单:BakeMuttonCommand 时间:11:31:30
取消订单:BakeMuttonCommand 时间:11:31:30
服务员:鸡翅没有了,请点其他烧烤
点菜完毕
烤羊肉串
烤羊肉串

职责链模式

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,知道有一个对象处理它为止

package design;

abstract class Handler{
    protected Handler successor;
    //设置继任者
    public void setSuccessor(Handler successor){
        this.successor = successor;
    }
    public abstract void handleRequest(int request);
}
class ConcreteHandler1 extends Handler{
    public void handleRequest(int request){
        if(request>=0&& request<10){
            System.out.println(this.getClass().getSimpleName()+" 处理请求 "+request);
        }else if(successor!=null){
            successor.handleRequest(request);
        }
    }
}
class ConcreteHandler2 extends Handler{
    public void handleRequest(int request){
        if(request>=10&& request<20){
            System.out.println(this.getClass().getSimpleName()+" 处理请求 "+request);
        }else if(successor!=null){
            successor.handleRequest(request);
        }
    }
}
class ConcreteHandler3 extends Handler{
    public void handleRequest(int request){
        if(request>=20&& request<30){
            System.out.println(this.getClass().getSimpleName()+" 处理请求 "+request);
        }else if(successor!=null){
            successor.handleRequest(request);
        }
    }
}
public class ResponsibilityTest {
    public static void main(String[] args) {
        ConcreteHandler1 h1 = new ConcreteHandler1();
        ConcreteHandler2 h2 = new ConcreteHandler2();
        ConcreteHandler3 h3 = new ConcreteHandler3();
        h1.setSuccessor(h2);
        h2.setSuccessor(h3);

        int[] requests = {2,5,14,22,18,3,27,20};

        for (int request : requests) {
            h1.handleRequest(request);
        }
    }
}

ConcreteHandler1 处理请求 2
ConcreteHandler1 处理请求 5
ConcreteHandler2 处理请求 14
ConcreteHandler3 处理请求 22
ConcreteHandler2 处理请求 18
ConcreteHandler1 处理请求 3
ConcreteHandler3 处理请求 27
ConcreteHandler3 处理请求 20

中介者模式

用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变他们之间的交互。

package design;

//抽象同事类
abstract class Colleague{
    protected Mediator mediator;
    public Colleague(Mediator mediator){
        this.mediator = mediator;
    }
}
class ConcreteColleague1 extends Colleague{
    public ConcreteColleague1(Mediator mediator){
        super(mediator);
    }
    public void send(String message){
        mediator.send(message,this);
    }
    public void notify(String message){
        System.out.println("同事1得到信息:"+message);
    }
}
class ConcreteColleague2 extends Colleague{
    public ConcreteColleague2(Mediator mediator){
        super(mediator);
    }
    public void send(String message){
        mediator.send(message,this);
    }
    public void notify(String message){
        System.out.println("同事2得到信息:"+message);
    }
}

//抽象中介者类
abstract class Mediator{
    public abstract void send(String message,Colleague colleague);
}
class ConcreteMediator extends Mediator{
    private ConcreteColleague1 colleague1;
    private ConcreteColleague2 colleague2;

    public void setColleague1(ConcreteColleague1 value){
        colleague1 = value;
    }
    public void setColleague2(ConcreteColleague2 value){
        colleague2 = value;
    }

    public void send(String message, Colleague colleague) {
        if(colleague == colleague1){
            colleague2.notify(message);
        }else {
            colleague1.notify(message);
        }
    }
}

public class MediatorTest {
    public static void main(String[] args) {
        ConcreteMediator m = new ConcreteMediator();
        ConcreteColleague1 c1 = new ConcreteColleague1(m);
        ConcreteColleague2 c2 = new ConcreteColleague2(m);

        m.setColleague1(c1);
        m.setColleague2(c2);

        c1.send("吃饭了吗?");
        c2.send("么有呢?");
    }
}

同事2得到信息:吃饭了吗?
同事1得到信息:么有呢?

享元模式

运用共享技术有效地支持大量细粒度的对象。

package design;

import java.util.Hashtable;

abstract class Flyweight{
    public abstract void operation(int extrinsicstate);
}
//需要共享的具体Flyweight子类
class ConcreteFlyweight extends Flyweight{
    public void operation(int extrinsicstate){
        System.out.println("具体Flyweight:"+extrinsicstate);
    }
}
//不需要共享Flyweight子类
class UnsharedConcreteFlyweight extends Flyweight{
    public void operation(int extrinsicstate){
        System.out.println("不共享的具体Flyweight:"+extrinsicstate);
    }
}
//享元工厂
class FlyweightFactory{
    private Hashtable<String,Flyweight> flyweights = new Hashtable<>();
    public FlyweightFactory(){
        flyweights.put("X",new ConcreteFlyweight());
        flyweights.put("Y",new ConcreteFlyweight());
        flyweights.put("Z",new ConcreteFlyweight());
    }
    public Flyweight getFlyweight(String key){
        return flyweights.get(key);
    }
}
public class FlyweightTest {
    public static void main(String[] args) {
        int extrinaicstate = 22;
        FlyweightFactory f = new FlyweightFactory();
        Flyweight fx = f.getFlyweight("X");
        fx.operation(--extrinaicstate);
        Flyweight fy = f.getFlyweight("Y");
        fy.operation(--extrinaicstate);
        Flyweight fz = f.getFlyweight("Z");
        fz.operation(--extrinaicstate);
        Flyweight uf = new UnsharedConcreteFlyweight();
        uf.operation(--extrinaicstate);
    }
}

Ex:网站展示

package design;

import java.util.Hashtable;

class User2{
    private String name;
    public User2(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

class Website{
    private String name = "";
    public Website(String name){
        this.name = name;
    }
    public void use(){
        System.out.println("网站分类:"+name);
    }
}

//网站抽象
abstract class WebSite2{
    public abstract void use(User2 user);
}
//具体网站
class ConcreteWebSite extends WebSite2{
    private String name = "";
    public ConcreteWebSite(String name){
        this.name = name;
    }
    public void use(User2 user){
        System.out.println("网站分类:"+name+" 用户:"+user.getName());
    }
}
//网站工厂
class WebSiteFactory{
    private Hashtable<String,WebSite2> flyweights = new Hashtable<>();
    //获得网站分类
    public WebSite2 getWebSiteCategory(String key){
        if(!flyweights.contains(key)){
            flyweights.put(key,new ConcreteWebSite(key));
        }
        return flyweights.get(key);
    }
    //获取网站分类总数
    public int getWebSiteCount(){
        return flyweights.size();
    }
}

public class WebTest {
    public static void main(String[] args) {
        WebSiteFactory f = new WebSiteFactory();
        WebSite2 fx = f.getWebSiteCategory("产品展示");
        fx.use(new User2("小蔡"));
        WebSite2 fy = f.getWebSiteCategory("产品展示");
        fy.use(new User2("小刘"));
        WebSite2 fz = f.getWebSiteCategory("产品展示");
        fz.use(new User2("小王"));

        WebSite2 fl = f.getWebSiteCategory("博客");
        fl.use(new User2("小占"));
        WebSite2 fm = f.getWebSiteCategory("博客");
        fm.use(new User2("小书"));
        WebSite2 fn = f.getWebSiteCategory("博客");
        fn.use(new User2("小黄"));

        System.out.println("网站分类总数为:"+f.getWebSiteCount());
    }
}

网站分类:产品展示 用户:小蔡
网站分类:产品展示 用户:小刘
网站分类:产品展示 用户:小王
网站分类:博客 用户:小占
网站分类:博客 用户:小书
网站分类:博客 用户:小黄
网站分类总数为:2

目的:节约资源。

解释器模式

给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

package design;

import java.util.ArrayList;

//抽象表达式
abstract class AbstractExpression{
    //解释操作
    public abstract void interpret(Context context);
}
//终结符表达式
class TerminalExpression extends AbstractExpression{
    public void interpret(Context context){
        System.out.println("终端解释器");
    }
}
//非终结符表达式
class NonterninalExpressin extends AbstractExpression{
    public void interpret(Context context){
        System.out.println("非终端解释器");
    }
}
class Context{
    private String input;
    public String getInput(){
        return input;
    }
    public void setInput(String value){
        input = value;
    }

    private String output;
    public String getOutput(){
        return output;
    }
    public void setOutput(String value){
        output = value;
    }
}

public class InterpreterTest {
    public static void main(String[] args) {
        Context context = new Context();
        ArrayList<AbstractExpression> list = new ArrayList<>();
        list.add(new TerminalExpression());
        list.add(new NonterninalExpressin());
        list.add(new TerminalExpression());
        list.add(new TerminalExpression());

        for (AbstractExpression exp : list) {
            exp.interpret(context);
        }
    }
}

Ex:music interpreter

package design;
//演奏内容
class PlayContext{
    private String playText;
    public String getPlayText(){
        return playText;
    }
    public void setPlayText(String value){
        playText = value;
    }
}
//抽象表达式
abstract class Expression{
    public void interpret(PlayContext context){
        if(context.getPlayText().length()==0) return;
        else{
            String playKey = context.getPlayText().substring(0,1);
            context.setPlayText(context.getPlayText().substring(2));
            double playValue = Double.parseDouble(
                    context.getPlayText().substring(0,context.getPlayText().indexOf(" ")));
            context.setPlayText(context.getPlayText().substring(context.getPlayText().indexOf(" ")+1));

            this.excute(playKey,playValue);
        }
    }
    //抽象方法执行,不同的文法子类,有不同的执行处理
    public abstract void excute(String key,double value);
}
//音符
class Note extends Expression{
    public void excute(String key,double value){
        String note = "";
        switch(key){
            case "C":
                note = "1";
                break;
            case "D":
                note = "2";
                break;
            case "E":
                note = "3";
                break;
            case "F":
                note = "4";
                break;
            case "G":
                note = "5";
                break;
            case "A":
                note = "6";
                break;
            case "B":
                note = "7";
                break;
        }
        System.out.print(note+" ");
    }
}
//音阶
class Scale extends Expression{
    public void excute(String key,double value){
        String scale = "";
        switch((int)value){
            case 1:
                scale = "低音";
                break;
            case 2:
                scale = "中音";
                break;
            case 3:
                scale = "高音";
                break;
        }
        System.out.print(scale+" ");
    }
}
public class MusicInterpreterTest {
    public static void main(String[] args) {
        PlayContext context = new PlayContext();
        System.out.println("音乐-上海滩:");
        context.setPlayText("O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G");

        Expression expression = null;
        while(context.getPlayText().length()>0){
            String str = context.getPlayText().substring(0,1);
            switch (str){
                case "O":
                    expression = new Scale();
                    break;
                case "C":
                case "D":
                case "E":
                case "F":
                case "G":
                case "A":
                case "B":
                case "P":
                    expression = new Note();
                    break;
            }
            expression.interpret(context);
        }
    }
}

音乐-上海滩:
中音 3 5 6 3 5 2 3 5 6 高音 1 中音 6 

如果需要扩展 音速 功能:

//音速
class Speed extends Expression{
    public void excute(String key,double value){
        String speed="";
        if(value<1000) speed ="快速";
        if(value<500) speed ="快速";
        if(value<100) speed ="快速";
        System.out.print(speed+" ");
    }
}

public class MusicInterpreterTest {
    public static void main(String[] args) {
       ...
                case "P":
                    expression = new Note();
                    break;
                case "S":
                    expression = new Speed();
                    break;
            }
            expression.interpret(context);
        }
    }
}

访问者模式

表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

package design;

import java.util.ArrayList;

// Visitor类,为该对象结构中ConcreteElement的每一个类声明一个Visit操作
abstract class Visitor{
    public abstract void visitConcreteElementA(ConcreteElementA concreteElementA);
    public abstract void visitConcreteElementB(ConcreteElementB concreteElementB);
}
class ConcreteVisitor1 extends Visitor{
    public void visitConcreteElementA(ConcreteElementA concreteElementA){
        System.out.println(concreteElementA.getClass().getSimpleName()+"被"
                +this.getClass().getSimpleName()+"访问");
    }
    public void visitConcreteElementB(ConcreteElementB concreteElementB){
        System.out.println(concreteElementB.getClass().getSimpleName()+"被"
                +this.getClass().getSimpleName()+"访问");
    }
}
class ConcreteVisitor2 extends Visitor{
    public void visitConcreteElementA(ConcreteElementA concreteElementA){
        System.out.println(concreteElementA.getClass().getSimpleName()+"被"
                +this.getClass().getSimpleName()+"访问");
    }
    public void visitConcreteElementB(ConcreteElementB concreteElementB){
        System.out.println(concreteElementB.getClass().getSimpleName()+"被"
                +this.getClass().getSimpleName()+"访问");
    }
}

// Element类:定义一个Accept操作,它以一个访问者为参数。
abstract class Element{
    public abstract void accept(Visitor visitor);
}
class ConcreteElementA extends Element{
    public void accept(Visitor visitor){
        visitor.visitConcreteElementA(this);
        operationA();
    }
    public void operationA(){
        System.out.println("operationA()...");
    }
}
class ConcreteElementB extends Element{
    public void accept(Visitor visitor){
        visitor.visitConcreteElementB(this);
        operationB();
    }
    public void operationB(){
        System.out.println("operationB()...");
    }
}

//ObjectStructure类:能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素
class ObjectStructure{
    private ArrayList<Element> elements = new ArrayList<>();

    public void attach(Element element){
        elements.add(element);
    }
    public void detach(Element element){
        elements.remove(element);
    }
    public void accept(Visitor visitor){
        for (Element e : elements) {
            e.accept(visitor);
        }
    }
}

public class VisitorTEst {
    public static void main(String[] args) {
        ObjectStructure o = new ObjectStructure();
        o.attach(new ConcreteElementA());
        o.attach(new ConcreteElementB());

        ConcreteVisitor1 v1 = new ConcreteVisitor1();
        ConcreteVisitor2 v2 = new ConcreteVisitor2();

        o.accept(v1);
        o.accept(v2);
    }
}

ConcreteElementA被ConcreteVisitor1访问
operationA()...
ConcreteElementB被ConcreteVisitor1访问
operationB()...
ConcreteElementA被ConcreteVisitor2访问
operationA()...
ConcreteElementB被ConcreteVisitor2访问
operationB()...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值