Java开发者必备:23种设计模式全面解析

news2024/12/30 1:17:06

文章目录

  • 一、创建型模式
    • 1、工厂模式
      • 简单工厂
      • 工厂方法
    • 2、抽象工厂模式
    • 3、原型模式
    • 4、建造者模式
    • 5、单例模式
  • 二、结构型模式
    • 1、适配器模式
    • 2、桥接模式
    • 3、组合模式
    • 4、装饰模式
    • 5、外观模式
    • 6、享元模式
    • 7、代理模式
  • 三、行为型模式
    • 1、解释器模式
    • 2、模板方法模式
    • 3、策略模式
    • 4、观察者模式
    • 5、状态模式
    • 6、备忘录模式
    • 7、迭代器模式
    • 8、命令模式
    • 9、责任链模式
    • 10、中介者模式
    • 11、访问者模式


创建型结构型行为型
工厂模式(简单工厂、工厂方法)适配器 Adapter责任链 Chain of Responsibility
抽象工厂模式桥接 Bridge命令 Command
原型模式组合 Composite解释器 Interpreter
建造者模式装饰 Decorator迭代器 Iterator
单例模式外观 Facade中介 Mediator
享元 Flyweight备忘录 Memento
代理 Proxy观察者 Observer
状态 State
策略 Strategy
模板方法 Template Method
访问者 Visitor
  • 创建型包含5种模式,涉及对象/对象组合的创建构建。
  • 结构性包含7种模式,涉及对象/类之间的关系。
  • 行为型包含11种模式,涉及对象/类的行为、状态、流程。

一、创建型模式

1、工厂模式

简单工厂

在这里插入图片描述

public class OperationFactory {
    public static Operation createOperation(char operator) {
        Operation operation;

        switch (operator) {
            case '+':
                operation = new OperationAdd();
                break;
            case '-':
                operation = new OperationSub();
                break;
            case '*':
                operation = new OperationMul();
                break;
            case '/':
                operation = new OperationDiv();
                break;
            default:
                throw new RuntimeException("unsupported operation");
        }

        return operation;
    }
}
public abstract class Operation {
    public double numberA;
    public double numberB;

    public abstract double getResult();
}
public class OperationAdd extends Operation {

    @Override
    public double getResult() {
        return numberA + numberB;
    }

}
public class OperationSub extends Operation {

    @Override
    public double getResult() {
        return numberA - numberB;
    }

}
public class OperationMul extends Operation {

    @Override
    public double getResult() {
        return numberA * numberB;
    }

}
public class OperationDiv extends Operation {

    @Override
    public double getResult() {
        if (numberB == 0) {
            throw new RuntimeException("divided by 0");
        }
        return numberA / numberB;
    }

}
/**
 * 使用工厂方法生成实例完成运算操作
 */
public class Calculator {
    public static void main(String[] args) {
        Operation operation;
        char operator;

        operator = '+';
        operation = OperationFactory.createOperation(operator);
        operation.numberA = 1.2;
        operation.numberB = 2.3;

        System.out.println(operation.getResult());
    }
}

工厂方法

工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
在这里插入图片描述

/**
 * 工厂接口
 */
public interface IFactory {
    Operation createOperation();
}
public class AddFactory implements IFactory {

    @Override
    public Operation createOperation() {
        return new OperationAdd();
    }

}
public class SubFactory implements IFactory {

    @Override
    public Operation createOperation() {
        return new OperationSub();
    }

}
public class MulFactory implements IFactory {

    @Override
    public Operation createOperation() {
        return new OperationMul();
    }

}
public class DivFactory implements IFactory {

    @Override
    public Operation createOperation() {
        return new OperationDiv();
    }

}

类Operation、OperationAdd、OperationSub、OperationMul、OperationDiv同上

/**
 * 工厂方法客户端
 */
public class FactoryClient {

    public static void main(String[] args) {
        IFactory operFactory = new DivFactory();
        Operation operation = operFactory.createOperation();

        operation.numberA = 3.4;
        operation.numberB = 4.5;

        System.out.println(operation.getResult());

    }
}

2、抽象工厂模式

抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
在这里插入图片描述

// 抽象工厂
public abstract class AbstractFactory {
    public abstract AbstractProductA createProductA();
    public abstract AbstractProductB createProductB();
}
// 具体工厂1
public class ConcreteFactory1 extends AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ProductA1();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ProductB1();
    }
}
// 具体工厂2
public class ConcreteFactory2 extends AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ProductA2();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ProductB2();
    }
}
// 抽象产品A
public abstract class AbstractProductA {
    public abstract void methodA();
}
// 具体产品A1
public class ProductA1 extends AbstractProductA {
    @Override
    public void methodA() {
        System.out.println("ProductA1's methodA");
    }
}
// 具体产品A2
public class ProductA2 extends AbstractProductA {
    @Override
    public void methodA() {
        System.out.println("ProductA2's methodA");
    }
}
// 抽象产品B
public abstract class AbstractProductB {
    public abstract void methodB();
}
// 具体产品B1
public class ProductB1 extends AbstractProductB {
    @Override
    public void methodB() {
        System.out.println("ProductB1's methodB");
    }
}
// 具体产品B2
public class ProductB2 extends AbstractProductB {
    @Override
    public void methodB() {
        System.out.println("ProductB2's methodB");
    }
}
// 客户端
public class Client {
    public static void main(String[] args) {
        // 使用具体工厂1
        AbstractFactory factory1 = new ConcreteFactory1();
        AbstractProductA productA1 = factory1.createProductA();
        AbstractProductB productB1 = factory1.createProductB();
        productA1.methodA();
        productB1.methodB();

        // 使用具体工厂2
        AbstractFactory factory2 = new ConcreteFactory2();
        AbstractProductA productA2 = factory2.createProductA();
        AbstractProductB productB2 = factory2.createProductB();
        productA2.methodA();
        productB2.methodB();
    }
}

3、原型模式

原型模式,用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
在这里插入图片描述

