设计模式

设计模式设计原则

创建型模式

工厂模式

如同命名一样,当我们需要某个对象的时候,直接调用其工厂对象,获取对象即可,不用关心对象时怎么创建出来的,具体实现是怎么样的

优点

缺点

使用场景

示例 根据不同的订单类型和订单id返回不同的订单

/**
 * 工厂模式
 */
public class FactoryPattern {

    public Order getOrder(Integer orderId, OrderTypeEnum orderTypeEnum) {
        if (OrderTypeEnum.GOODSORDERTYPE == orderTypeEnum) {
            // 返回商品订单
            return new GoodsOrder();
        } else if(OrderTypeEnum.SERVICEORDERTYPE == orderTypeEnum) {
            // 返回服务订单
            return new ServicesOrder();
        } else if (OrderTypeEnum.AFTERSALEORDERTYPE == orderTypeEnum) {
            // 返回售后订单
            return new AfsOrder();
        } else {
            return null;
        }
    }
}


/**
 * 售后订单的model
 */
class AfsOrder extends Order {
    /**
     * 订单类型
     */
    private Integer orderType;
    /**
     * 客服姓名
     */
    private String servicerName;
}

/**
 * 服务订单的model
 */
class ServicesOrder extends Order {
    /**
     * 订单类型
     */
    private Integer orderType;
    /**
     * 服务内容
     */
    private String serviceContent;
}

/**
 * 商品订单model
 */
class GoodsOrder extends Order {
    /**
     * 订单类型
     */
    private Integer orderType;
    /**
     * 商品名称
     */
    private String goodsName;
}

class Order {
    /**
     * 订单ID
     */
    private Integer orderId;
    /**
     * 订单金额
     */
    private Double orderFee;
    /**
     *
     */
    private Date createTime;
}

enum OrderTypeEnum {
    GOODSORDERTYPE(1,"商品订单"),
    SERVICEORDERTYPE(2,"服务订单"),
    AFTERSALEORDERTYPE(3,"售后订单");

    OrderTypeEnum(Integer key,String value) {
        this.key = key;
        this.value = value;
    }
    private Integer key;
    private String value;

    public Integer getKey() {
        return key;
    }

    public void setKey(Integer key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

创建型模式

单例模式 该模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象

优点

缺点

使用场景

单例模式按加载顺序又可分为饿汉模式,懒汉模式

饿汉式

class HungrySingleTon {
    private HungrySingleTon(){}

    private static HungrySingleTon hungrySingleTon = new HungrySingleTon();

    public static HungrySingleTon getInstance() {
        return hungrySingleTon;
    }
}

懒汉式

class lazySingleTonOfDcl {
    private lazySingleTonOfDcl(){}
    // volatile 关键字,限制cpu对指令重排序
    private static volatile lazySingleTonOfDcl singleTon = null;

    public static lazySingleTonOfDcl getInstance() {
        if (singleTon == null) {
            synchronized (lazySingleTonOfDcl.class) {
                if (singleTon == null) {
                    singleTon = new lazySingleTonOfDcl();
                }
            }
        }
        return singleTon;
    }
}

在懒加载单例对象时候,由于Java中new一个对象并不是一个原子操作,编译时singleton = new Singleton(); 语句会被转成多条汇编指令,它们大致做了3件事情

由于Java编译器允许处理器乱序执行(处理器会根据语句执行效率进行指令重排序),以及JDK1.5之前的旧的Java内存模型中Cache、寄存器到主内存回写顺序的规定,上面步骤2)和3)的执行顺序是无法确定的,可能是 1) → 2) → 3) 也可能是 1) → 3) → 2) 。如果是后一种情况,在线程 A 执行完步骤 3) 但还没完成 2) 之前,被切换到线程 B 上,此时线程 B 对singleton 第1次判空结果为false,直接取走了singleton使用,但是构造函数却还没有完成所有的初始化工作,就会出错,也就是DCL失效问题。这时我们在加上volatile关键字就能解决这个问题

另外还有其他实现单例模式的方式,如下图 此处输入图片的描述

创建型模式

建造者模式

适用于多个简单的对象一步一步构建成一个复杂的对象,一些基本部件不会变,而其组合经常变化的情况

优点

缺点

使用场景

示例

/**
 * 建造者模式
 */
public class BuilderPattern {
    public static void main(String[] args) {
        Meal chickenMeal = MealBuilder.buildChickenMeal();
        chickenMeal.showItems();
        Meal vegeMeal = MealBuilder.buildVegeMeal();
        vegeMeal.showItems();
    }
}

