理解23种设计模式思想

一、创建型模式

1.1 单例模式

保证整个应用中有且只有一个实例,避免创建多个实例造成资源浪费,避免多个实例在多次调用过程中出现结果错误

创建思路

  • 类的构造方法私有化,对其他类隐藏(不允许其他程序new对象)
  • 创建一个实例对象供其他类使用
  • 提供一个方法给其他类访问这个实例对象

思考:为什么一定要设置成静态的方法和实例?
首先,理解static:

  • 在类中,用static修饰的函数->静态成员变量
    作用:调用这个函数不能访问或修改任何非static对象的数据成员(在static的环境中是不允许访问非static的成员变量的)
    理解:类的静态成员属于类本身,在类加载时分配内存,可通过类名直接访问;而类的非静态成员属于类的对象,只有在类的对象产生时才会分配内存,通过类的对象实例访问(由于静态方法(类方法)是跟随类加载一起被加载进来的,而普通的成员变量是在实例化对象的时候才随之产生的,如果在静态方法中访问了普通的成员变量那么就是在访问一个不存在的变量,会导致错误)
  • 不在类中,用static修饰的函数->全局静态函数
    作用:不能被其他文件所用(普通函数默认是extern的,能被其他代码文件调用)

其次,了解访问一个类的2种方式:

  • 一是new一个对应的类的对象,通过对象.方法()来调用
  • 二是通过类名.方法名()来调用

答案

  • 单例模式的设计原则就是构造方法私有化,对其他类隐藏,因此访问这个类无法new对象,只能通过类名.方法名()来调用,所以单例模式中的getInstance()方法必须被定义为类方法,即必须加上static。
  • 根据Java语法要求,调用static函数不能访问或修改任何非static对象的数据成员,所以对应的实例对象也必须被定义为类属性,即必须加上static。

创建方式

// 1、饿汉式
public class Singleton {  
     private static Singleton instance = new Singleton();  
     private Singleton (){
     }
     public static Singleton getInstance() {  
     	return instance;  
     }  
 }  

// 2、懒汉式
public class Singleton {  
      private static Singleton instance;  
      private Singleton (){
      }   
      public static Singleton getInstance() {  
      if (instance == null) {  
          instance = new Singleton();  
      }  
      return instance;  
      }  
 }  

// 3、懒汉式-线程安全
public class Singleton {  
      private static Singleton instance;  
      private Singleton (){
      }
      public static synchronized Singleton getInstance() {  
      if (instance == null) {  
          instance = new Singleton();  
      }  
      return instance;  
      }  
 }  

// 4、双检模式

public class Singleton {  
      private volatile static Singleton instance;  
      private Singleton (){
      }   
      public static Singleton getInstance() {  
      if (instance== null) {  
          synchronized (Singleton.class) {  
          if (instance== null) {  
              instance= new Singleton();  
          }  
         }  
     }  
     return instance;  
     }  
 }  
// 5、静态内部类单例模式
public class Singleton { 
    private Singleton(){
    }
      public static Singleton getInstance(){  
        return SingletonHolder.Instance;  
    }  
    private static class SingletonHolder {  
        private static final Singleton Instance = new Singleton();  
    }  
} 

// 6、枚举单例模式
public enum Singleton {  
     INSTANCE;  
     public void doSomeThing() {  
     }  
 }  

1.2 工厂模式

工厂类根据传入的类型返回对应的处理类

public class FactoryDemo {
    public static void main(String[] args) {
        ShapeFactory shapeFactory = new ShapeFactory();
        Shape shapeDraw2 = shapeFactory.getShape("ShapeDraw2");
        shapeDraw2.draw();
    }
}
// 简单工厂模式的核心
class ShapeFactory{
    public Shape getShape(String s){
        if(s.equalsIgnoreCase("ShapeDraw")) return new ShapeDraw();
        if(s.equalsIgnoreCase("ShapeDraw2")) return new ShapeDraw2();
        return null;
    }
}
class ShapeDraw implements Shape{

    @Override
    public void draw() {
        System.out.println("ShapeDraw~");
    }
}
class ShapeDraw2 implements Shape{

    @Override
    public void draw() {
        System.out.println("ShapeDraw2~~");
    }
}
// 当方法较多时,也可以定义一个抽象类,和各种抽象方法
interface Shape{
    void draw();
}

1.3 抽象工厂模式