// 原型接口
public interface Prototype {
    Prototype clone();
}
// 具体原型A
public class ConcretePrototypeA implements Prototype {
    @Override
    public Prototype clone() {
        try {
            return (ConcretePrototypeA) super.clone();
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }
}
// 具体原型B
public class ConcretePrototypeB implements Prototype {
    @Override
    public Prototype clone() {
        try {
            return (ConcretePrototypeB) super.clone();
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }
}
// 客户端
public class Client {
    public static void main(String[] args) {
        // 创建具体原型A和具体原型B
        ConcretePrototypeA prototypeA = new ConcretePrototypeA();
        ConcretePrototypeB prototypeB = new ConcretePrototypeB();

        // 克隆具体原型A和具体原型B
        ConcretePrototypeA cloneA = (ConcretePrototypeA) prototypeA.clone();
        ConcretePrototypeB cloneB = (ConcretePrototypeB) prototypeB.clone();

        // 检查克隆是否成功
        System.out.println("Clone A == Prototype A: " + (cloneA!= prototypeA));
        System.out.println("Clone B == Prototype B: " + (cloneB!= prototypeB));
    }
}

4、建造者模式

建造者模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
在这里插入图片描述

// 产品类
public class Product {
    private String part1;
    private String part2;

    public void setPart1(String part1) {
        this.part1 = part1;
    }

    public void setPart2(String part2) {
        this.part2 = part2;
    }

    public void show() {
        System.out.println("Part 1: " + part1);
        System.out.println("Part 2: " + part2);
    }
}
// 建造者接口
public interface Builder {
    void buildPart();
    Product getResult();
}
// 具体建造者类
public class ConcreteBuilder implements Builder {
    private Product product = new Product();

    @Override
    public void buildPart() {
        product.setPart1("Part 1 built by ConcreteBuilder");
        product.setPart2("Part 2 built by ConcreteBuilder");
    }

    @Override
    public Product getResult() {
        return product;
    }
}
// 指挥者类
public class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public void construct() {
        builder.buildPart();
    }
}
// 客户端
public class Client {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);

        director.construct();
        Product product = builder.getResult();
        product.show();
    }
}

5、单例模式

单例模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点。
在这里插入图片描述

/**
 * 线程安全的写法,单例模式最优写法
 */
public class SingletonThreadSafe {
    private static volatile SingletonThreadSafe instance;

    private SingletonThreadSafe() {

    }

    public static SingletonThreadSafe getInstance() {
        if (instance == null) {
            synchronized (SingletonThreadSafe.class) {
                if (instance == null) {
                    instance = new SingletonThreadSafe();
                }
            }
        }

        return instance;
    }
}
/**
 * 单例模式客户端
 */
public class SingletonClient {
    public static void main(String[] args) {

        SingletonThreadSafe instance1 = SingletonThreadSafe.getInstance();
        SingletonThreadSafe instance2 = SingletonThreadSafe.getInstance();

        if (instance1.equals(instance2)) {
            System.out.println("同样的实例");
        } else {
            System.out.println("不同的实例");
        }

    }
}

二、结构型模式

1、适配器模式

适配器模式,将一个类的接口转换成客户希望的另外一个接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
在这里插入图片描述

/**
 * 需要适配的类
 */
public class Adaptee {

    public void specificRequest() {
        System.out.println("特殊的请求!");
    }

}
/**
 * 客户所期待的接口
 */
public abstract class Target {
    public void request() {
        System.out.println("普通请求!");
    }
}
/**
 * 适配器类,通过在内部包装一个Adaptee对象,把原接口转换成目标接口
 */
public class Adapter extends Target {
    private Adaptee adaptee = new Adaptee();

    @Override
    public void request() {
        adaptee.specificRequest();
    }
}
/**
 * 适配器客户端
 */
public class AdapterClient {

    public static void main(String[] args) {
        Target target = new Adapter();
        target.request();
    }
}

2、桥接模式

桥接模式,将抽象部分与它的实现部分分离,使它们都可以独立地变化。
在这里插入图片描述

public abstract class Abstraction {
    /**
     * 桥接模式的关键,使得Abstraction聚合Implementor
     */
    protected Implementor implementor;
    private String name;

    public Abstraction(String name) {
        this.setName(name);
    }

    public void setImplementor(Implementor implementor) {
        this.implementor = implementor;
    }

    public void operation() {
        System.out.print("Abstraction-" + this.getName() + ": ");
        implementor.operation();
    }

    public String getName() {
        return name;
    }

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

class AbstractionA extends Abstraction {

    public AbstractionA(String name) {
        super(name);
    }

    @Override
    public void operation() {
        super.operation();
    }

}

class AbstractionB extends Abstraction {

    public AbstractionB(String name) {
        super(name);
    }

    @Override
    public void operation() {
        super.operation();
    }

}
public abstract class Implementor {

    public abstract void operation();

}

class ConcreteImplemtorA extends Implementor {

    @Override
    public void operation() {
        System.out.println("ConcreteImplemtorA的方法执行");
    }

}

class ConcreteImplemtorB extends Implementor {

    @Override
    public void operation() {
        System.out.println("ConcreteImplemtorB的方法执行");
    }

}
/**
 * 客户端
 */
public class BridgeClient {
    public static void main(String[] args) {

        Abstraction a = new AbstractionA("A");
        a.setImplementor(new ConcreteImplemtorA());
        a.operation();
        a.setImplementor(new ConcreteImplemtorB());
        a.operation();

        Abstraction b = new AbstractionB("B");
        b.setImplementor(new ConcreteImplemtorA());
        b.operation();
        b.setImplementor(new ConcreteImplemtorB());
        b.operation();

        // 这样通过使用“组合/聚合复用原则”
        // 如果继续有AbstractionC ... 或者ConcreteImplemtorC ...
        // 只需要扩展类即可,不需要修改现有类,符合“开放-封闭”原则
    }

}

3、组合模式

组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
在这里插入图片描述

/**
 * Component为组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为。
 */
public abstract class Component {
    protected String name;

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