class MealBuilder {

    public static Meal buildChickenMeal() {
        Meal meal = new Meal();
        pepsi pepsi = new pepsi();
        chickenBurger chickenBurger = new chickenBurger();
        meal.addItem(pepsi);
        meal.addItem(chickenBurger);

        return meal;
    }

    public static Meal buildVegeMeal() {
        Meal meal = new Meal();
        Coke coke = new Coke();
        VegBurger vegBurger = new VegBurger();
        meal.addItem(coke);
        meal.addItem(vegBurger);

        return meal;
    }
}

class Meal {
    private List<Item> items = new ArrayList<Item>();

    public void addItem(Item item) {
        items.add(item);
    }

    public Double getCost() {
        BigDecimal cost = new BigDecimal("0.00");

        for (Item item : items) {
            cost = cost.add(new BigDecimal(item.price()== null?"0.00":item.price().toString()));
        }

        return cost.doubleValue();
    }

    public void showItems () {
        for (Item item : items) {
            System.out.println(item.toString());
        }
    }
}

class Coke extends ColdDrink {
    @Override
    public String name() {
        return "coke";
    }

    @Override
    public Double price() {
        return 3.50;
    }

    @Override
    public String toString() {
        return "name-" + name() +" " + "price-" + price();
    }
}


class pepsi extends ColdDrink {
    @Override
    public String name() {
        return "pepsi";
    }

    @Override
    public Double price() {
        return 3.00;
    }
    @Override
    public String toString() {
        return "name-" + name() +" " + "price-" + price();
    }
}

class chickenBurger extends Burger {
    @Override
    public String name() {
        return "chicken burger";
    }

    @Override
    public Double price() {
        return 11.2;
    }
    @Override
    public String toString() {
        return "name-" + name() +" " + "price-" + price();
    }
}

class VegBurger extends Burger {
    @Override
    public String name() {
        return "vegBurger";
    }

    @Override
    public Double price() {
        return 5.5;
    }
    @Override
    public String toString() {
        return "name-" + name() +" " + "price-" + price();
    }
}

/**
 * 冷饮
 */
abstract class ColdDrink implements Item {
    @Override
    public Packing pack() {
        return new Bottle();
    }
}

/**
 * 汉堡
 */
abstract class Burger implements Item{
    @Override
    public Packing pack() {
        return new Wrapper();
    }
}

/**
 * 组件接口
 */
interface Item{
    String name();
    Double price();
    Packing pack();
}

/**
 * 盒装
 */
class Wrapper implements Packing {
    @Override
    public String pack() {
        return "wrapper";
    }
}

/**
 * 瓶装
 */
class Bottle implements Packing {
    @Override
    public String pack() {
        return "bottle";
    }
}
/**
 * 包装
 */
interface Packing {
    String pack();
}

创建型模式

原型模式

原型模式用于创建重复的对象,同时又能保证性能

优点

缺点

使用场景

示例

/**
 * 原型模式
 */
public class PrototypePattern {
    public static void main(String[] args) {
        BallCache.loadCache();
        try {
            BallCache.getBall("footBall");
        }catch (Exception e){
            e.getMessage();
        }

    }
}

class BallCache {
    private static Hashtable<String,Ball> hashtable = new Hashtable();


    public static Ball getBall(String ballName) throws Exception{
        return (Ball)hashtable.get(ballName).clone();
    }

    public static void loadCache() {
        hashtable.put("footBall",new FootBall());
        hashtable.put("basketBall",new BasketBall());
    }

}

class FootBall extends Ball {
    FootBall() {
        this.wight = 1.1;
        this.color = "white";
    }
}
class BasketBall extends Ball {
    BasketBall() {
        this.wight = 2.1;
        this.color = "red";
    }
}

abstract class Ball implements Cloneable {
    protected String name;
    protected Double wight;
    protected String color;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getWight() {
        return wight;
    }