工厂根据二级工厂的类型返回二级工厂(继承抽象工厂),二级工厂根据传入的类型返回对应处理类。

public class AbstractFactoryDemo {
    public static void main(String[] args) {
        BuildFactory buildFactory = new BuildFactory();
        AbstractFactory colorFactory = buildFactory.getFactory("ColorFactory");
        Color blue = colorFactory.getColor("Blue");
        blue.fill();
    }
}
class BuildFactory{
    public AbstractFactory getFactory(String s){
        if (s.equalsIgnoreCase("ColorFactory")) return new ColorFactory();
        if (s.equalsIgnoreCase("ShapeShapeFactory")) return new ShapeShapeFactory();
        return null;
    }
}
class ColorFactory extends AbstractFactory{

    @Override
    public ShapeShape getShape(String s) {
        return null;
    }

    @Override
    public Color getColor(String c) {
        if (c.equalsIgnoreCase("Blue")) return new Blue();
        if (c.equalsIgnoreCase("Red")) return new Red();
        return null;
    }
}
class ShapeShapeFactory extends AbstractFactory{

    @Override
    public ShapeShape getShape(String s) {
        if(s.equalsIgnoreCase("Circle")) return new Circle();
        if(s.equalsIgnoreCase("Line")) return new Line();
        return null;
    }

    @Override
    public Color getColor(String c) {
        return null;
    }
}
abstract class AbstractFactory{
    public abstract ShapeShape getShape(String s);
    public abstract Color getColor(String c);
}
class Red implements Color{

    @Override
    public void fill() {
        System.out.println("红色");
    }
}
class Blue implements Color{

    @Override
    public void fill() {
        System.out.println("蓝色");
    }
}
class Line implements ShapeShape{

    @Override
    public void draw() {
        System.out.println("这是一条line");
    }
}
class Circle implements ShapeShape{

    @Override
    public void draw() {
        System.out.println("这是一个circle");
    }
}

interface Color{
    void fill();
}
interface ShapeShape{
    void draw();
}

1.4 建造者模式

将内部生产细节隐藏,提供不同的生产方法,使一个建造过程生成具有不同的内部表象的产品对象。

public class BuilderFactoryDemo {
    public static void main(String[] args) {
        MealBuilder mealBuilder = new MealBuilder();
        Meal meal = mealBuilder.chickenMealOrder();
        meal.showItems();
        //meal.getPrices();
        System.out.println("Cost:" +meal.getPrices());
    }
}
//获取套餐的类
class MealBuilder{
    public Meal vegMealOrder(){
        Meal meal = new Meal();
        meal.addItem( new VegBurger());
        meal.addItem(new Coke());
        return meal;
    }
    public Meal chickenMealOrder(){
        Meal meal = new Meal();
        meal.addItem(new ChickenBurger());
        meal.addItem(new Pepsi());
        return meal;
    }
}
//套餐 用一个ArrayList存储
class Meal{
    private List<Item> items = new ArrayList<>();
    public void addItem(Item item){
        items.add(item);
    }
    public float getPrices(){
        float prices = 0.0f;
        for(Item item:items){
            prices += item.price();
        }
        return prices;
    }
    public void showItems(){
        for(Item item: items){
            System.out.println("Item:" +item.name());
            System.out.println("Packing:" +item.packing().pack());
            System.out.println("Price:" +item.price());
        }
    }
}
//构建Burger和ColdDrink的实体类
class VegBurger extends Burger{

    @Override
    public String name() {
        return "VegBurger";
    }

    @Override
    public float price() {
        return 25.0f;
    }
}
class ChickenBurger extends Burger{

    @Override
    public String name() {
        return "ChickenBurger";
    }

    @Override
    public float price() {
        return 50.0f;
    }
}
class Coke extends ColdDrink{

    @Override
    public String name() {
        return "Coke";
    }

    @Override
    public float price() {
        return 8.0f;
    }
}
class Pepsi extends ColdDrink{

    @Override
    public String name() {
        return "Pepsi";
    }

    @Override
    public float price() {
        return 9.0f;
    }
}
//实现Item接口的抽象类
abstract class Burger implements Item{
    @Override
    public Packing packing() {
        return new Wrapper();
    }

    @Override
    public abstract float price();
}
abstract class ColdDrink implements Item{
    @Override
    public Packing packing() {
        return new Bottle();
    }