    public abstract void add(Component component);

    public abstract void remove(Component component);

    public abstract void display(int depth);

    protected String repeatableLayer(int depth) {
        StringBuilder append = new StringBuilder();
        for (int i = 0; i < depth; i++) {
            append.append("-");
        }
        return append.toString();
    }

}
/**
 * Leaf在组合中表示叶节点对象,叶节点没有子节点
 */
public 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 component) {
        System.out.println("cannot remove from a leaf");
    }

    @Override
    public void display(int depth) {
        // 通过“-”的数目显示级别
        System.out.println(repeatableLayer(depth) + this.name);
    }

}
/**
 * 定义有枝节点行为,用来存储子部件
 */
public class Composite extends Component {
    private List<Component> children = new ArrayList<>();

    public Composite(String name) {
        super(name);
    }

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

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

    @Override
    public void display(int depth) {
        // 显示其枝节点名称,并对其下级进行遍历
        System.out.println(repeatableLayer(depth) + this.name);

        for (Component component : children) {
            component.display(depth + 2);
        }
    }

}
/**
 * 客户端。通过Component接口操作组合部件的对象
 */
public class CompositeClient {

    public static void main(String[] args) {
        // 生成树根,根上长出两叶Leaf A和Leaf B
        Composite root = new Composite("root");
        root.add(new Leaf("Leaf A"));
        root.add(new Leaf("Leaf B"));

        // 根上长出分支Composite X,分支上也有两叶Leaf X-A和Leaf X-B
        Composite compositeX = new Composite("Composite X");
        compositeX.add(new Leaf("Leaf X-A"));
        compositeX.add(new Leaf("Leaf X-B"));
        root.add(compositeX);

        // 在Composite X上再长出分支Composite X-Y,分支上也有两叶Leaf X-Y-A和Leaf X-Y-B
        Composite compositeXY = new Composite("Composite X-Y");
        compositeXY.add(new Leaf("Leaf X-Y-A"));
        compositeXY.add(new Leaf("Leaf X-Y-B"));
        compositeX.add(compositeXY);

        // 显示大树的样子
        root.display(1);
    }
}

4、装饰模式

装饰模式,动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
在这里插入图片描述

/**
 * Component是定义一个对象接口,可以给这些对象动态地添加职责
 */
public abstract class Component {
    public abstract void operation();
}
/**
 * ConcreteComponent是定义一个具体的对象,也可以给这个对象添加一些职责
 */
public class ConcreteComponent extends Component {

    @Override
    public void operation() {
        System.out.println("具体对象的操作");
    }

}
package designpattern.structural.decorator;

/**
 * Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,
 * 是无需知道Decorator的存在的
 */
public abstract class Decorator extends Component {
    protected Component component;

    public Component getComponent() {
        return component;
    }

    public void setComponent(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        if (component != null) {
            component.operation();
        }
    }

}

class ConcreteDecoratorA extends Decorator {
    private String addedState;

    @Override
    public void operation() {
        // 首先运行原Component的operation(),再执行本类的功能,如addedState,相当于对原Component进行了装饰
        super.operation();
        addedState = "A中的new state ";
        System.out.println(addedState + "具体装饰对象A的操作");
    }
}

class ConcreteDecoratorB extends Decorator {
    @Override
    public void operation() {
        super.operation();
        addedBehavior();
        System.out.println("具体装饰对象B的操作");
    }

    public void addedBehavior() {
        System.out.print("B中的新增行为 ");
    }
}

class ConcreteDecoratorC extends Decorator {
    @Override
    public void operation() {
        super.operation();
        System.out.println("C没有特殊行为 " + "具体装饰对象C的操作");
    }

}

5、外观模式

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

/**
 * “系统”接口,只是标记接口,暂无任何意义
 */
public interface SystemInterface {

}

class SubSystemOne implements SystemInterface {
    public void methodOne() {
        System.out.println("子系统方法一");
    }
}

class SubSystemTwo implements SystemInterface {
    public void methodTwo() {
        System.out.println("子系统方法二");
    }
}

class SubSystemThree implements SystemInterface {
    public void methodThree() {
        System.out.println("子系统方法三");
    }
}

class SubSystemFour implements SystemInterface {
    public void methodFour() {
        System.out.println("子系统方法四");
    }
}
/**
 * 外观类,它需要了解所有的子系统的方法或属性,进行组合,以备外界调用
 */
public class Facade {
    SubSystemOne subSystemOne;
    SubSystemTwo subSystemTwo;
    SubSystemThree subSystemThree;
    SubSystemFour subSystemFour;

    public Facade() {
        subSystemOne = new SubSystemOne();
        subSystemTwo = new SubSystemTwo();
        subSystemThree = new SubSystemThree();
        subSystemFour = new SubSystemFour();
    }

    public void methodA() {
        System.out.println("方法组A:");

        subSystemOne.methodOne();
        subSystemTwo.methodTwo();
        subSystemFour.methodFour();
    }

    public void methodB() {
        System.out.println("方法组B:");

        subSystemThree.methodThree();
        subSystemFour.methodFour();
    }
}
/**
 * 外观类客户端
 */
public class FacadeClient {
    public static void main(String[] args) {
        // 由于Facade的作用,客户端可以根本不知道四个子系统的存在
        // 启发:维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,此时可以
        // 为新系统开发一个外观Facade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单
        // 的接口,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作
        Facade facade = new Facade();

        facade.methodA();
        facade.methodB();
    }
}

6、享元模式

享元模式,运用共享技术有效地支持大量细粒度的对象。
在这里插入图片描述

/**
 * 享元工厂
 */
public class FlyWeightFactory {
    private HashMap<String, FlyWeight> flyWeights = new HashMap<>();

    public FlyWeight getFlyWeight(String key) {
        if (!flyWeights.containsKey(key)) {
            flyWeights.put(key, new ConcreteFlyWeight());
        }

        return flyWeights.get(key);
    }

}
/**
 * 所有具体享元类的超类,接受并作用于外部状态
 */
