设计模式05:状态模式、策略模式、访问者模式、中介者模式

发布时间 2023-10-27 21:20:56作者: 201812

1.State状态模式

 

示例代码:

package State13;

/**
 * 状态模式
 * 意图: 允许一个对象在其内部状态改变的时候改变它的行为。对象看起来似乎修改了它的类
 * 适用于:
 *      一个对象的行为决定于它的状态,并且它需要在运行时刻根据状态改变它的行为
 *
 */
public class StatePattern {
    public static void main(String[] args) {
        Context context = new Context();
        //原始库存为3
        System.out.println(context.getState());
        context.Request();//购买饮料请求:成功
        context.Request();//购买饮料请求:成功
        context.Request();//购买饮料请求:成功
        //库存量为0的时候
        System.out.println(context.getState());
        context.Request();//购买饮料请求:失败
        System.out.println(context.getState());
    }
}
//贩卖机
class Context{
    private int count;
    private State state;
    public Context(){
        count=3;
        state = new StateA();
    }

    //请求:购买请求
    public void Request(){
        state.Handle(this);
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }
}
interface State{
    public void Handle(Context context);
}
//状态A: 有货
class StateA implements State{

    @Override
    public void Handle(Context context) {
        //处理请求
        int count = context.getCount();
        if(count>=1){
            System.out.println("购买成功");
            context.setCount(count-1);
            if(context.getCount()==0){
                //变成无货的状态
                context.setState(new StateB());
            }
        }else {
            System.out.println("购买失败");
        }
    }
}
//状态B: 无货
class StateB implements State{

    @Override
    public void Handle(Context context) {
        int count = context.getCount();
        if(count==0){
            System.out.println("购买失败,等待补货");
            context.setCount(5);
            System.out.println("补货成功,请重新购买");
            //转换为有货的状态
            context.setState(new StateA());
        }
    }
}

 

2.Strategy策略模式

 

示例代码:

package Strategy14;

/**
 * 策略模式:
 * 意图:定义一系列的算法,把他们一个个封装起来,并且使他们可以相互替换。此模式使得算法可以独立于使用他们的客户而变化。
 * 适用于:
 *      许多相关的类仅仅是行为有异,“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
 *      需要使用一个算法的不同变体
 */
public class StrategyPattern {
    public static void main(String[] args) {
        Strategy add = new AddStrategy();
        Strategy sub = new SubtractStrategy();
        Strategy multiply = new MultiplyStrategy();
        OperationContext context = new OperationContext(add);
        context.Operation(100,20);
        context = new OperationContext(sub);
        context.Operation(90,8);
        context = new OperationContext(multiply);
        context.Operation(10,10);


    }
}
class OperationContext{
    private Strategy strategy;
    public OperationContext(Strategy strategy){
        this.strategy = strategy;
    }
    public void Operation(int a,int b){
        strategy.TwoNumberOperation(a,b);
    }
}
interface Strategy{
    public void TwoNumberOperation(int a,int b);
}
class AddStrategy implements Strategy{

    @Override
    public void TwoNumberOperation(int a, int b) {
        System.out.println(a+b);
    }
}
class SubtractStrategy implements Strategy{

    @Override
    public void TwoNumberOperation(int a, int b) {
        System.out.println(a-b);
    }
}
class MultiplyStrategy implements Strategy{

    @Override
    public void TwoNumberOperation(int a, int b) {
        System.out.println(a*b);
    }
}

 

3.Visitor访问者模式

 

示例代码:

package Visitor15;

import java.util.ArrayList;
import java.util.List;

/**
 * 访问者模式
 * 意图: 表示一个作用于某对象结构中的各元素的操作。它允许在不改变各元素的类的前提下定义作用于这些元素的新操作。
 * 适用于:
 *      一个对象结构包含很多类对象,他们有不同的接口,用户想对这些对象实施一些依赖其具体类的操作
 *      需要对一个对象结构中的对象进行很多不同并且不相干的操作
 *      定义对象结构的类很少改变但是经常需要在这些结构上定义新的操作
 */
public class VisitorPattern {
    public static void main(String[] args) {
        PersonStructure personStructure = new PersonStructure();
        Visitor1 visitor1 = new Visitor1();
        System.out.println("访问者1进行访问");
        personStructure.Accept(visitor1);
        Visitor2 visitor2 = new Visitor2();
        System.out.println("访问者2进行访问");
        personStructure.Accept(visitor2);
        System.out.println("================第二部分================");
        System.out.println("学生年龄总和: "+visitor1.getStuAgeSum());
        System.out.println("老师年龄总和: "+visitor1.getTeaAgeSum());
        System.out.println("学生最高成绩: "+visitor2.getMaxScore());
        System.out.println("老师最高工龄: "+visitor2.getMaxWorkYear());
    }
}
interface Visitor{
    //方法重载
    public void visitStudent(Student student);//访问方法:访问学生
    public void visitTeacher(Teacher teacher);//访问方法:访问教师
}
class Visitor1 implements Visitor{
    //统计学生和老师的年龄总和
    private int stuAgeSum = 0;
    private int teaAgeSum = 0;
    //访问者1
    @Override
    public void visitStudent(Student student) {
        System.out.println("访问者1,访问学生姓名: "+student.getName()+"学生年龄: "+student.getAge());
        stuAgeSum+= student.getAge();
    }