    @Override
    public abstract float price();
}
//实现packing接口的实体类
class Wrapper implements Packing{

    @Override
    public String pack() {
        return "Wrapper";
    }
}
class Bottle implements Packing{

    @Override
    public String pack() {
        return "Bottle";
    }
}
//食物条目
interface Item{
    public String name();
    public Packing packing();
    public float price();
}
//食物包装
interface Packing{
    public String pack();
}

1.5 原型模式

用于创建重复的对象。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
Hashtable:数据库获取实体类,并把它们存储在一个 Hashtable中(Hashtable与Hashmap相比,不允许存null的key)

public class ProtoDemo {
    public static void main(String[] args) {
        ShapeCache.loadCache();
        Shape cloneShape = ShapeCache.getShape("1");
        System.out.println("Shape type:" +cloneShape.type);
        cloneShape.draw();
    }
}
//创建一个类,从数据库获取实体类,保存在ShapeCache中的Hashtable
class ShapeCache{
    private static Hashtable<String,Shape> hashtable = new Hashtable<String,Shape>();
    public static Shape getShape(String shapeId){
        Shape cacheShape = hashtable.get(shapeId);
        return (Shape) cacheShape.clone();//有这个方法 是因为Shape类实现了Cloneable接口

    }
    //数据库查询,创建形状
    public static void loadCache(){
        Circle circle = new Circle();
        circle.setId("1");
        hashtable.put(circle.getId(), circle);

        Line line = new Line();
        line.setId("2");
        hashtable.put(line.getId(), line);
    }
}
class Line extends Shape{
    public Line() {
        type = "Line";
    }

    @Override
    void draw() {
        System.out.println("Line");
    }
}
class Circle extends Shape{
    public Circle() {
        type = "Circle";
    }

    @Override
    void draw() {
        System.out.println("Circle");
    }
}
//实现了Cloneable接口的抽象类
abstract class Shape implements Cloneable{
    private String id;
    protected String type;
    abstract void draw();

    public String getId() {
        return id;
    }

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

    public String getType() {
        return type;
    }

    public Object clone(){
        Object clone = null;
        try {
            clone = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }
}

二、结构型模式

2.1 适配器模式

把一个接口转为另一个接口。

public class AdapterDemo {
    public static void main(String[] args) {
        AudioPlayer audioPlayer = new AudioPlayer();
        audioPlayer.play("Vlc","yoyoyo.Vlc");
        audioPlayer.play("Mp4","yoyoyo.Mp4");
        audioPlayer.play("Mp3","yoyoyo.Mp3");
        audioPlayer.play("avi","yoyoyo.avi");
    }
}
//原媒体,只能播放Mp3
interface MediaPlayer{
    public void play(String type, String name);
}
//改进的媒体,扩展了两种
interface AdvancedMediaPlayer{
    public void playVlc(String name);
    public void playMp4(String name);
}
class VlcPlayer implements AdvancedMediaPlayer{

    @Override
    public void playVlc(String name) {
        System.out.println("playing Vlc:" + name);
    }

    @Override
    public void playMp4(String name) {

    }
}
class Mp4Player implements AdvancedMediaPlayer{

    @Override
    public void playVlc(String name) {

    }

    @Override
    public void playMp4(String name) {
        System.out.println("playing Mp4:" + name);
    }
}
//创建适配器类 实现原MediaPlayer接口
class MediaAdapter implements MediaPlayer{
    AdvancedMediaPlayer advancedMediaPlayer;

    public MediaAdapter(String type) {
        if(type.equalsIgnoreCase("Vlc")) advancedMediaPlayer = new VlcPlayer();
        if(type.equalsIgnoreCase("Mp4")) advancedMediaPlayer = new Mp4Player();
    }

    @Override
    public void play(String type, String name) {
        if(type.equalsIgnoreCase("Vlc")) advancedMediaPlayer.playVlc(name);
        if(type.equalsIgnoreCase("Mp4")) advancedMediaPlayer.playMp4(name);
    }
}
class AudioPlayer implements MediaPlayer{
    MediaAdapter mediaAdapter;
    @Override
    public void play(String type, String name) {
        if(type.equalsIgnoreCase("Vlc") || type.equalsIgnoreCase("Mp4")){
            mediaAdapter = new MediaAdapter(type);
            mediaAdapter.play(type,name);
        }else if (type.equalsIgnoreCase("Mp3")){
            System.out.println("Playing Mp3");
        }else{
            System.out.println("This is not a support type");
        }
    }
}

2.2 桥接模式

用于把抽象化与实现化解耦,使得二者可以独立变化

public class BridgeDemo {
    public static void main(String[] args) {
        Circle circle = new Circle(new BlueCircle(), 3, 1, 1);
        circle.draw();
    }
}
//桥接实现接口
interface DrawAPI{
    public void drawCircle(int radio, int x,int y);
}
//实体的桥接实现类
class BlueCircle implements DrawAPI{