public abstract class FlyWeight {

    public abstract void operation(int extrinsicState);

}

class ConcreteFlyWeight extends FlyWeight {

    @Override
    public void operation(int extrinsicState) {
        System.out.println("具体FlyWeight:" + extrinsicState);
    }

}

class UnsharedConcreteFlyWeight extends FlyWeight {

    @Override
    public void operation(int extrinsicState) {
        System.out.println("不共享的具体FlyWeight:" + extrinsicState);
    }

}
/**
 * 客户端
 */
public class FlyWeightClient {

    public static void main(String[] args) {
        int extrinsicState = 22;

        FlyWeightFactory factory = new FlyWeightFactory();

        FlyWeight fx = factory.getFlyWeight("X");
        fx.operation(--extrinsicState);

        FlyWeight fy = factory.getFlyWeight("Y");
        fy.operation(--extrinsicState);

        FlyWeight fz = factory.getFlyWeight("Z");
        fz.operation(--extrinsicState);

        FlyWeight uf = new UnsharedConcreteFlyWeight();
        uf.operation(--extrinsicState);
    }

}

7、代理模式

代理模式,为其他对象提供一种代理以控制对这个对象的访问。
在这里插入图片描述

/**
 * 定义真实实体类与代理类共用的接口
 */
public interface Subject {
    void request();
}
/**
 * 代理类
 */
public class Proxy implements Subject {

    // 保存一个引用,使得代理可以访问真实实体
    Subject subject;

    public Proxy() {
		subject = new RealSubject();
    }

    @Override
    public void request() {
		subject.request();
    }

}
/**
 * 真实实体类
 */
public class RealSubject implements Subject {

    @Override
    public void request() {
		System.out.println("真实对象的请求");
    }

}

三、行为型模式

1、解释器模式

解释器模式,给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
在这里插入图片描述

/**
 * 包含解释器之外的一些全局信息
 */
public class Context {

    private String input;
    private String output;

    public String getInput() {
        return input;
    }

    public void setInput(String input) {
        this.input = input;
    }

    public String getOutput() {
        return output;
    }

    public void setOutput(String output) {
        this.output = output;
    }

}
/**
 * 声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享
 */
public abstract class AbstractExpression {

    public abstract void interpret(Context context);

}
/**
 * 实现与文法中的终结符相关联的解释操作,文法中每一个终结符都有一个具体终结表达式与之相对应
 */
public class TerminalExpression extends AbstractExpression {

    @Override
    public void interpret(Context context) {
        System.out.println("终端解释器");
    }

}
/**
 * 非终结符表达式,为文法中的非终结符实现解释操作。对文法中每一条规则R1、R2 ... ... Rn都需要一个具体的非终结符表达式类。
 */
public class NonTerminalExpression extends AbstractExpression {

    @Override
    public void interpret(Context context) {
        System.out.println("非终端解释器");
    }

}
/**
 * 构建表示该文法定义的语言中一个特定的句子的抽象语法树,调用解释操作
 */
public class InterpreterClient {

    public static void main(String[] args) {
        Context context = new Context();
        List<AbstractExpression> list = new ArrayList<>();

        list.add(new TerminalExpression());
        list.add(new NonTerminalExpression());
        list.add(new TerminalExpression());
        list.add(new TerminalExpression());

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

}

2、模板方法模式

模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
在这里插入图片描述

/**
 * 模板方法抽象类:不变的部分给出具体实现,变化的部分封装为抽象方法延迟到子类实现
 */
public abstract class AbstractTemplate {
    public abstract void primitiveOperation1();
    public abstract void primitiveOperation2();

    public void templateMethod() {
        primitiveOperation1();
        primitiveOperation2();
        System.out.println("模板方法结束\n");
    }
}
/**
 * 具体类A
 */
public class ConcreteClassA extends AbstractTemplate {

    @Override
    public void primitiveOperation1() {
        System.out.println("具体类A的方法1实现");
    }

    @Override
    public void primitiveOperation2() {
        System.out.println("具体类A的方法2实现");
    }
}
/**
 * 具体类B
 */
public class ConcreteClassB extends AbstractTemplate {

    @Override
    public void primitiveOperation1() {
        System.out.println("具体类B的方法1实现");
    }

    @Override
    public void primitiveOperation2() {
        System.out.println("具体类B的方法2实现");
    }
}
/**
 * 模板方法客户端
 */
public class TemplateClient {
    public static void main(String[] args) {
        AbstractTemplate abstractTemplate;

        abstractTemplate = new ConcreteClassA();
        abstractTemplate.templateMethod();

        abstractTemplate = new ConcreteClassB();
        abstractTemplate.templateMethod();
    }
}

3、策略模式

场景:商场促销。简单工厂模式虽然也能解决这个问题,但这个模式只是解决对象的创建问题,而且由于工厂本身包括了所有的收费方式,商场是可能经常性地更改打折额度和返利额度,每次维护或扩展收费方式都要改动这个工厂。所以它不是最好的办法。

面对算法的时常变动,应该有更好的办法。

策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
在这里插入图片描述

/**
 * 上下文
 */
public class Context {

    Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    /**
     * 上下文接口
     */
    public void contextInterface() {
        strategy.algorithmInterface();
    }
}
/**
 * 策略接口
 */
public interface Strategy {
    void algorithmInterface();
}

class ConcreteStrategyA implements Strategy {

    @Override
    public void algorithmInterface() {
        System.out.println("策略A的具体算法实现");
    }
}

class ConcreteStrategyB implements Strategy {

    @Override
    public void algorithmInterface() {
        System.out.println("策略B的具体算法实现");
    }
}

class ConcreteStrategyC implements Strategy {

    @Override
    public void algorithmInterface() {
        System.out.println("策略C的具体算法实现");
    }
}
package designpattern.behavioral.strategy;

/**
 * 客户端使用策略
 */
public class StrategyClient {