    public void setWight(Double wight) {
        this.wight = wight;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

结构型模式

适配器模式

适配器模式是作为两个不兼容的接口之间的桥梁,它结合了两个独立接口的功能。这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能

优点

缺点

使用场景

示例

/**
 * 适配器模式:类适配模式
 */
public class Adapter extends targetClass implements CAdaptee {

    public String readXmlByStream() {
        return readXml();
    }
}


/**
 * 适配器模式:对象适配模式
 */
class Adapter2 implements CAdaptee {
    // 该对象的方法适配我所需求
    targetClass tc = new targetClass();


    public String readXmlByStream() {
        return tc.readXml();
    }
}

interface CAdaptee {
    String readXmlByStream();
}

class targetClass {
    public String readXml() {
        return "we can read readXml";
    };
}

/**
 * 让这个工具也能读取xml格式数据
 */
class ReadDataTool extends Adapter2{
    public String readJson() {
        return "i can read json data!";
    }

    @Override
    public String readXmlByStream() {
        return super.readXmlByStream();
    }
}

结构型模式

桥接模式

桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化,通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦

优点

缺点

使用场景

示例

public class brigdePattern {
    public static void main(String[] args) {
        xiaoMian xm = new xiaoMian(new hotStyle(), new redColor());
        System.out.println(xm.eat());
        laMian lm = new laMian(new lightStyle(), new greenColor());
        System.out.println(lm.eat());
    }

}

interface style {
    String getName();
}

class hotStyle implements style {
    public String getName() {
        return "hot style";
    }
}

class lightStyle implements style {
    public String getName() {
        return "light style";
    }
}

interface color {
    String getColor();
}

class greenColor implements color {
    public String getColor() {
        return "green";
    }
}

class redColor implements color {
    public String getColor() {
        return "red";
    }
}

abstract class nodle {
    private style style;
    private color color;

    nodle(style style, color color) {
        this.color = color;
        this.style = style;
    }

    public String getStyle() {
        return style.getName();
    }

    public void setStyle(style style) {
        this.style = style;
    }

    public String getColor() {
        return color.getColor();
    }

    abstract String getName();

    abstract String eat();
}

class xiaoMian extends nodle {

    xiaoMian(style style, color color) {
        super(style, color);
    }

    public String getName() {
        return "xiaomian";
    }

    public String eat() {
        return "eat color:" + this.getColor() + "style:" + this.getStyle() + getName();
    }
}

class laMian extends nodle {
    laMian(style style, color color) {
        super(style, color);
    }

    public String getName() {
        return "laMian";
    }

    public String eat() {
        return "eat color:" + this.getColor() + "style:" + this.getStyle() + getName();
    }
}

结构型模式

过滤器模式

过滤器模式使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来

示例

/**
 * 标准接口
 */
interface Criteria {
    List<Apple> MaterialCriteria(List<Apple> apples);
}

/**
 * 能做饮料的苹果标准
 */
class AppleDrink implements Criteria {
    @Override
    public List<Apple> MaterialCriteria(List<Apple> apples) {
        List<Apple> appleDrinks = new ArrayList<>();
        if (!CollectionUtils.isEmpty(apples)) {
            for (Apple apple : apples) {
                if ("green".equals(apple.getColor()) && 2 > apple.getWight()) {
                    appleDrinks.add(apple);
                }
            }
        }

        return appleDrinks;
    }
}

/**
 * 能做披萨的苹果标准
 */
class ApplePizza implements Criteria {
    @Override
    public List<Apple> MaterialCriteria(List<Apple> apples) {
        List<Apple> applePizzas = new ArrayList<>();
        if (!CollectionUtils.isEmpty(apples)) {
            for (Apple apple : apples) {
                if ("Brazil".equals(apple.getCountry())) {
                    applePizzas.add(apple);
                }
            }
        }

        return applePizzas;
    }
}

/**
 * 符合两个标准的苹果
 */
class AndCriteria implements Criteria {
    private Criteria criteria;
    private Criteria oherCriteria;

    AndCriteria(Criteria criteria,Criteria oherCriteria) {
        this.criteria = criteria;
        this.oherCriteria = oherCriteria;
    }

    @Override
    public List<Apple> MaterialCriteria(List<Apple> apples) {
        List<Apple> criteriaApples = criteria.MaterialCriteria(apples);
        List<Apple> andApples = oherCriteria.MaterialCriteria(criteriaApples);

        return andApples;
    }
}

/**
 * 两个标准都不符合的苹果
 */
class OrCriteria implements Criteria {
    private Criteria criteria;
    private Criteria oherCriteria;

    OrCriteria(Criteria criteria,Criteria oherCriteria) {
        this.criteria = criteria;
        this.oherCriteria = oherCriteria;
    }

    @Override
    public List<Apple> MaterialCriteria(List<Apple> apples) {
        List<Apple> criteriaApples = criteria.MaterialCriteria(apples);
        List<Apple> otherCriterApples = oherCriteria.MaterialCriteria(apples);
        List<Apple> orApples = new ArrayList<>();

        for (Apple apple : criteriaApples) {
            if (!otherCriterApples.contains(apple)) {
                orApples.add(apple);
            }
        }
        return orApples;
    }
}

结构型模式

组合模式

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次,创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式

优点

缺点

使用场景

示例

class subject {
    private String content;
    private String author;
    private String time;

    private Collection<comment> comments;
}

class comment {
    private String content;
    private String replyName;
    private String time;

    private Collection<reply> replies;
}

class reply {
    private String content;
    private String replyName;
    private String time;
}

结构型模式

装饰器模式

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构,创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能

优点

缺点

使用场景

示例

/**
 * 装饰者模式
 */
public class DecoratorPattern {
    public static void main(String[] args) {
        Person england = new EnglandMan();
        england.speak();
        Person china = new Chinese();
        china.speak();
        Person superman = new FlyPersonDecorator(new Chinese());
        superman.speak();
    }
}

interface Person {
    void speak();
}

class FlyPersonDecorator extends PersonDecorator {
    FlyPersonDecorator(Person decoratePerson) {
        super(decoratePerson);
    }

    @Override
    public void speak() {
        super.speak();
        setWing();
    }

    private void setWing() {
        System.out.println("i can fly");
    }
}

abstract class PersonDecorator implements Person {
    protected Person decoratePerson;

    PersonDecorator(Person decoratePerson) {
        this.decoratePerson = decoratePerson;
    }

    @Override
    public void speak() {
        decoratePerson.speak();
    }
}

class EnglandMan implements Person {

    @Override
    public void speak() {
        System.out.println("i will speak english");
    }
}

class Chinese implements Person{
    @Override
    public void speak() {
        System.out.println("i will speak chinese");
    }
}

结构型模式

外观模式

外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口,这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。

优点

缺点

使用场景

示例

public class Facade {
    registerClass rc = new registerClass();
    MathClass mc = new MathClass();
    notifyClass nc = new notifyClass();

    public void registerWeibo() {
        rc.register();
        mc.matchFriend();
        nc.notifyUser();
    }
}

class registerClass {
    public String register() {
        return "注册账号";
    }
}

class MathClass {
    public String matchFriend() {
        return "匹配朋友";
    }
}

class notifyClass {
    public String notifyUser() {
        return "短信通知";
    }
}

结构型模式

享元模式

享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能,享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象

优点

缺点

使用场景

示例

public class FlyweightPattern {
    private static final ExpressCompanyEnum express[] = ExpressCompanyEnum.values();

    public static void main(String[] args) {
        for (int i = 0; i < 1000; i++) {
            DeliverFare deliverFare = CacheFactory.getDeliverFare(getRandomExpressCompany());
            deliverFare.setUnitNum(getDeliverUnitNum());
            deliverFare.caculate();
        }
    }

    private static ExpressCompanyEnum getRandomExpressCompany() {
        return express[(int)(Math.random()*express.length)];
    }

    private static int getDeliverUnitNum() {
        return (int)(Math.random() * 10);
    }

}

class CacheFactory {
    private static Map<String,DeliverFare> deliverFareMap = new HashMap<>();

    public static DeliverFare getDeliverFare(ExpressCompanyEnum companyEnum) {
        if (deliverFareMap.containsKey(companyEnum.getKey())) {
            System.out.println("获取以前对象");
            return deliverFareMap.get(companyEnum.getKey());
        }else {
            DeliverFare deliverFare = new DeliverFare(companyEnum);
            deliverFareMap.put(companyEnum.getKey(),deliverFare);
            System.out.println("创建新对象");
            return deliverFare;
        }
    }
}

class DeliverFare implements ExpressDelivery {
    private Integer unitNum;
    private ExpressCompanyEnum company;
    DeliverFare(ExpressCompanyEnum company) {
        this.company = company;
    }

    @Override
    public void caculate() {
        System.out.println(company.getValue() + "计算运费,货物数量:" + unitNum);
    }

    public Integer getUnitNum() {
        return unitNum;
    }

    public void setUnitNum(Integer unitNum) {
        this.unitNum = unitNum;
    }

    public ExpressCompanyEnum getCompany() {
        return company;
    }

    public void setCompany(ExpressCompanyEnum company) {
        this.company = company;
    }
}

enum ExpressCompanyEnum {
    SHUNFENG("shunfeng","顺丰"),
    ZHONGTONG("zhongtong","中通"),
        JD("jd","京东");

    ExpressCompanyEnum(String key,String value) {
        this.key = key;
        this.value = value;
    }
    private String key;
    private String value;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

interface ExpressDelivery {
    void caculate();
}

结构型模式

代理模式

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能

优点

缺点

使用场景

示例

public class proxyPattern {
    public static void main(String[] args) {
        ProxyVideo video = new ProxyVideo("Rick And Morty");
        video.display();
    }
}

class ProxyVideo implements video {
    private YoutuBe youtuBe;
    private String videoName;

    ProxyVideo(String videoName) {
        this.videoName = videoName;
    }


    public String getVideoName() {
        return videoName;
    }

    public void setVideoName(String videoName) {
        this.videoName = videoName;
    }

    @Override
    public void display() {
        if (youtuBe == null) {
            youtuBe = new YoutuBe(videoName);
        }
        youtuBe.display();
    }
}

class YoutuBe implements video {
    private String videoName;

    YoutuBe(String videoName) {
        this.videoName = videoName;
    }

    @Override
    public void display() {
        System.out.println("youtube playing " + videoName);
    }
}

interface video {
    void display();
}

行为型模式

责任链模式

责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链,通常每个接收者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者

优点

缺点

使用场景

示例


@Component
class ChainHandler1 implements BaseChainHandler {

    @Autowired
    private ChainHandler2 nextHandLer;

    @Override
    public List<Object> filter(handleObj obj) {
        List<Object> returnList = new ArrayList<>();
        for (Object o : obj.getItem()) {
            if (o.equals("test")) {
                returnList.add(o);
            }
        }

        return returnList;
    }

    @Override
    public void handle(handleObj obj) {
        List<Object> returnList = this.filter(obj);

        //todo handle returnList
        returnList.stream().forEach(o -> o.getClass());

        nextHandLer.handle(obj);
    }
}


@Component
class ChainHandler2 implements BaseChainHandler {

    @Override
    public List<Object> filter(handleObj obj) {
        List<Object> returnList = new ArrayList<>();
        for (Object o : obj.getItem()) {
            if (o.equals("test2")) {
                returnList.add(o);
            }
        }

        return returnList;
    }

    @Override
    public void handle(handleObj obj) {
        List<Object> returnList = this.filter(obj);

        //todo handle returnList
        returnList.stream().forEach(o -> o.getClass());

    }
}

interface BaseChainHandler {
    List<Object> filter(handleObj obj);

    void handle(handleObj obj);
}

class handleObj {
    List<Object> item;

    public List<Object> getItem() {
        return item;
    }

    public void setItem(List<Object> item) {
        this.item = item;
    }
}

行为型模式

命令模式

命令模式(Command Pattern)是一种数据驱动的设计模式,请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令

优点

缺点

使用场景

示例

public class CommandPattern {
    public static void main(String[] args) {
        Stock stock = new Stock("footBall",100);
        AddStock addStock = new AddStock(stock,23);
        ReduceStock reduceStock = new ReduceStock(stock,121);
        Cmd.scanf(addStock);
        Cmd.scanf(reduceStock);
        Cmd.excute();
    }

}

class Cmd {
    private static List<Commond> commonds = new ArrayList<>();

    public static void scanf(Commond commond) {
        commonds.add(commond);
    }

    public static void excute() {
        commonds.stream().forEach(commond -> commond.excute());
    }
}

class Stock {
    private String GoodName;
    private Integer num;

    Stock(String goodName, Integer num) {
        this.GoodName = goodName;
        this.num = num;
    }

    public void add(Integer num) {
        System.out.println(GoodName + " add stock[" + num + "]");
    }

    public void reduce(Integer num) {
        System.out.println(GoodName + " reduce stock[" + num + "]");
    }
}

class AddStock implements Commond {

    private Stock stock;
    private Integer num;

    AddStock(Stock stock,Integer num) {
        this.stock = stock;
        this.num = num;
    }

    @Override
    public void excute() {
        stock.add(num);
    }
}

class ReduceStock implements Commond {

    private Stock stock;
    private Integer num;

    ReduceStock(Stock stock,Integer num) {
        this.stock = stock;
        this.num = num;
    }

    @Override
    public void excute() {
        stock.reduce(num);
    }
}

interface Commond {
    void excute();

行为型模式

解释器模式

解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等

优点

缺点

使用场景

示例

public class InterpreterPattern {
    public static void main(String[] args) {
        System.out.println("hello,this is bbc news is news?:" + InterpreterPattern.setNewsWord().interpret("hello,this is bbc news"));
        System.out.println("1 hour 30 mills is time?:" + InterpreterPattern.setTimeWord().interpret("1 hour 30 mills"));

    }

    public static Explain setNewsWord() {
        Explain contextExplain = new ContextExplain("news");
        Explain contextExplain2 = new ContextExplain("report");

        return new OrExplain(contextExplain,contextExplain2);
    }

    public static Explain setTimeWord() {
        Explain contextExplain = new ContextExplain("minute");
        Explain contextExplain2 = new ContextExplain("hour");

        return new AndExplain(contextExplain,contextExplain2);
    }
}

class AndExplain implements Explain {
    private Explain orExplain1;
    private Explain orExplain2;

    AndExplain(Explain orExplain1, Explain orExplain2) {
        this.orExplain1 = orExplain1;
        this.orExplain2 = orExplain2;
    }


    @Override
    public boolean interpret(String context) {
        return orExplain1.interpret(context) && orExplain2.interpret(context);
    }
}

class OrExplain implements Explain {
    private Explain orExplain1;
    private Explain orExplain2;

    OrExplain(Explain orExplain1, Explain orExplain2) {
        this.orExplain1 = orExplain1;
        this.orExplain2 = orExplain2;
    }


    @Override
    public boolean interpret(String context) {
        return orExplain1.interpret(context) || orExplain2.interpret(context);
    }
}

class ContextExplain implements Explain {
    private  String data;

    ContextExplain(String data) {
        this.data = data;
    }

    @Override
    public boolean interpret(String context) {
        if (context.contains(data)) {
            return true;
        }

        return false;
    }
}

interface Explain {
    boolean interpret(String context);
}

行为型模式

迭代器模式

迭代器模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示

优点

缺点

使用场景

示例

public class IteratorPattern {
    public static void main(String[] args) {
        MyContainer container = new MyContainer();
        container.add("str1");
        container.add("str7");
        container.add("str5");
        container.add("str2");
        container.add("str3");

        MyIterator iterator = container.getIterator();

        while (iterator.hashNext()) {
            System.out.println(iterator.next());
        }
    }
}

class MyContainer implements Container {
    private String[] strs = new String[10];
    private int size = 0;

    @Override
    public void add(Object object) {
        strs[size++] = (String) object;
    }

    @Override
    public MyIterator getIterator() {
        return new Iterator();
    }

    private class Iterator implements MyIterator {
        int index = 0;
        @Override
        public boolean hashNext() {
            if (index < strs.length) {
                return true;
            }
            return false;
        }

        @Override
        public Object next() {
            if (hashNext()) {
                return strs[index++];
            }

            return null;
        }
    }
}

interface Container {
    MyIterator getIterator();
    void add(Object obj);
}

interface MyIterator {
    boolean hashNext();
    Object next();
}

行为型模式

中介者模式

中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护

优点

缺点

使用场景

示例

public class MediatorPattern {

    public static void main(String[] args) {
        concreteMediator cm = new concreteMediator();
        ColleagueA a = new ColleagueA("tom", cm);
        ColleagueB b = new ColleagueB("jerry", cm);
        cm.setA(a);
        cm.setB(b);
        a.contact("i have something to b");
        b.contact("i busy!! don't intterupt me");
    }
}

abstract class Mediator {
    public abstract void contact(String content, Colleague coll);
}

class concreteMediator extends Mediator {
    ColleagueA a;
    ColleagueB b;

    public ColleagueA getA() {
        return a;
    }

    public void setA(ColleagueA a) {
        this.a = a;
    }

    public ColleagueB getB() {
        return b;
    }

    public void setB(ColleagueB b) {
        this.b = b;
    }

    @Override
    public void contact(String content, Colleague coll) {
        if (coll == a) {
            b.getMes(content);
        } else {
            a.getMes(content);
        }
    }
}


class ColleagueA extends Colleague {
    public ColleagueA(String name, Mediator mediator) {
        super(name, mediator);
    }

    public void getMes(String mes) {
        System.out.println("collA " + name + "get mes " + mes);
    }

    public void contact(String mes) {
        mediator.contact(mes, this);
    }
}

class ColleagueB extends Colleague {
    public ColleagueB(String name, Mediator mediator) {
        super(name, mediator);
    }

    public void getMes(String mes) {
        System.out.println("collB " + name + "get mes " + mes);
    }

    public void contact(String mes) {
        mediator.contact(mes, this);
    }
}

class Colleague {
    protected String name;
    protected Mediator mediator;

    public Colleague(String name, Mediator mediator) {
        this.name = name;
        this.mediator = mediator;
    }
}

行为型模式

备忘录模式

备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象

优点

缺点

使用场景

示例

public class MementoPattern {
    public static void main(String[] args) {
        ArchiveTool archiveTool = new ArchiveTool();
        ArchiveArea archiveArea = new ArchiveArea();

        archiveTool.setState("三打白骨精");
        archiveTool.setState("大战红孩儿");
        archiveArea.add(archiveTool.saveArchiveFile());
        archiveTool.setState("真假美猴王");
        archiveArea.add(archiveTool.saveArchiveFile());
        archiveTool.setState("三借芭蕉扇");
        archiveArea.add(archiveTool.saveArchiveFile());

        int i = 0;
        ArchiveFile file;
        while (true) {
            file = archiveArea.get(i);
            if (file == null) {
                return;
            }
            System.out.println("存档记录--" + file.getState());
            i++;
        }
    }
}

/**
 * 存档区
 */
class ArchiveArea {
    private List<ArchiveFile> archiveFiles = new ArrayList<>();

    public void add(ArchiveFile file) {
        archiveFiles.add(file);
    }

    public ArchiveFile get(Integer index) {
        if (index < archiveFiles.size()) {
            return archiveFiles.get(index);
        }

        return null;
    }
}

/**
 * 存档工具
 */
class ArchiveTool {
    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public ArchiveFile saveArchiveFile() {
        return new ArchiveFile(state);
    }

    public void getArchiveFileState(ArchiveFile archiveFile) {
        state = archiveFile.getState();
    }
}

/**
 * 存档文件
 */
class ArchiveFile {
    private String state;

    ArchiveFile(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}

行为型模式

观察者模式

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新

优点

缺点

使用场景

示例

public class ObserverPattern {
    
    public static void main(String[] args) {
        Subject subject = new Subject();
        Observer1 observer1 = new Observer1(subject);
        Observer2 observer2 = new Observer2(subject);
        subject.addObserver(observer1);
        subject.addObserver(observer2);
        subject.setState(10);
        subject.setState(100);
    }
}

class Observer1 extends Observer {
    Observer1(Subject subject) {
        this.subject = subject;
    }

    @Override
    void update() {
        System.out.println("观察者一号观察的对象状态改变为:" + subject.getState());
    }
}

class Observer2 extends Observer {
    Observer2(Subject subject) {
        this.subject = subject;
    }

    @Override
    void update() {
        System.out.println("观察者二号观察的对象状态改变为:" + subject.getState());
    }
}

class Subject {
    private List<Observer> observers = new ArrayList<>();

    private Integer state;

    public Integer getState() {
        return state;
    }

    public void setState(Integer state) {
        this.state = state;
        notifyAllObserver();
    }

    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    private void notifyAllObserver() {
        for (Observer observer : observers) {
            observer.update();
        }
    }

}

/**
 * 观察者
 */
abstract class Observer {
    protected Subject subject;
    void update(){};
}

行为型模式

状态模式

在状态模式(State Pattern)中,类的行为是基于它的状态改变的,在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象

优点

缺点

使用场景

示例

public class StatePattern {
    public static void main(String[] args) {
        Context context = new Context();
        StartState startState = new StartState();
        EndState endState = new EndState();
        startState.doAction(context);
        endState.doAction(context);
    }
}

class EndState implements State {
    @Override
    public void doAction(Context context) {
        System.out.println("context at end status");
        context.setState(this);
    }
}

class StartState implements State {
    @Override
    public void doAction(Context context) {
        System.out.println("context at start status");
        context.setState(this);
    }
}

interface State {
    void doAction(Context context);
}

class Context {
    private State state;

    Context() {
        state = null;
    }
    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }
}

行为型模式

策略模式

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改

优点

缺点

使用场景

示例 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法

public class StrategyPattern {

    public static void main(String[] args) {
        Army army1 = new Army(new OffensiveStrategy());
        Army army2 = new Army(new RetreatStrategy());

        army1.excuteStrategy();
        army2.excuteStrategy();
    }
}

class Army {
    private Strategy strategy;

    Army(Strategy strategy) {
        this.strategy = strategy;
    }

    void excuteStrategy() {
        strategy.doOperation();
    }
}

/**
 * 进攻策略
 */
class OffensiveStrategy implements Strategy {
    @Override
    public void doOperation() {
        System.out.println("执行进攻策略");
    }
}

/**
 * 撤退策略
 */
class RetreatStrategy implements Strategy {
    @Override
    public void doOperation() {
        System.out.println("执行撤退策略");
    }
}

interface Strategy {
    void doOperation();
}

行为型模式

空对象模式

在空对象模式(Null Object Pattern)中,一个空对象取代NULL对象实例的检查。Null对象不是检查空值,而是反应一个不做任何动作的关系。这样的 Null 对象也可以在数据不可用的时候提供默认的行为。

优点

缺点

使用场景

示例 在空对象模式中,我们创建一个指定各种要执行的操作的抽象类和扩展该类的实体类,还创建一个未对该类做任何实现的空对象类,该空对象类将无缝地使用在需要检查空值的地方

ublic class NullObjectPattern {

    public static void main(String[] args) {
        NullObjectPattern nullObjectPattern = new NullObjectPattern();

        Factory factory = nullObjectPattern.new Factory();
        System.out.println(factory.getSubject("haha").getName());
        System.out.println(factory.getSubject("PE").getName());
    }

     class Factory {
        public final String[] names = {"PE","MATH","LITERATURE","POLITICAL"};

        public Subject getSubject(String subject) {
            for (String name : names) {
                if (name.equals(subject)) {
                    return new SecondarySubject(subject);
                }
            }

            return new NullSubject();
        }
    }


    class NullSubject extends Subject {
        @Override
        boolean isNull() {
            return true;
        }

        @Override
        String getName() {
            return "not avilable subject";
        }
    }

    class SecondarySubject extends Subject {
        SecondarySubject( String name) {
            this.name = name;
        }

        @Override
        boolean isNull() {
            return false;
        }

        @Override
        String getName() {
            return name;
        }
    }

    abstract class Subject {
        String name;
        abstract boolean isNull();
        abstract String getName();
    }
}

行为型模式

模板模式

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行

优点

缺点

使用场景

示例 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,为防止恶意操作,一般模板方法都加上 final 关键词

public class TemplatePattern {
    public static void main(String[] args) {
        cooking tofuOfMapo = new TofuOfMapo();
        tofuOfMapo.cookingFood();

        cooking hotChicken = new HotChicken();
        hotChicken.cookingFood();
    }
}

class TofuOfMapo extends cooking{
    @Override
    void prePareCokie() {
        System.out.println("切豆腐");
        System.out.println("宽油");
    }

    @Override
    void cooking() {
        System.out.println("烧酱汁");
        System.out.println("放豆腐");
    }

    @Override
    void cookied() {
        System.out.println("起锅,装盘");
    }
}

class HotChicken extends cooking{
    @Override
    void prePareCokie() {
        System.out.println("杀鸡,放血,拔毛");
        System.out.println("刀工");
    }

    @Override
    void cooking() {
        System.out.println("宽油");
        System.out.println("烧制");
    }

    @Override
    void cookied() {
        System.out.println("起锅,装盘");
    }
}

abstract class cooking {
    abstract void prePareCokie();

    abstract void cooking();

    abstract  void cookied();

    public final void cookingFood() {
        prePareCokie();
        cooking();
        cookied();
    }
}

行为型模式

访问者模式

在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变,根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作

优点

缺点

使用场景

示例

public class VisitorPattern {
    public static void main(String[] args) {
        RealComputerVisitor visitor = new RealComputerVisitor();
        Computer computer = new Computer();
        computer.accept(visitor);

    }
}

class RealComputerVisitor implements ComputerVisitor {
    @Override
    public void visit(Computer computer) {
        System.out.println("visiting computer");
    }

    @Override
    public void visit(KeyBoard keyBoard) {
        System.out.println("visiting keyBoard");
    }

    @Override
    public void visit(Mouse mouse) {
        System.out.println("visiting mouse");
    }

    @Override
    public void visit(Monitor monitor) {
        System.out.println("visiting monitor");
    }
}

class Computer implements ComputerPart {
    ComputerPart[] parts;

    Computer() {
        parts = new ComputerPart[] {new Mouse(),new Monitor(),new KeyBoard()};
    }

    @Override
    public void accept(ComputerVisitor computerVisitor) {
        for (ComputerPart part : parts) {
            part.accept(computerVisitor);
        }
        computerVisitor.visit(this);
    }
}

interface ComputerVisitor {
    void visit(Computer computer);
    void visit(KeyBoard keyBoard);
    void visit(Mouse mouse);
    void visit(Monitor monitor);
}

class Monitor implements ComputerPart {
    @Override
    public void accept(ComputerVisitor computerVisitor) {
        computerVisitor.visit(this);
    }
}

class Mouse implements ComputerPart {
    @Override
    public void accept(ComputerVisitor computerVisitor) {
        computerVisitor.visit(this);
    }
}

class KeyBoard implements ComputerPart {
    @Override
    public void accept(ComputerVisitor computerVisitor) {
        computerVisitor.visit(this);
    }
}

interface ComputerPart {
    void accept(ComputerVisitor computerVisitor);
}

TODO 未完待续