    @Override
    public void drawCircle(int radio, int x, int y) {
        System.out.println("BlueCircle: radio:" + radio+ " x:" + x + " y:" + y);
    }
}
class RedCircle implements DrawAPI{

    @Override
    public void drawCircle(int radio, int x, int y) {
        System.out.println("RedCircle: radio:" + radio+ "x:" + x + "y:" + y);
    }
}
//抽象类Shape,用DrawAPI接口创建
abstract class Shape{
    protected DrawAPI drawAPI;

    protected Shape(DrawAPI drawAPI) {
        this.drawAPI = drawAPI;
    }
    public abstract void draw();
}
class Circle extends Shape{
    private int radio, x,y;

    public Circle(DrawAPI drawAPI, int radio, int x, int y) {
        super(drawAPI);
        this.radio = radio;
        this.x = x;
        this.y = y;
    }

    @Override
    public void draw() {
        drawAPI.drawCircle(radio,x,y);
    }
}

2.3 装饰者模式

给目标类添加一些辅助的功能,并且不改变这个类的代码
原则:类应该对扩展开放,对修改关闭。

public class DecorateDemo {
    public static void main(String[] args) {
        RedShapeDecorate redShapeDecorate = new RedShapeDecorate(new Circle());
        redShapeDecorate.draw();

        Line line = new Line();
        line.draw();
    }
}
public class RedShapeDecorate extends ShapeDecorate{
    public RedShapeDecorate(Shape shape) {
        super(shape);
    }

    @Override
    public void draw() {
        shape.draw();
        setRed(shape);
        //System.out.println("Red decorating");
    }
    private void setRed(Shape shape){
        System.out.println("Red decorating");
    }
}
// 装饰者抽象类
public abstract class ShapeDecorate implements Shape{
    protected Shape shape;//为什么要用protected修饰?如果是私有的,那么继承这个抽象类的实体类无法调用该对象;protected本包+所有子类

    public ShapeDecorate(Shape shape) {
        this.shape = shape;
    }

    @Override
    public void draw() {
        shape.draw();
    }
}
public class Circle implements Shape{
    @Override
    public void draw() {
        System.out.println(" Drawing Circle");
    }
}
public class Line implements Shape{
    @Override
    public void draw() {
        System.out.println("Drawing Line");
    }
}
public interface Shape {
    void draw();
}

2.4 组合模式

用于把一组相似的对象当作一个单一的对象,依据树形结构来组合对象,用来表示部分以及整体层次
主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。

public class CompositeDemo {
    public static void main(String[] args) {
        Employee employee1 = new Employee("yihao", "CEO", "1");
        Employee employee2 = new Employee("erhao", "head develop", "1");
        Employee employee3 = new Employee("sanhao", "head test", "1");
        Employee employee4 = new Employee("sihao", "test", "1");
        Employee employee5 = new Employee("wuhao", "develop", "1");
        Employee employee6 = new Employee("liuhao", "test", "1");

        employee1.add(employee2);
        employee1.add(employee3);
        employee2.add(employee5);
        employee3.add(employee4);
        employee3.add(employee6);

        List<Employee> subordinates = employee3.getSubordinates();
        for (Employee employee:subordinates){
            System.out.println(employee);

        }

    }
}
public class Employee {
    private String name;
    private String dept;
    private String salary;
    private List<Employee> subordinates;