    public static void main(String[] args) {
        Context context;

        context = new Context(new ConcreteStrategyA());
        context.contextInterface();

        context = new Context(new ConcreteStrategyB());
        context.contextInterface();

        context = new Context(new ConcreteStrategyC());
        context.contextInterface();
    }
}

4、观察者模式

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

/**
 * 主题或抽象通知者
 */
public abstract class Subject {
    private List<Observer> observers = new ArrayList<>();

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

    public void detach(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObserver() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}
/**
 * 具体主题或通知者
 */
public class ConcreteSubject extends Subject {
    private String subjectState;

    public String getSubjectState() {
        return subjectState;
    }

    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
    }
}
/**
 * 抽象观察者
 */
public abstract class Observer {
    public abstract void update();
}
/**
 * 具体观察者
 */
public class ConcreteObserver extends Observer {

    private String name;
    private String observerState;
    private ConcreteSubject concreteSubject;

    public ConcreteObserver(ConcreteSubject concreteSubject, String name) {
        this.setName(name);
        this.setConcreteSubject(concreteSubject);
    }

    @Override
    public void update() {
        this.setObserverState(concreteSubject.getSubjectState());
        System.out.println("观察者" + this.getName() + "的新状态是" + this.getObserverState());
    }

    public String getName() {
        return name;
    }

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

    public String getObserverState() {
        return observerState;
    }

    public void setObserverState(String observerState) {
        this.observerState = observerState;
    }

    public ConcreteSubject getConcreteSubject() {
        return concreteSubject;
    }

    public void setConcreteSubject(ConcreteSubject concreteSubject) {
        this.concreteSubject = concreteSubject;
    }
}
/**
 * 观察者模式客户端代码
 */
public class ObserverClient {
    public static void main(String[] args) {
        ConcreteSubject concreteSubject = new ConcreteSubject();

        concreteSubject.attach(new ConcreteObserver(concreteSubject, "X"));
        concreteSubject.attach(new ConcreteObserver(concreteSubject, "Y"));
        concreteSubject.attach(new ConcreteObserver(concreteSubject, "Z"));

        concreteSubject.setSubjectState("ABC");
        concreteSubject.notifyObserver();
    }
}

5、状态模式

状态模式,当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
在这里插入图片描述

/**
 * Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态
 */
public class Context {
    private State state;

    public Context(State state) {
        this.state = state;
    }

    public State getState() {
        return state;
    }

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

    public void request() {
        this.state.handle(this);
    }
}
/**
 * 抽象状态类
 */
public abstract class State {
    public abstract void handle(Context context);
}

class ConcreteStateA extends State {

    @Override
    public void handle(Context context) {
        System.out.println("现在是在状态A");
        context.setState(new ConcreteStateB());
    }
}

class ConcreteStateB extends State {

    @Override
    public void handle(Context context) {
        System.out.println("现在是在状态B");
        context.setState(new ConcreteStateC());
    }
}

class ConcreteStateC extends State {

    @Override
    public void handle(Context context) {
        System.out.println("现在是在状态C");
        context.setState(new ConcreteStateA());
    }
}
/**
 * 客户端:不断请求,不断更改状态
 */
public class StateClient {
    public static void main(String[] args) {

        Context context = new Context(new ConcreteStateA());

        context.request();
        context.request();
        context.request();
        context.request();
        context.request();
    }
}

6、备忘录模式

备忘录:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
在这里插入图片描述

/**
 * 发起人(Originator) 类
 */
public class Originator {

    private String state;

    public Memento createMemento() {
        return new Memento(this.state);
    }

    public void recoverMemento(Memento memento) {
        this.setState(memento.getState());
    }

    public void show() {
        System.out.println("state = " + this.state);
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}
/**
 * 备忘录(Memento)类
 */
public class Memento {
    private String state;

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

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}
/**
 * 管理者(CareTaker)类:管理备忘录
 */
public class CareTaker {

    private Memento memento;

    public Memento getMemento() {
        return memento;
    }

    public void setMemento(Memento memento) {
        this.memento = memento;
    }
}
/**
 * 客户端
 */
public class MementoClient {

    public static void main(String[] args) {
        // 设置初始状态
        Originator originator = new Originator();
        originator.setState("On");
        originator.show();

        // 管理者通过备忘录保存状态,由于有了很好地封装,可以隐藏Originator的实现细节
        CareTaker careTaker = new CareTaker();
        careTaker.setMemento(originator.createMemento());

        // 改变状态
        originator.setState("Off");
        originator.show();

        // 通过管理者从备忘录中恢复状态
        originator.recoverMemento(careTaker.getMemento());
        originator.show();
    }
}

7、迭代器模式

迭代器模式,提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
在这里插入图片描述

/**
 * 聚集接口
 *
 * @param <T>
 */
public interface Aggregate<T> {

    Iterator<T> createIterator();
}
/**
 * 具体聚集类
 *
 * @param <T>
 */
public class ConcreteAggregate<T> implements Aggregate<T> {

    private List<T> items = new ArrayList<>();

    @Override
    public Iterator<T> createIterator() {
        return new ConcreteIterator<T>(this);
    }

    public int count() {
        return items.size();
    }

    public T getItems(int index) {
        return items.get(index);
    }

    public void setItems(T item) {
        items.add(item);
    }
}
/**
 * 迭代器接口
 *
 * @param <T>
 */
public interface Iterator<T> {

    T first();

    T next();

    boolean isDone();

    T currentItem();
}
/**
 * 具体迭代器类,给出一种具体迭代的实现方式。思考:迭代器表示的是一种迭代的行为,而聚集则是真正要被迭代的数据集合。
 * 之所以要将迭代器和聚集分开,就是为了将行为与数据分开。 可类比Java中Iterator与Iterable的关系进行理解
 *
 * @param <T>
 */
public class ConcreteIterator<T> implements Iterator<T> {

    private ConcreteAggregate<T> concreteAggregate;
    private int current = 0;