    @Override
    public void visitTeacher(Teacher teacher) {
        System.out.println("访问者1,访问老师姓名: "+teacher.getName()+"老师年龄: "+teacher.getAge());
        teaAgeSum+=teacher.getAge();
    }

    public int getStuAgeSum() {
        return stuAgeSum;
    }

    public int getTeaAgeSum() {
        return teaAgeSum;
    }
}
class Visitor2 implements Visitor{
    //访问者2:求出学生最高成绩和老师的最高工龄
    private int maxScore = -1;
    private int maxWorkYear = -1;
    @Override
    public void visitStudent(Student student) {
        System.out.println("访问者2,访问学生姓名: "+student.getName()+"学生年龄: "+student.getAge());
        maxScore = Math.max(maxScore,student.getScore());
    }

    @Override
    public void visitTeacher(Teacher teacher) {
        System.out.println("访问者2,访问老师姓名: "+teacher.getName()+"老师工龄: "+teacher.getWorkYear());
        maxWorkYear = Math.max(maxWorkYear,teacher.getWorkYear());
    }

    public int getMaxScore() {
        return maxScore;
    }

    public int getMaxWorkYear() {
        return maxWorkYear;
    }
}

//ObjectStructure
class PersonStructure{
    private List<Person> personList = new ArrayList<Person>();
    public PersonStructure(){
        personList.add(new Student("张三",20,70));
        personList.add(new Student("李四",21,80));
        personList.add(new Student("王五",22,90));
        personList.add(new Teacher("陈老师",26,3));
        personList.add(new Teacher("李老师",27,4));
        personList.add(new Teacher("王老师",28,5));
    }
    public void Accept(Visitor visitor){
        for (Person person:personList ) {
            person.Accept(visitor);
        }
    }
}

//Element
abstract class Person{
    private String name;
    private int age;
    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }
    //接收访问者的访问方法
    public abstract void Accept(Visitor visitor);

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}
//ConcreteElementA
class Student extends Person{
    private int score;
    public Student(String name,int age,int score){
//        this.name = name;
        super(name,age);
        this.score = score;
    }

    @Override
    public void Accept(Visitor visitor) {
        visitor.visitStudent(this);
    }

    public int getScore() {
        return score;
    }
}
//ConcreteElementB
class Teacher extends Person{
    private int workYear;
    public Teacher(String name,int age,int workYear){
//        this.name=name;
        super(name,age);
        this.workYear = workYear;
    }

    @Override
    public void Accept(Visitor visitor) {
        visitor.visitTeacher(this);
    }

    public int getWorkYear() {
        return workYear;
    }
}

 

4.Mediator中介者模式

 

示例代码:

package Mediator16;

/**
 * 中介者模式
 * 意图:用一个中介对象来封装一系列的对象交互。
 *      中介者模式使得个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立的改变他们之间的交互
 * 适用于:一组对象以定义良好但是复杂的方式进行通信,产生的相互依赖关系结构混乱且难以理解
 *      一个对象引用气压很多对象并且直接与这些对象通信,导致难以复用该对象
 *      想定制一个发布在多个类中的行为但是又不想生成太多的子类
 */
public class MediatorPattern {
    public static void main(String[] args) {
        ConcreteMediator mediator = new ConcreteMediator();
        //同事12设置中介者
        Colleague1 colleague1 = new Colleague1(mediator);
        Colleague2 colleague2 = new Colleague2(mediator);
        //中介者设置同事12
        mediator.setColleague1(colleague1);
        mediator.setColleague2(colleague2);
        colleague1.sendMessage("你好,我叫李华!");
        colleague2.sendMessage("你好李华,我是Tom!");
    }
}
abstract class Colleague{
    protected Mediator mediator;
}
class Colleague1 extends Colleague{
    public Colleague1(Mediator mediator){
        this.mediator = mediator;
    }
    //发消息
    public void sendMessage(String message){
        mediator.sendMessage(message,this);
    }
    //收消息
    public void Notify(String message){
        System.out.println("同事1收到消息:"+message);
    }
}
class Colleague2 extends Colleague{
    public Colleague2(Mediator mediator){
        this.mediator=mediator;
    }
    //发消息
    public void sendMessage(String message){
        mediator.sendMessage(message,this);
    }
    //收消息
    public void Notify(String message){
        System.out.println("同事2收到消息:"+message);
    }
}
abstract class Mediator{
    public abstract void sendMessage(String message, Colleague colleague);
}
class ConcreteMediator extends Mediator{
    private Colleague1 colleague1;
    private Colleague2 colleague2;

    public void setColleague1(Colleague1 colleague1){
        this.colleague1 = colleague1;
    }
    public void setColleague2(Colleague2 colleague2){
        this.colleague2 = colleague2;
    }

    @Override
    public void sendMessage(String message,Colleague colleague) {
        if(colleague == colleague1){
            //让同事2接收消息
            colleague2.Notify(message);
        }else {
            colleague1.Notify(message);
        }
    }
}