    public Employee(String name, String dept, String salary) {
        this.name = name;
        this.dept = dept;
        this.salary = salary;
        subordinates = new ArrayList<Employee>();
    }
    public void add(Employee employee){
        subordinates.add(employee);
    }
    public void remove(Employee employee){
        subordinates.remove(employee);
    }
    public List<Employee> getSubordinates(){
        return subordinates;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", dept='" + dept + '\'' +
                ", salary='" + salary + '\'' +
                ", subordinates=" + subordinates +
                '}';
    }
}

2.5 外观模式

提供一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层的接口,让子系统更容易使用。其实就是为了方便客户的使用,把一群操作,封装成一个方法。

public class FacadeDemo {
    public static void main(String[] args) {
        ShapeMaker shapeMaker = new ShapeMaker();
        shapeMaker.drawCircle();
    }
}
public class ShapeMaker{
    private Shape circle;
    private Shape line;

    public ShapeMaker( ) {
        circle = new Circle();
        line = new Line();
    }

    public void drawCircle(){
        circle.draw();
    }
    public void drawLine(){
        line.draw();
    }
}
public class Line implements Shape{
    @Override
    public void draw() {
        System.out.println("drawing line");
    }
}
public class Circle implements Shape{
    @Override
    public void draw() {
        System.out.println("drawing circle");
    }
}
public interface Shape {
    void draw();
}

2.6 享元模式

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

public class FlyweightDemo {
    private static String colors[] = {"yellow","blue","red","black","white"};
    public static void main(String[] args) {
        Circle shape1 = ShapeFactory.getCircle("blue");//此时被创建出来保存在hashmap中
        Circle shape = ShapeFactory.getCircle("blue");
        shape.setRadio(1);
        shape.setX(1);
        shape.setY(1);
        shape.draw();
    }
}
// 核心类 尝试重用现有的同类对象
public class ShapeFactory {
    private static final HashMap<String, Circle> hashMap = new HashMap<>();
    public static Circle getCircle(String color){
        Circle shape = (Circle) hashMap.get(color);
        if (shape == null){
            Circle circle = new Circle(color);
            hashMap.put(color, circle);
            System.out.println("creating a circle");

        }
        return  shape;
    }
}
public class Circle {
    private String color;
    private int x;
    private int y;
    private int radio;

    public Circle(String color) {
        this.color = color;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    public void setRadio(int radio) {
        this.radio = radio;
    }
    public void draw(){
        System.out.println("drawing circle: color:" + color+" x:" +x+" y:"+y+" radio:"+radio);
    }
}
public interface Shape {
    void draw();
}

2.7 代理模式

一个类代表另一个类的功能。创建具有现有对象的对象,以便向外界提供功能接口。可以理解为内存中没有这个对象就创建,有就直接返回这个对象。
主要解决:直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。

public class TestStudent {
    @Test
    public void testStudent(){
        Student student = new Student();
        StudentServiceImpl studentService = new StudentServiceImpl();
        DaoTransaction daoTransaction = new DaoTransaction();
        ProxyStudent proxyStudent = new ProxyStudent(studentService, daoTransaction);
        proxyStudent.save();
        System.out.println(proxyStudent.query((long) 1));

    }
}
public class ProxyStudent implements IStudentService {
    // 将被代理的类传进来 目标类对象
    private StudentServiceImpl studentService;
    // 将事务拓展类传进来 增强类对象
    private DaoTransaction transaction;
    // 属性是空的,通过构造器传进来
    public ProxyStudent(IStudentService studentService,DaoTransaction transaction){
        this.studentService = (StudentServiceImpl) studentService;
        this.transaction = transaction;
    }
    public void save() {
        transaction.before();
        studentService.save();
        transaction.after();

    }

    public Student query(Long id) {
        return studentService.query(id);
    }
}
public class DaoTransaction {
    public void before(){
        System.out.println("开启事务");
    }
    public void after(){
        System.out.println("关闭事务");
    }
}
public class StudentServiceImpl implements IStudentService {
    public void save() {
        System.out.println("保存学生信息");
    }

    public Student query(Long id) {
        System.out.println("查询操作");
        Student student = new Student();
        student.setAge(18);
        student.setName("qinxiang");
        return student;
    }
}
public interface IStudentService {
    /**
     * 添加学生
     */
    void save();

    /**
     * 查询学生信息
     * @param id
     * @return
     */
    Student query(Long id);
}

@Data
public class Student {
    private String name;
    private int age;
}

三、行为型模式

3.1 模板方法模式

子类可以在不改变算法结构的情况下,重新定义算法的步骤。

public class TemplatePatternDemo {
    public static void main(String[] args) {
        Game game = new Cricket();
        game.play();
        System.out.println();
        game = new Football();
        game.play();
    }
}
public class Cricket extends Game{
    @Override
    void initialize() {
        System.out.println("Cricket Game Initialized. Start playing");
    }