    public ConcreteIterator(ConcreteAggregate<T> concreteAggregate) {
        this.setConcreteAggregate(concreteAggregate);
    }

    @Override
    public T first() {
        return concreteAggregate.getItems(0);
    }

    @Override
    public T next() {
        current++;

        if (current < concreteAggregate.count()) {
            return concreteAggregate.getItems(current);
        }

        return null;
    }

    @Override
    public boolean isDone() {
        return current >= concreteAggregate.count() ? true : false;
    }

    @Override
    public T currentItem() {
        return concreteAggregate.getItems(current);
    }

    public ConcreteAggregate<T> getConcreteAggregate() {
        return concreteAggregate;
    }

    public void setConcreteAggregate(ConcreteAggregate<T> concreteAggregate) {
        this.concreteAggregate = concreteAggregate;
    }

    public int getCurrent() {
        return current;
    }

    public void setCurrent(int current) {
        this.current = current;
    }
}
/**
 * 迭代器客户端
 */
public class IteratorClient {
    public static void main(String[] args) {
        ConcreteAggregate<String> bus = new ConcreteAggregate<String>();

        bus.setItems("大鸟");
        bus.setItems("小菜");
        bus.setItems("行李");
        bus.setItems("老外");
        bus.setItems("公交内部员工");
        bus.setItems("小偷");

        Iterator<String> iterator = new ConcreteIterator<>(bus);

        while (!iterator.isDone()) {
            System.out.println(iterator.currentItem() + "请买票!");
            iterator.next();
        }
    }
}

8、命令模式

命令模式,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以 及支持可撤销的操作。
在这里插入图片描述

/**
 * 用来声明执行操作的接口
 */
public abstract class Command {

    protected List<Reciever> recievers;

    public Command(List<Reciever> recievers) {
        this.recievers = recievers;
    }

    public void addRecievers(Reciever reciever) {
        this.recievers.add(reciever);
    }

    public abstract void execute();

}

// 将一个接收者对象绑定于一个动作,调用接收者相应的操作,以实现execute
class ConcreteCommand extends Command {

    public ConcreteCommand(List<Reciever> recievers) {
        super(recievers);
    }

    @Override
    public void execute() {
        for (Reciever reciever : recievers) {
            reciever.action();
        }
    }
}
/**
 * 知道如何实施与执行一个与请求相关的操作,任何类都可能作为一个接收者。真正执行请求的地方!
 */
interface Reciever {
    void action();
}

class RecieverA implements Reciever {

    @Override
    public void action() {
        System.out.println("RecieverA执行请求!");
    }

}

class RecieverB implements Reciever {

    @Override
    public void action() {
        System.out.println("RecieverB执行请求!");
    }
}

class RecieverC implements Reciever {

    @Override
    public void action() {
        System.out.println("RecieverC执行请求!");
    }
}
/**
 * 要求该命令执行这个请求
 */
public class Invoker {

    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void executeCommand() {
        command.execute();
    }
}
/**
 * 创建一个具体命令对象并设定它的接收者
 */
public class CommandClient {

    public static void main(String[] args) {
        List<Reciever> recievers = new ArrayList<>();

        recievers.add(new RecieverA());
        recievers.add(new RecieverB());
        recievers.add(new RecieverC());

        Command command = new ConcreteCommand(recievers);
        Invoker invoker = new Invoker();

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

9、责任链模式

责任链模式,使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
在这里插入图片描述

/**
 * 处理请求的接口
 */
public abstract class Handler {

    protected Handler successor;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    public abstract void handleRequest(int request);
}

/**
 * 具体处理者类,处理它所负责的请求,可访问它的后继者,如果可处理该请求,则处理,否则转给它的后继者处理
 */
class ConcreteHandlerA extends Handler {

    @Override
    public void handleRequest(int request) {
        if (request >= 0 && request <= 10) {
            System.out.println(this.getClass().getName() + "处理了请求" + request);
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }

}

class ConcreteHandlerB extends Handler {

    @Override
    public void handleRequest(int request) {
        if (request > 10 && request <= 20) {
            System.out.println(this.getClass().getName() + "处理了请求" + request);
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }

}

class ConcreteHandlerC extends Handler {

    @Override
    public void handleRequest(int request) {
        if (request > 20 && request <= 30) {
            System.out.println(this.getClass().getName() + "处理了请求" + request);
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}
/**
 * 向链上的具体处理者对象提交请求
 */
public class Client {
    public static void main(String[] args) {

        Handler handlerA = new ConcreteHandlerA();
        Handler handlerB = new ConcreteHandlerB();
        Handler handlerC = new ConcreteHandlerC();

        handlerA.setSuccessor(handlerB);
        handlerB.setSuccessor(handlerC);

        int[] requests = {2, 14, 5, 6, 8, 23, 12, 21};

        for (int i : requests) {
            handlerA.handleRequest(i);
        }
    }
}

10、中介者模式

中介者模式,用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
在这里插入图片描述

/**
 * 抽象同事类
 */
public abstract class Colleague {

    protected Mediator mediator;

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

    public abstract void sendMsg(String message);

    public abstract void notifyMsg(String message);

}

class ConcreteColleague1 extends Colleague {

    public ConcreteColleague1(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void sendMsg(String message) {
        mediator.send(message, this);
    }

    @Override
    public void notifyMsg(String message) {
        System.out.println("同事1得到消息:" + message);
    }

}

class ConcreteColleague2 extends Colleague {

    public ConcreteColleague2(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void sendMsg(String message) {
        mediator.send(message, this);
    }

    @Override
    public void notifyMsg(String message) {
        System.out.println("同事2得到消息:" + message);
    }
}
/**
 * 抽象中介者类
 */
public abstract class Mediator {

    public abstract void send(String message, Colleague colleague);

}

class ConcreteMediator extends Mediator {
    // 需要了解所有的具体同事对象
    private ConcreteColleague1 c1;
    private ConcreteColleague2 c2;

    public ConcreteColleague1 getC1() {
        return c1;
    }

    public void setC1(ConcreteColleague1 c1) {
        this.c1 = c1;
    }

    public ConcreteColleague2 getC2() {
        return c2;
    }

    public void setC2(ConcreteColleague2 c2) {
        this.c2 = c2;
    }

    @Override
    public void send(String message, Colleague colleague) {
        // 重写发送信息的方法,根据对象做出选择判断,通知对象
        if (colleague == c1) {
            c2.notifyMsg(message);
        } else {
            c1.notifyMsg(message);
        }
    }
}
/**
 * 客户端
 */
public class MediatorClient {

    public static void main(String[] args) {
        ConcreteMediator concreteMediator = new ConcreteMediator();

        // 让两个具体同事类认识中介者对象
        ConcreteColleague1 concreteColleague1 = new ConcreteColleague1(concreteMediator);
        ConcreteColleague2 concreteColleague2 = new ConcreteColleague2(concreteMediator);

        // 让中介者认识各个具体同事类对象
        concreteMediator.setC1(concreteColleague1);
        concreteMediator.setC2(concreteColleague2);

        // 具体同事类对象的消息发送都是通过中介者对象转发
        concreteColleague1.sendMsg("吃过饭了没有?");
        concreteColleague2.sendMsg("没有呢,你打算请客?");
    }
}

11、访问者模式

访问者模式,表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
在这里插入图片描述

/**
 * 为该对象结构中ConcreteElement的每一个类声明一个Visit操作
 */
public abstract class Visitor {

    public abstract void visitConcreteElementA(ConcreteElementA concreteElementA);

    public abstract void visitConcreteElementB(ConcreteElementB concreteElementB);

}

class ConcreteVisitor1 extends Visitor {

    @Override
    public void visitConcreteElementA(ConcreteElementA concreteElementA) {
		System.out.println(concreteElementA.getClass().getSimpleName() + "被"
			+ this.getClass().getSimpleName() + "访问");
    }

    @Override
    public void visitConcreteElementB(ConcreteElementB concreteElementB) {
		System.out.println(concreteElementB.getClass().getSimpleName() + "被"
			+ this.getClass().getSimpleName() + "访问");
    }
}

class ConcreteVisitor2 extends Visitor {

    @Override
    public void visitConcreteElementA(ConcreteElementA concreteElementA) {
		System.out.println(concreteElementA.getClass().getSimpleName() + "被"
			+ this.getClass().getSimpleName() + "访问");
    }

    @Override
    public void visitConcreteElementB(ConcreteElementB concreteElementB) {
		System.out.println(concreteElementB.getClass().getSimpleName() + "被"
			+ this.getClass().getSimpleName() + "访问");
    }
}
/**
 * 定义一个accept操作,它以一个访问者为参数
 */
public abstract class Element {
    public abstract void accept(Visitor visitor);
}

class ConcreteElementA extends Element {

    @Override
    public void accept(Visitor visitor) {
		visitor.visitConcreteElementA(this);
    }
}

class ConcreteElementB extends Element {

    @Override
    public void accept(Visitor visitor) {
		visitor.visitConcreteElementB(this);
    }
}
/**
 * 提供一个高层的接口以允许访问者访问它的元素
 */
public class ObjectStructure {

    private List<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 element : elements) {
            element.accept(visitor);
        }
    }
}
/**
 * 客户端
 */
public class VisitorClient {

    public static void main(String[] args) {
        ObjectStructure o = new ObjectStructure();

        o.attach(new ConcreteElementA());
        o.attach(new ConcreteElementB());

        ConcreteVisitor1 visitor1 = new ConcreteVisitor1();
        ConcreteVisitor2 visitor2 = new ConcreteVisitor2();

        o.accept(visitor1);
        o.accept(visitor2);
    }
}

提示:更多内容可以访问Clang’s Blog:https://www.clang.asia

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2245530.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode:1008. 前序遍历构造二叉搜索树

目录 题目描述: 代码: 第一种: 第二种: 第三种:分治法 题目描述: 给定一个整数数组&#xff0c;它表示BST(即 二叉搜索树 )的 先序遍历 &#xff0c;构造树并返回其根。 保证 对于给定的测试用例&#xff0c;总是有可能找到具有给定需求的二叉搜索树。 二叉搜索树 是一棵…

STM32F103 GPIO和串口实战

本节我们将会对STM32F103的硬件资源GPIO和串口进行介绍。 一、GPIO 1.1 电路原理图 LED电路原理图如下图所示&#xff1a; 其中&#xff1a; LED1连接到PA8引脚&#xff0c;低电平点亮&#xff1b;LED2连接到PD2引脚&#xff0c;低电平点亮&#xff1b; 1.2 GPIO引脚介绍 STM32…

Statsmodels之OLS回归

目录 Statsmodels基本介绍OLS 回归实战实战1&#xff1a;实战2&#xff1a; Statsmodels基本介绍 Statsmodels 是 Python 中一个强大的统计分析包&#xff0c;包含了回归分析、时间序列分析、假设检验等等的功能。Statsmodels 在计量的简便性上是远远不及 Stata 等软件的&…

在 macOS 和 Linux 中,波浪号 `~`的区别

文章目录 1、在 macOS 和 Linux 中&#xff0c;波浪号 ~macOS示例 Linux示例 区别总结其他注意事项示例macOSLinux 结论 2、root 用户的主目录通常是 /root解释示例切换用户使用 su 命令使用 sudo 命令 验证当前用户总结 1、在 macOS 和 Linux 中&#xff0c;波浪号 ~ 在 macO…

人工智能之机器学习5-回归算法2【培训机构学习笔记】

培训班ppt内容&#xff1a; 个人精进总结&#xff1a; 可解释方差 定义 可解释方差的回归评分函数是一种用于评估回归模型性能的指标&#xff0c;以下从其定义、计算公式、取值范围及意义、应用场景等方面进行详细介绍&#xff1a; 可解释方差&#xff08;Explained Varian…

vue2中引入cesium全步骤

1.npm 下载cesium建议指定版本下载&#xff0c;最新版本有兼容性问题 npm install cesium1.95.0 2.在node_models中找到cesium将此文件下的Cesium文件复制出来放在项目的静态资源public中或者static中&#xff0c;获取去github上去下载zip包放在本地也可以 3.在index.html中引…

数据结构(顺序栈——c语言实现)

栈的基本概念&#xff1a; 栈是限制在一端进行插入操作和删除操作的线性表&#xff08;俗称堆栈&#xff09;&#xff0c;允许进行操作的一端称为“栈顶”&#xff0c;另一固定端称为“栈底”&#xff0c;当栈中没有元素时称为“空栈” 特点&#xff1a;先进后出&#xff08;FI…

基于Windows系统用C++做一个点名工具

目录 一、前言 二、主要技术点 三、准备工作 四、主界面 1.绘制背景图 2、实现读取花名册功能 3.实现遍历花名册功能 4.实现储存功能 4.1创建数据库 4.2存储数据到数据库表 4.3读取数据库表数据 一、前言 人总是喜欢回忆过去&#xff0c;突然回忆起…

前端监控之sourcemap精准定位和还原错误源码

一、概述 在前端开发中&#xff0c;监控和错误追踪是确保应用稳定性和用户体验的重要环节。 随着前端应用的复杂性增加&#xff0c;JavaScript错误监控变得尤为重要。在生产环境中&#xff0c;为了优化加载速度和性能&#xff0c;前端代码通常会被压缩和混淆。这虽然提升了性…

算法编程题-排序

算法编程题-排序 比较型排序算法冒泡排序选择排序插入排序希尔排序堆排序快速排序归并排序 非比较型排序算法计数排序基数排序 本文将对七中经典比较型排序算法进行介绍&#xff0c;并且给出golang语言的实现&#xff0c;还包括基数排序、计数排序等非比较型的算法的介绍和实现…

Jenkins修改LOGO

重启看的LOGO和登录页面左上角的LOGO 进入LOGO存在的目录 [roottest-server01 svgs]# pwd /opt/jenkins_data/war/images/svgs [roottest-server01 svgs]# ll logo.svg -rw-r--r-- 1 jenkins jenkins 29819 Oct 21 10:58 logo.svg #jenkins_data目录是我挂载到了/opt目录&…

【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段

文章目录 一、MyBatis-Plus简介二、快速入门1、环境准备2、将mybatis项目改造成mybatis-plus项目&#xff08;1&#xff09;引入MybatisPlus依赖&#xff0c;代替MyBatis依赖&#xff08;2&#xff09;配置Mapper包扫描路径&#xff08;3&#xff09;定义Mapper接口并继承BaseM…

云讷科技Kerloud无人飞车专利发布

云讷科技Kerloud无人飞车获得了“一种室内外两用的四旋翼无人飞车”的实用新型专利证书&#xff0c;作为科教社区第一款四旋翼飞车&#xff0c;这项技术结合了无人机和无人车的优势&#xff0c;提供了一种能够在多种环境下使用的多功能飞行器。 这项设计的优势如下&#xff…

Applied Intelligence投稿

一、关于手稿格式&#xff1a; 1、该期刊是一个二区的&#xff0c;模板使用Springer nature格式&#xff0c; 期刊投稿要求&#xff0c;详细期刊投稿指南&#xff0c;大部分按Soringernature模板即可&#xff0c;图片表格声明参考文献命名要求需注意。 2、参考文献&#xff…

Spark SQL大数据分析快速上手-完全分布模式安装

【图书介绍】《Spark SQL大数据分析快速上手》-CSDN博客 《Spark SQL大数据分析快速上手》【摘要 书评 试读】- 京东图书 大数据与数据分析_夏天又到了的博客-CSDN博客 Hadoop完全分布式环境搭建步骤-CSDN博客,前置环境安装参看此博文 完全分布模式也叫集群模式。将Spark目…

零基础上手WebGIS+智慧校园实例(1)【html by js】

请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01; 等下再更新一下1. WebGIS矢量图形的绘制&#xff08;超级详细&#xff01;&#xff01;&#xff09;&#xff0c;2. WebGIS计算距离&#xff0c; 以及智慧校园实例 with 3个例子&#xff01;&#xff01;…

[开源] 告别黑苹果!用docker安装MacOS体验苹果系统

没用过苹果电脑的朋友可能会对苹果系统好奇&#xff0c;有人甚至会为了尝鲜MacOS去折腾黑苹果。如果你只是想体验一下MacOS&#xff0c;这里有个更简单更优雅的解决方案&#xff0c;用docker安装MacOS来体验苹果系统。 一、项目简介 项目描述 Docker 容器内的 OSX&#xff08…

IDEA:2023版远程服务器debug

很简单&#xff0c;但是很多文档没有写清楚&#xff0c;wocao 一、首先新建一个远程jvm 二、配置 三、把上面的参数复制出来 -agentlib:jdwptransportdt_socket,servery,suspendn,address5005 四、然后把这串代码放到服务器中&#xff08;这里的0.0.0.0意思是所有IP都能访问&a…

卷积神经网络的padding是什么?如何计算?

文章目录 为什么需要padding&#xff1f;1.Valid Padding&#xff08;有效填充&#xff09;2.Same Padding&#xff08;相同填充&#xff09;2.1.如何计算padding&#xff1f;1. 计算总 padding2. 分配 padding&#xff1a; 2.2.举例子1. 步幅为 1 的 Same Padding2. 步幅不为 …

介绍一下strncmp(c基础)

strncmp是strcmp的进阶版 链接介绍一下strcmp(c基础)-CSDN博客 作用 比较两个字符串的前n位 格式 #include <string.h> strncmp (arr1,arr2,n); 工作原理&#xff1a;strcmp函数按照ACII&#xff08;字符编码顺序&#xff09;比较两个字符串。它从两个字符串的第一…