    @Override
    void startPlay() {
        System.out.println("Cricket Game started. Enjoy the game");
    }

    @Override
    void endPlay() {
        System.out.println("Cricket Game Finished");
    }
}
public class Football extends Game{
    @Override
    void initialize() {
        System.out.println("Football Game Initialized. Start playing");
    }

    @Override
    void startPlay() {
        System.out.println("Football Game started. Enjoy the game");
    }

    @Override
    void endPlay() {
        System.out.println("Football Game Finished");
        System.out.println("add another");
    }
}
//  * 在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。
// 它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。

public abstract class Game {
    abstract void initialize();
    abstract void startPlay();
    abstract void endPlay();
    public final void play(){
        initialize();
        startPlay();
        endPlay();
    }
}

3.2 命令模式

将“请求”封装成对象,将动作请求者和动作执行者解耦,以便使用不同的请求、队列或者日志来参数化其他对象。

public class CommandDemo {
    public static void main(String[] args) {
        Stock stock = new Stock();
        BuyStock buyStock = new BuyStock(stock);
        SellStock sellStock = new SellStock(stock);
        Broker broker = new Broker();
        broker.takeOrder(buyStock);
        broker.takeOrder(sellStock);
        broker.placeOrder();

    }
}
// 核心类 命令调用类
public class Broker {
    private List<Order> list = new ArrayList<>();
    public void takeOrder(Order order){
        list.add(order);
    }
    public void placeOrder(){
        for(Order order: list){
            order.execute();
        }
        list.clear();
    }
}
public class BuyStock implements Order{
    private Stock stock;

    public BuyStock(Stock stock) {
        this.stock = stock;
    }

    @Override
    public void execute() {
        stock.buy();
    }
}
public class SellStock implements Order{
    private Stock stock;

    public SellStock(Stock stock) {
        this.stock = stock;
    }

    @Override
    public void execute() {
        stock.sell();
    }
}
// 请求类 买卖商品
public class Stock {
    private String name = "ABC";
    private int quantity = 5;
    public void buy(){
        System.out.println(" buy stock name:" + name+" quantity:"+quantity);
    }
    public void sell(){
        System.out.println("sell stock name:"+name+" quantity:"+quantity);
    }
}
public interface Order {
    void execute();
}

3.3 迭代器模式

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

public class IteratorDemo {
    public static void main(String[] args) {
        NameRepository nameRepository = new NameRepository();
        Iterator iterator = nameRepository.getIterator();
        while(iterator.hasNext()){
            Object next = iterator.next();
            System.out.println(next);
        }

    }
}
// 核心类
public class NameRepository implements Container{
    public String[] names = {"yihao","erhao","sanhao","sihao"};
    @Override
    public Iterator getIterator() {
        return new NameIterator();
    }
    private class NameIterator implements Iterator{
        int index;

        @Override
        public boolean hasNext() {
            if(index < names.length){
                return true;
            }
            return false;
        }

        @Override
        public Object next() {
            if(this.hasNext()){
                return names[index++];
            }
            return null;
        }
    }
}
public interface Container {
    public Iterator getIterator();
}
public interface Iterator {
    public boolean hasNext();
    public Object next();
}

3.4 观察者模式

定义了对象之间的一对多的依赖,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。

public class ObserverDemo {
    public static void main(String[] args) {
        Subject subject = new Subject();
        BinaryObserver binaryObserver = new BinaryObserver(subject);
        //binaryObserver.update();
        OctalObserver octalObserver = new OctalObserver(subject);
        //subject.notifyAllObservers();
        //octalObserver.update();
        subject.setState(6);
    }
}
public class Subject {
    private List<Observer> observers = new ArrayList<>();
    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        notifyAllObservers();
    }
    public void attach(Observer object){
        observers.add(object);
    }
    public void notifyAllObservers(){
        for (Observer observer:observers){
            observer.update();
        }
    }
}
public class BinaryObserver extends Observer{
    public BinaryObserver(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println("binary String:" + Integer.toBinaryString(subject.getState()));
    }
}
public class OctalObserver extends Observer{
    public OctalObserver(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println("octal String:" + Integer.toOctalString(subject.getState()));
    }
}
public abstract class Observer {
    protected Subject subject;
    public abstract void update();
}

3.5 中介者模式

用来降低多个对象和类之间的通信复杂性。中介类处理不同类之间的通信,并支持松耦合,使代码易于维护。

public class MediatorDemo {
    public static void main(String[] args) {
        User zhangsan = new User("zhangsan");
        User lisi = new User("lisi");
        zhangsan.sendMessage("去吃饭");
        lisi.sendMessage("好!");


    }
}
// 核心类 中介类 在User的方法中被调用
public class ChatRoom {
    public static void showMessage(User user, String message){
        String s = new Date().toString();
        System.out.println(s+" user:"+user.getName()+" send a message:"+message);
    }

}
public class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public void sendMessage(String message){
        ChatRoom.showMessage(this,message);
    }
}

3.6 备忘录模式

保存一个对象的某个状态,以便在适当的时候恢复对象

public class MementoDemo {
    public static void main(String[] args) {
        Originator originator = new Originator();
        CareTaker careTaker = new CareTaker();
        originator.setState("1hao");
        careTaker.add(originator.saveStateToMemento());
        originator.setState("2hao");
        careTaker.add(originator.saveStateToMemento());
        originator.setState("3hao");
        careTaker.add(originator.saveStateToMemento());
        Memento memento = careTaker.get(2);
        originator.getStateFromMemento(memento);
        String state = originator.getState();
        System.out.println(state);
    }
}
public class Originator {
    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
    public Memento saveStateToMemento(){
        Memento memento = new Memento(state);
        return memento;
    }
    public void getStateFromMemento(Memento memento){
        state = memento.getState();
    }
}
// 核心类
public class CareTaker {
    List<Memento> mementoList = new ArrayList<>();//用于保存Memento,增加add或者根据索引得到get
    public void add(Memento m){
        mementoList.add(m);
    }
    public Memento get(int index){
        return mementoList.get(index);
    }
}
public class Memento {
    private String state;

    public Memento(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }
}

3.7 解释器模式

实现一个表达式接口,该接口解释一个特定的上下文。应用于 SQL 解析、符号处理引擎等。

public class InterpreterDemo {
    public static void main(String[] args) {
        boolean john = getMaleExpression("john");
        System.out.println("john is a male? " + john);


    }
    public static boolean getMaleExpression(String s){
        TerminalExpression john = new TerminalExpression("john");
        TerminalExpression shone = new TerminalExpression("shone");
        OrExpression orExpression = new OrExpression(john, shone);
        return orExpression.interpret(s);
    }
}
public class TerminalExpression implements Expression{
    private String data;

    public TerminalExpression(String data) {
        this.data = data;
    }

    @Override
    public boolean interpret(String context) {
        if(context.contains(data)){
            return true;
        }
        return false;
    }
}
public class OrExpression implements Expression{
    private Expression expression1;
    private Expression expression2;

    public OrExpression(Expression expression1, Expression expression2) {
        this.expression1 = expression1;
        this.expression2 = expression2;
    }

    @Override
    public boolean interpret(String context) {
        return expression1.interpret(context) || expression2.interpret(context);
    }
}
public class AndExpression implements Expression{
    private Expression expression1;
    private Expression expression2;

    public AndExpression(Expression expression1, Expression expression2) {
        this.expression1 = expression1;
        this.expression2 = expression2;
    }

    @Override
    public boolean interpret(String context) {
        return expression1.interpret(context) && expression2.interpret(context);
    }
}
// 表达式接口
public interface Expression {
    public boolean interpret(String context);
}

3.8 状态模式

当对象的内部状态改变时,它的行为跟随状态的改变而改变了,看起来好像重新初始化了一个类似的。

public class StateDemo {
    public static void main(String[] args) {
        StartState startState = new StartState();
        Context context = new Context();
        startState.doState(context);
        System.out.println(context.getState().toString());
        System.out.println(context.toString());;
        System.out.println(startState.toString());;

    }
}
public class StartState implements State{
    @Override
    public void doState(Context context) {
        System.out.println("player is in start state");
        context.setState(this);
    }

    @Override
    public String toString() {
        return "StartState{}";
    }
}
public class Context {
    private State state;

    public Context() {

    }

    public State getState() {
        return state;
    }

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

    @Override
    public String toString() {
        return "Context{" +
                "state=" + state +
                '}';
    }
}
public interface State {
    public void doState(Context context);
}

3.9 策略模式

定义了算法族,分别封装起来,让它们之间可相互替换,此模式让算法的变化独立于使用算法的客户。
1、封装变化(把可能变化的代码封装起来)
2、多用组合,少用继承
3、针对接口编程,不针对实现

public class StrategyDemo {
    public static void main(String[] args) {
        Context context = new Context(new AddOperation());
        System.out.println(context.doStrategy(2,4));
    }
}
public class AddOperation implements Strategy{
    @Override
    public int doOperation(int num1, int num2) {
        return num1+num2;
    }
}
// 核心类 封装上下文对象
public class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }
    public int doStrategy(int num1,int num2){
        return strategy.doOperation(num1,num2);
    }
}
public interface Strategy {
    public int doOperation(int num1,int num2);
}

3.10 责任链模式

为请求创建一个接收者对象的链,将请求的发送者和请求的处理者解耦。
每个接收者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

public class ChainDemo {
    private static AbstractLogger getChainOfLoggers(){
        ErrorLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
        FileLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);
        ConsoleLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);
        errorLogger.setNextLogger(fileLogger);
        fileLogger.setNextLogger(consoleLogger);
        return errorLogger;
    }
    public static void main(String[] args) {
        AbstractLogger chainOfLoggers = getChainOfLoggers();
        //chainOfLoggers.logMessage(AbstractLogger.INFO,"this is a info message");
//        chainOfLoggers.logMessage(AbstractLogger.DEBUG,"this is a debug message");
        chainOfLoggers.logMessage(AbstractLogger.ERROR,"this is a error message");

    }
}
public class ErrorLogger extends AbstractLogger{
    public ErrorLogger(int level) {
        this.level = level;
    }

    @Override
    void write(String message) {
        System.out.println("error logger:" + message);
    }
}
public class FileLogger extends AbstractLogger{
    public FileLogger(int level) {
        this.level = level;
    }

    @Override
    void write(String message) {
        System.out.println("file logger:" + message);
    }
}
public class ConsoleLogger extends AbstractLogger {
    public ConsoleLogger(int level) {
        this.level = level;
    }

    @Override
    void write(String message) {
        System.out.println("console logger:" + message);
    }
}
public abstract class AbstractLogger {
    public static int INFO = 1;
    public static int DEBUG = 2;
    public static int ERROR = 3;
    protected int level;

    protected AbstractLogger nextLogger;

    public void setNextLogger(AbstractLogger nextLogger) {
        this.nextLogger = nextLogger;
    }
    public void logMessage(int level, String message){
        if(this.level <= level){
            write(message);
        }
        // 递归效果,不断调用下一级
        if (nextLogger != null){
            nextLogger.logMessage(level, message);
        }
    }
    abstract void write(String message);
}

3.11 访问者模式

使用一个访问者类,元素的执行算法可以随着访问者改变而改变。
元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。
主要解决:稳定的数据结构和易变的操作耦合问题。

public class VisitorDemo {
    public static void main(String[] args) {
        Computer computer = new Computer();

        computer.accept(new ComputerDisplayVisitor());
    }
}
// 核心类 访问者类
public class ComputerDisplayVisitor implements ComputerVisitor{
    @Override
    public void visit(Keyboard keyboard) {
        System.out.println("display keyboard");
    }

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

    }

    @Override
    public void visit(Computer computer) {
        System.out.println("display computer");

    }
}
public class Computer implements ComputerPart{
    ComputerPart[] parts;

    public Computer() {
        parts = new ComputerPart[]{new Mouse(),new Keyboard()};
    }

    @Override
    public void accept(ComputerVisitor computerVisitor) {
        for (int i = 0;i<parts.length;i++){
            parts[i].accept(computerVisitor);
        }
        computerVisitor.visit(this);
    }
}
public class Keyboard implements ComputerPart{
    @Override
    public void accept(ComputerVisitor computerVisitor) {
        computerVisitor.visit(this);
    }
}
public class Mouse implements ComputerPart{

    @Override
    public void accept(ComputerVisitor computerVisitor) {
        computerVisitor.visit(this);
    }
}
public interface ComputerVisitor {
    public  void visit(Keyboard keyboard);
    public  void visit(Mouse mouse);
    public  void visit(Computer computer);
}
public interface ComputerPart {
    public void accept(ComputerVisitor computerVisitor);
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值