在软件开发过程中,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,程序员要尽量根据七条原则来开发程序,从而提高软件开发效率、节约软件开发成本和维护成本。

  • 单一职责原则:一个类只负责一项职责,一个方法负责一件事。
  • 里氏替换原则:子类可以扩展父类的功能,但不能改变父类原有的功能,子类可以实现父类的抽象方法,但不能覆盖父类的抽象方法,子类可以增加自己特有的方法。
  • 依赖倒置原则:高层次的模块不应该依赖低层次的模块,二者应该依赖于抽象,抽象应该不依赖于具体实现,具体实现应该依赖于抽象。
  • 接口隔离原则:一个类对另一个类的依赖应该建立在最小的接口上。(类不应该依赖不他需要的接口)。
  • 迪米特法则:一个对象应该对其它对象有尽可能的了解,简称类间解耦。
  • 开闭原则:尽可能通过扩展软件实体来解决需求变化,而不是通过修改已有的代码来完成变化。
  • 合成复用原则:软件复用时,尽量优先使用组合或聚合等关联关系来实现,其次再考虑使用继承关系来实现。

根据目的来分可以将设计模式分为创建型模式,结构性模式,和行为性模式三种。

  1. 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
  2. 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  3. 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

创建型模式:

1 单例模式

单例模式指一个类只有一个实例,且该类能自行创建这个实例。
单例模式通常有两种实现方式:

1.1 懒汉式

顾名思义就是实例在第一次使用的时候才去创建,这种方式存在线程不安全问题(多个实例同时创建)。

class LazySingleton{private static LazySingleton lazySingleton;//避免在外部被实例化private LazySingleton(){}public static LazySingleton getInstance(){lazySingleton =Optional.ofNullable(lazySingleton).orElse(new LazySingleton());return lazySingleton;}
}

1.2 饿汉式

在类加载的时候就创建好了实例,线程安全,但有可能浪费内存。

class HungrySingleton{private static HungrySingleton hungrySingleton=new HungrySingleton();private HungrySingleton(){}public static HungrySingleton getInstance(){return hungrySingleton;}
}

1.3 双重检验锁

双检索是懒汉式线程安全问题的一种优化,先判定对象是否被初始化,再决定要不要加锁。

class DoubleCheck{private static DoubleCheck doubleCheck;private DoubleCheck() {}public static DoubleCheck getInstance(){if(doubleCheck==null)synchronized (DoubleCheck.class){if(doubleCheck==null){doubleCheck=new DoubleCheck();}}return doubleCheck;}
}

2 原型模式

原型模式是通过创建一个实例去实现Cloneable接口,用这个已经创建的实例作为原型,通过复制该对象来创建一个和原型相同或相似的新对象。克隆分为浅克隆和深克隆。下列代码为测试实体类


2.1 浅克隆

创建一个新对象,新对象和旧对象基本类型数据的值相同,对于引用类型的数据共用内存地址。

@Testpublic void testShallowClone() throws CloneNotSupportedException {User user = new User();user.setGender("1");user.setName("LiMing");user.setMoney(new Money(5));User cloneUser = user.clone();cloneUser.setName("ZhangSan");cloneUser.getMoney().setCount(10);System.out.println(user);System.out.println(cloneUser);}
class User implements Cloneable {private String name;private String gender;private Money money;@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", gender='" + gender + '\'' +", money=" + money +'}';}public Money getMoney() {return money;}public void setMoney(Money money) {this.money = money;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public User clone() throws CloneNotSupportedException {return (User) super.clone();}
}
class Money{double count;public Money(double count) {this.count = count;}public double getCount() {return count;}@Overridepublic String toString() {return "Money{" +"count=" + count +'}';}public void setCount(double count) {this.count = count;}
}

运行结果:
在这里插入图片描述

2.2 深克隆

解决思路,在引用类型数据上也实现Cloneable。

public User clone() throws CloneNotSupportedException {User clone = (User) super.clone();Money money = new Money(1);clone.setMoney(money.clone());return clone;}

3 工厂方法模式

工厂方法模式是简单工厂模式的延伸,包含以下四个角色:

  • Product(抽象产品):它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类。
  • ConcreteProduct(具体产品):它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品之间一一对应。
  • Factory(抽象工厂):在抽象工厂类中声明了工厂方法( Factory Method),用于返回一个产品。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
  • ConcreteFactory(具体工厂):它是抽象工厂类的子类,实现了在抽象工厂中声明的工厂方法,并可由客户端调用,返回一个具体产品类的实例。
public class Factory {@Testpublic void testFactoryMethod(){OrderPizza orderPizza=new BJOrderPizza();Pizza pizza = orderPizza.createPizza("cheese");System.out.println(pizza);orderPizza=new SHOrderPizza();pizza= orderPizza.createPizza("cheese");System.out.println(pizza);}
}
//抽象工厂类
interface OrderPizza{Pizza createPizza(String orderType);
}
//具体工厂类
class BJOrderPizza implements OrderPizza{@Overridepublic Pizza createPizza(String orderType) {Pizza pizza=null;if("cheese".equals(orderType)){pizza=new CheesePizza();}else if("greek".equals(orderType)){pizza=new GreekPizza();}return pizza;}
}
class SHOrderPizza implements OrderPizza{@Overridepublic Pizza createPizza(String orderType) {Pizza pizza=null;if("cheese".equals(orderType)){pizza=new GreekPizza();}else if("greek".equals(orderType)){pizza=new CheesePizza();}return pizza;}
}
//抽象产品
interface Pizza{void bake();
}
//具体产品
class CheesePizza implements Pizza{@Overridepublic void bake() {System.out.println("CheesePizza烘培中");}
}
class GreekPizza implements Pizza{@Overridepublic void bake() {System.out.println("GreekPizza烘培中");}
}

4 抽象工厂模式

把工厂方法的范围扩大了,原来工厂方法模式中考虑的是一种产品的生产,而在抽象工厂模式中考虑多种同等级产品的生产。

简单工厂模式、工厂方法模式、抽象工厂模式之间的异同

简单工厂模式中没有抽象工厂类,如果要增加新的功能,必须对工厂类进行修改,违背了"开闭原则"。
工厂模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类
抽象工厂模式:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类

工厂方法模式抽象工厂模式
针对的是一个产品等级结构针对的是多个产品等级结构
一个抽象产品类多个抽象产品类
可以派生出多个具体产品类每个抽象产品类能派生出多个具体产品类
一个抽象工厂类可以派生出多个具体产品类一个抽象工厂类可以派生出多个具体产品类
每个具体工厂类只能创建一个具体产品类的实例每个具体工厂类可以创建多个具体产品类的实例

5 建造者模式

构成要素:

  • 产品角色:包含多个组件的复杂对象,由具体创建者来创建其各个部位
  • 抽象建造者:它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法getResult()
  • 具体建造者:实现Builder接口,完成复杂产品的各个部件的具体创建方法。
  • 指挥者:调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
/** 装修客厅的墙,客户只需要把需求告诉产品经理,产品经理再去指挥工人装修* 指挥者->建造者->产品* */
public class Builder {public static void main(String[] args) {Worker1 worker1 = new Worker1();Worker2 worker2 = new Worker2();//让worker1去建造ProduceManager produceManager = new ProduceManager(worker1);Parlour decorate = produceManager.decorate();System.out.println(decorate);//让worker2去建造produceManager = new ProduceManager(worker2);decorate = produceManager.decorate();System.out.println(decorate);}
}
//产品
class Parlour{private String wall;private String TV;@Overridepublic String toString() {return "Parlour{" +"wall='" + wall + '\'' +", TV='" + TV + '\'' +", soft='" + soft + '\'' +'}';}private String soft;public String getWall() {return wall;}public void setWall(String wall) {this.wall = wall;}public String getTV() {return TV;}public void setTV(String TV) {this.TV = TV;}public String getSoft() {return soft;}public void setSoft(String soft) {this.soft = soft;}
}
//抽象建造者
abstract class Decorator{protected Parlour parlour=new Parlour();abstract void buildWall();abstract void buildTV();abstract void buildSoft();public Parlour getParlour(){return parlour;}
}
//具体建造者
class Worker1 extends Decorator{void buildWall() {parlour.setWall("wall build by woker1");}void buildTV() {parlour.setTV("TV build by worker1");}void buildSoft() {parlour.setSoft("soft build by worker1");}
}
class Worker2 extends Decorator{void buildWall() {parlour.setWall("wall build by woker2");}void buildTV() {parlour.setTV("TV build by worker2");}void buildSoft() {parlour.setSoft("soft build by worker2");}
}
//指挥者
class ProduceManager{private Decorator decorator;public ProduceManager(Decorator decorator) {this.decorator = decorator;}public Parlour decorate(){decorator.buildSoft();decorator.buildTV();decorator.buildWall();return decorator.getParlour();}
}

如果把建造者作为产品的内部类,去除抽象建造者,那就是建造模式在Java中的一种简化使用方式。
缺点:
如果产品内部发生变化,建造者也要同步修改,后期维护成本大。
优点:
封装性好,扩展性好,客户端不必知道知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生影响。

结构型模式

结构性模式描述的是如何将类或对象按某种布局组成更大的结构。

6 代理模式

代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。

6.1 静态代理

静态代理在使用时需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同的类。

@Testpublic void testStaticProxy(){UserDaoProxy userDaoProxy = new UserDaoProxy(new UserDao());userDaoProxy.save();}//接口
interface IUserDao{void save();
}
//目标对象
class UserDao implements IUserDao{@Overridepublic void save() {System.out.println("--保存数据--");}
}
//代理对象
class UserDaoProxy implements IUserDao{IUserDao iUserDao=null;public UserDaoProxy(IUserDao iUserDao) {this.iUserDao = iUserDao;}@Overridepublic void save() {System.out.println("--save前--");iUserDao.save();System.out.println("--save后--");}
}

缺点:一旦接口中增加方法,目标对象和代理对象都需要维护。

6.2 动态代理

动态代理中不需要实现接口,通过使用反射,动态的在内存中构建代理对象,动态代理也称JDK代理。关键创建一个InvocationHandler的实现类。

@Testpublic void testDynamicProxy(){UserDao userDao = new UserDao();IUserDao iUserDao = (IUserDao) java.lang.reflect.Proxy.newProxyInstance(UserDao.class.getClassLoader(), UserDao.class.getInterfaces(), new ProxyHandler(userDao));iUserDao.save();}
class ProxyHandler implements InvocationHandler{private Object object;public ProxyHandler(Object object) {this.object = object;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("--save前--");Object invoke = method.invoke(object, args);System.out.println("--save前--");return invoke;}
}

6.3 CGLIB代理

JDK实现动态代理需要实现类通过接口定义方法,对于没有接口的类,如何实现动态代理呢?这就需要CGLIB了,CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。但因为采用的是继承,所以不能对final修饰的类进行代理。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。

@Testpublic void testProxyCglib(){UserDao userDao = new UserDao();Enhancer enhancer = new Enhancer();enhancer.setSuperclass(UserDao.class);MethodInterceptor methodInterceptor=(Object o, Method method, Object[] objects, MethodProxy methodProxy)->{System.out.println("--save前--");//不要使用method.invoke(o,objects) 不然会出现死循环Object invoke = methodProxy.invokeSuper(o,objects);System.out.println("--save后--");return invoke;};enhancer.setCallback(methodInterceptor);UserDao dao = (UserDao) enhancer.create();dao.save();}

7 适配器模式

通过实现将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。

7.1 类适配器模式

适配器类通过继承适配者类和实现目标接口,在实现的方法中去调用适配者类的相应方法。

 @Testpublic void testClassAdapter(){VoltageAdapter voltageAdapter = new VoltageAdapter();voltageAdapter.output5();}//适配者类
class Voltage220{public int output220(){int voltage=220;System.out.println("当前电压"+voltage);return voltage;}
}
//目标接口
interface Voltage5{int output5();
}
//适配器类
class VoltageAdapter extends Voltage220 implements Voltage5{@Overridepublic int output5() {int voltage220 = this.output220();int voltage5 = voltage220 / 44;System.out.println("转换之后的电压为"+voltage5);return voltage5;}
}

7.2 对象适配器模式

对象适配器模式是最常用的,适配器类需要实现目标接口,通过客户端传入适配者类对象,进而在实现的方法中使用适配者对象去调用相应的方法。

 @Testpublic void testObjectAdapter(){Voltage220 voltage220 = new Voltage220();VoltageAdapter voltageAdapter = new VoltageAdapter(voltage220);voltageAdapter.output5();}class VoltageAdapter implements Voltage5{private Voltage220 voltage220=null;public VoltageAdapter(Voltage220 voltage220) {this.voltage220 = voltage220;}public int output5() {int voltage5=0;if(null != voltage220) {int a = voltage220.output220();voltage5 = a / 44;System.out.println("转换之后的电压为" + voltage5);}return voltage5;}
}

7.3 接口适配器模式

也叫认适配器模式(Default Adapter Pattern)或缺省适配器模式。让适配器类去继承中间适配器,具体的操作在中间适配器中完成。

 @Testpublic void testInterfaceAdapter(){VoltageAdapter voltageAdapter = new VoltageAdapter(new Voltage220());voltageAdapter.output5v();}
//中间适配器
abstract class MediationAdapter implements Voltage5{protected Voltage220 voltage220;public MediationAdapter(Voltage220 voltage220) {this.voltage220 = voltage220;}public int output5(){int voltage5=0;if(null != voltage220) {int a = voltage220.output220();voltage5 = a / 44;System.out.println("转换之后的电压为" + voltage5);}return voltage5;}
}
// 具体适配器
class VoltageAdapter extends MediationAdapter{public VoltageAdapter(Voltage220 voltage220) {super(voltage220);}public int output5v(){int output=0;if(voltage220!=null){output=this.output5();}System.out.println("当前电压"+output);return output;}
}

8 桥接模式

一个类需要在两个或以上维度扩展时,采用继承方式会导致子类繁多,采用桥接模式可以将抽象部分和实现部分分离,使其可以独立变化。

 /** 选购手机时有手机牌子和手机配置* 手机牌子:小米、华为* 手机运行内存:4g、8g* 内存:128、256* */@Testpublic void testBridge(){RAM ram = new RAM4G();Memory memory = new Memory128G();XiaoMi xiaoMi = new XiaoMi();xiaoMi.setRam(ram);xiaoMi.setMemory(memory);xiaoMi.buyPhone();ram =new RAM8G();memory = new Memory256G();HuaWei huaWei = new HuaWei();huaWei.setMemory(memory);huaWei.setRam(ram);huaWei.buyPhone();}
//抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
abstract class Phone{public Memory memory;public RAM ram;public void setMemory(Memory memory) {this.memory = memory;}public void setRam(RAM ram) {this.ram = ram;}public abstract void buyPhone();
}
//扩展抽象化(Refined    Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
class XiaoMi extends Phone{@Overridepublic void buyPhone() {System.out.println("你所购买的是小米:"+ram.getRAM()+"+"+memory.getMemory());}
}
class HuaWei extends Phone{@Overridepublic void buyPhone() {System.out.println("你所购买的是华为:"+ram.getRAM()+"+"+memory.getMemory());}
}
//实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。
//品牌
interface Brand{String getName();
}
//运行内存
interface RAM{String getRAM();
}
interface Memory{String getMemory();
}
//具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。
class RAM4G implements RAM{@Overridepublic String getRAM() {return "4G";}
}
class RAM8G implements RAM{@Overridepublic String getRAM() {return "8G";}
}
class Memory128G implements Memory{@Overridepublic String getMemory() {return "128G";}
}
class Memory256G implements Memory{@Overridepublic String getMemory() {return "256G";}
}

9 装饰模式

在不改变现有对象结构的情况下,动态的给对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。

/** 模仿买奶茶时加东西* */@Testpublic void testDecorator(){MilkTea milkTea = new PearMilkTea();AddCoffe addCoffe = new AddCoffe(milkTea);System.out.println(addCoffe.getMilkTeaName()+"\n合计"+addCoffe.getPrice()+"元");AddIceTaste addIceTaste = new AddIceTaste(milkTea);System.out.println(addIceTaste.getMilkTeaName()+"\n合计"+addIceTaste.getPrice()+"元");}
//抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
interface MilkTea{String getMilkTeaName();int getPrice();
}
//具体构件(Concrete    Component)角色:实现抽象构件,通过装饰角色为其添加一些职责。
class PearMilkTea implements MilkTea{@Overridepublic String getMilkTeaName() {return "珍珠奶茶";}@Overridepublic int getPrice() {return 15;}
}
class HoneyMilkTea implements MilkTea{@Overridepublic String getMilkTeaName() {return "蜂蜜奶茶";}@Overridepublic int getPrice() {return 20;}
}
//抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
abstract class Taste implements MilkTea{protected MilkTea milkTea;public Taste(MilkTea milkTea) {this.milkTea = milkTea;}
}
//具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
class AddIceTaste extends Taste{private String description="加冰";public AddIceTaste(MilkTea milkTea) {super(milkTea);}@Overridepublic String getMilkTeaName() {return milkTea.getMilkTeaName()+description;}@Overridepublic int getPrice() {return milkTea.getPrice()+5;}
}
class AddCoffe extends Taste{private String description="加咖啡";public AddCoffe(MilkTea milkTea) {super(milkTea);}@Overridepublic String getMilkTeaName() {return milkTea.getMilkTeaName()+description;}@Overridepublic int getPrice() {return milkTea.getPrice()+15;}
}

桥接模式和装饰模式的区别:

两个模式都是为了解决子类过多的问题,但他们的诱因不同:桥接模式注重的是在设计之初使用,而装饰器模式是因为适应新需求而添加新的功能,并且不影响其它对象的一种模式,在扩展时候使用。

10 外观模式

通过多个复杂的子系统提供一个一致的外观角色,而使这些子系统更加容易被访问,外观模式是迪米特法则的典型应用。
在这里插入图片描述

/*
* 模仿开关 同时控制两层楼的灯。
* */
//客户(Client)角色:通过一个外观角色访问各个子系统的功能。@Testpublic void testFacade(){Switch aSwitch = new Switch();aSwitch.start();aSwitch.shutdown();}
//外观(Facade)角色:为多个子系统对外提供一个共同的接口。
class Switch{FirstFloor firstFloor =new FirstFloor();SecondFloor secondFloor =new SecondFloor();public void start(){firstFloor.start();secondFloor.start();}public void shutdown(){firstFloor.shutdown();secondFloor.shutdown();}
}
//子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。
class FirstFloor{public void start(){System.out.println("一楼 的灯已打开");}public void shutdown(){System.out.println("一楼的灯已关闭");}
}
class SecondFloor{public void start(){System.out.println("二楼的灯已打开");}public void shutdown(){System.out.println("二楼的灯已关闭");}
}

11 享元模式

通过共享技术有效的支持大量细粒度对象的复用,通过共享已经存在的对象来大幅减少需要创建对象的数量。

/** 模仿从线程池中创建线程* */@Testpublic void testFlyWeight(){ThreadPool threadPool = new ThreadPool();Thread thread01 = threadPool.getThread("a");thread01.operation(new UnsharedConcreteFlyweight("第一次调用a"));Thread thread02 = threadPool.getThread("b");thread02.operation(new UnsharedConcreteFlyweight("第一次调用b"));Thread thread03 = threadPool.getThread("a");thread03.operation(new UnsharedConcreteFlyweight("第二次调用a"));Thread thread04 = threadPool.getThread("b");thread04.operation(new UnsharedConcreteFlyweight("第二次调用b"));}
//抽象享元角色(Flyweight):是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。
interface Thread{void operation(UnsharedConcreteFlyweight state);
}
//具体享元(Concrete Flyweight)角色:实现抽象享元角色中所规定的接口。
class ThreadImpl implements Thread{private String key;public ThreadImpl(String key) {this.key = key;}@Overridepublic void operation(UnsharedConcreteFlyweight state) {System.out.print("具体享元"+key+"被调用,");System.out.println("非享元信息是:"+state.getInfo());}
}
//非享元(Unsharable Flyweight)角色:是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。
class UnsharedConcreteFlyweight{private String info;public String getInfo() {return info;}public void setInfo(String info) {this.info = info;}public UnsharedConcreteFlyweight(String info) {this.info = info;}
}
//享元工厂(Flyweight Factory)角色:负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。
class ThreadPool{private HashMap<String,Thread> map=new HashMap<>();public Thread getThread(String key){Thread thread = map.get(key);if(null !=thread){System.out.println("具体享元"+key+"已经存在,被成功获取!");}else{System.out.println("创建具体享元");thread=new ThreadImpl(key);map.put(key,thread);}return thread;}
}

12 组合模式

组合模式允许你将对象组合成树形结构来表现”部分-整体“的层次结构,使得客户以一致的方式处理单个对象以及对象的组合。
组合模式实现的最关键的地方是——简单对象和复合对象必须实现相同的接口。这就是组合模式能够将组合对象和简单对象进行一致处理的原因。

 @Testpublic void testComposite(){Composit composit = new Composit();composit.add(new Leaf("a"));Leaf b = new Leaf("b");composit.add(b);composit.add(new Leaf("c"));composit.operation();composit.remove(b);composit.operation();}
//抽象构件(Component)角色:它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为。在透明式的组合模式中抽象构件还声明访问和管理子类的接口;在安全式的组合模式中不声明访问和管理子类的接口,管理工作由树枝构件完成。
interface Component{void add(Component c);void remove(Component c);void operation();
}
//树叶构件(Leaf)角色:是组合中的叶节点对象,它没有子节点,用于实现抽象构件角色中 声明的公共接口。
class Leaf implements Component{private String name;public Leaf(String name){this.name=name;}@Overridepublic void add(Component c) {}@Overridepublic void remove(Component c) {}@Overridepublic void operation() {System.out.println("树叶"+name+":被访问!");}
}
//树枝构件(Composite)角色:是组合中的分支节点对象,它有子节点。它实现了抽象构件角色中声明的接口,它的主要作用是存储和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。
class Composit implements Component{private List<Component> list = new LinkedList<>();@Overridepublic void add(Component c) {list.add(c);}@Overridepublic void remove(Component c) {list.remove(c);}@Overridepublic void operation() {for (Component component : list) {component.operation();}}
}

行为型模式

行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。

13 模板方法模式

定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
模板方法模式包含以下主要角色:
1:抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。这些方法的定义如下:
模板方法:定义了算法的骨架,按照某种顺序调用其包含的基本方法。
基本方法:是整个算法中的一个步骤,包含以下几种类型:
~ 抽象方法:再抽象类中生命,由具体子类实现。
~ 具体方法:再抽象类中已经实现,在具体子类中可以继承或重写它。
~ 钩子方法:再抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。
2:具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的一个组成步骤。

@Testpublic void testTM(){MeCook meCook = new MeCook();meCook.cook();ChefCook chefCook = new ChefCook();chefCook.cook();}
//抽象类(Abstract Class)
abstract class Cook{public abstract void oil();public abstract void tomato();public abstract void egg();public final void cook(){this.oil();this.tomato();this.egg();}
}
//具体子类(Concrete Class)
class MeCook extends Cook{@Overridepublic void oil() {System.out.println("放了1斤油");}@Overridepublic void tomato() {System.out.println("放了2个西红柿");}@Overridepublic void egg() {System.out.println("放了10个鸡蛋");}
}
class ChefCook extends Cook{@Overridepublic void oil() {System.out.println("放了适当的油");}@Overridepublic void tomato() {System.out.println("放了适量的西红柿");}@Overridepublic void egg() {System.out.println("放了适量的鸡蛋");}
}

14 策略模式

策略模式是准备一组算法,并将这组算法封装到一系列的策略类里面,作为一个抽象策略类的子类。策略模式的重心不是如何实现算法,而是如何组织这些算法,从而让程序结构更加灵活,具有更好的维护性和扩展性。

//模仿使用加减法
@Testpublic void testStrage(){AddStrategy addStrategy = new AddStrategy();Calculate calculate = new Calculate(addStrategy);System.out.println("5+3="+calculate.calculate(5,3));;SubStrategy subStrategy = new SubStrategy();calculate = new Calculate(subStrategy);System.out.println("5-3="+calculate.calculate(5,3));;}
//抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
interface CalStrategy{int cal(int num1,int num2);
}
//具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
class AddStrategy implements CalStrategy{@Overridepublic int cal(int num1, int num2) {return num1+num2;}
}
class  SubStrategy implements CalStrategy{@Overridepublic int cal(int num1, int num2) {return num1-num2;}
}
//环境(Context)类:持有一个策略类的引用,最终给客户端调用。
class Calculate{private CalStrategy calStrategy;public Calculate(CalStrategy calStrategy) {this.calStrategy = calStrategy;}public int calculate(int a,int b){return calStrategy.cal(a,b);}
}

15 命令模式

将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。

/** 模仿点早餐* 客户把需求告诉服务员,服务员去调用命令去通知厨师出餐。* */
@Testpublic void testCommand(){Breakfast breakfast= new ChangFen();Waiter waiter = new Waiter();waiter.setChangFen(breakfast);waiter.chooseCF();}
//抽象命令类(Command)角色:声明执行命令的接口,拥有执行命令的抽象方法 execute()。
interface Breakfast{void cooking();
}
//具体命令角色(Concrete    Command)角色:是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。
class ChangFen implements Breakfast{private ChanFenChef chanFenChef;public ChangFen() {this.chanFenChef=new ChanFenChef();}public void cooking() {System.out.println("通知肠粉师傅去做");chanFenChef.cooking();}
}
class HunTun implements Breakfast{private HunTunChef hunTunChef;public HunTun() {this.hunTunChef=new HunTunChef();}public void cooking() {System.out.println("通知馄饨师傅去做");hunTunChef.cooking();}
}
//实现者/接收者(Receiver)角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者。
class ChanFenChef{public void cooking(){System.out.println("肠粉已做好");}
}
class HunTunChef{public void cooking() {System.out.println("馄饨已做好");}
}
//调用者/请求者(Invoker)角色:是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。
class Waiter{private Breakfast changFen,hunTun;public Breakfast getChangFen() {return changFen;}public void setChangFen(Breakfast changFen) {this.changFen = changFen;}public Breakfast getHunTun() {return hunTun;}public void setHunTun(Breakfast hunTun) {this.hunTun = hunTun;}public void chooseCF(){changFen.cooking();}public void chooseHT(){hunTun.cooking();}
}

15.1 组合命令模式

组合模式和命令模式的联合使用称作组合命令模式,也叫宏命令模式。
思路:
组合模式中的树叶节点和命令模式中的具体命令等价。
组合模式中的树枝节点和命令模式中的调用者等价。

16 责任链模式

为了避免一个请求与多个请求处理者耦合在一起,将所有请求的处理者通过前一个对象记住其下一个对象的引用而形成一条链,当请求发生时,可将请求沿着这条链传递,知道有对象处理为止。在·

/** 规定学生请假小于或等于 2 天,班主任可以批准;*             小于或等于 7 天,系主任可以批准;*              小于或等于 10 天,院长可以批准;其他情况不予批准* *///客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。@Testpublic void testCor(){ClassAdviser classAdviser = new ClassAdviser();DepartmentHead departmentHead = new DepartmentHead();classAdviser.setNext(departmentHead);Dean dean = new Dean();departmentHead.setNext(dean);classAdviser.handleRequest(5);classAdviser.handleRequest(2);classAdviser.handleRequest(9);classAdviser.handleRequest(11);}
//抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
abstract class Leader{private Leader next;public Leader getNext() {return next;}public void setNext(Leader next) {this.next = next;}public abstract void handleRequest(int leaveDays);
}
//具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
//班主任
class ClassAdviser extends Leader{@Overridepublic void handleRequest(int leaveDays) {if(leaveDays >0 && leaveDays<=2){System.out.println("班主任批准了");}else{if(this.getNext()!=null){this.getNext().handleRequest(leaveDays);}else{System.out.println("请假太久没人批");}}}
}
//院长
class Dean extends Leader{@Overridepublic void handleRequest(int leaveDays) {if(leaveDays >7 && leaveDays<=10){System.out.println("院长批准了");}else{if(this.getNext()!=null){this.getNext().handleRequest(leaveDays);}else{System.out.println("请假太久没人批");}}}
}
//系主任
class DepartmentHead extends Leader{@Overridepublic void handleRequest(int leaveDays) {if(leaveDays >2 && leaveDays<=7){System.out.println("系主任批准了");}else{if(this.getNext()!=null){this.getNext().handleRequest(leaveDays);}else{System.out.println("请假太久没人批");}}}
}

17 状态模式

状态模式就是把复杂的判断逻辑提取到不同的对象中,允许状态对象在其内部状态改变时改变其行为。

 /** 模仿线程的五种状态变化* */@Testpublic void testState(){ThreadContext threadContext = new ThreadContext();threadContext.start();threadContext.getCPU();threadContext.suspend();threadContext.resume();threadContext.getCPU();threadContext.stop();}
//环境(Context)角色:也称为上下文,它定义了客户感兴趣的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理。
class ThreadContext{private ThreadState threadState;public ThreadContext() {threadState=new New();}public ThreadState getThreadState() {return threadState;}public void setThreadState(ThreadState threadState) {this.threadState = threadState;}public void start(){((New)threadState).start(this);}public void getCPU() {((Runnable) threadState).getCPU(this);}public void suspend() {((Running) threadState).suspend(this);}public void stop() {((Running) threadState).stop(this);}public void resume() {((Blocked) threadState).resume(this);}
}
//抽象状态(State)角色:定义一个接口,用于封装环境对象中的特定状态所对应的行为。
abstract class ThreadState{protected String stateName;
}
//具体状态(Concrete    State)角色:实现抽象状态所对应的行为。
class New extends ThreadState{public New() {stateName="新生状态";System.out.println("当前状态为"+stateName);}public void start(ThreadContext threadContext){if(stateName.equals("新生状态")){threadContext.setThreadState(new Runnable());}else {System.out.println("当前线程不是新建状态,不能调用start()方法.");}}
}
class Runnable extends ThreadState{public Runnable() {stateName="就绪状态";System.out.println("当前状态为"+stateName);}public void getCPU(ThreadContext threadContext){if(stateName.equals("就绪状态")){threadContext.setThreadState(new Running());}else {System.out.println("当前线程不是就绪状态,不能调用getCPU()方法.");}}
}
class Running extends ThreadState{public Running() {stateName="执行状态";System.out.println("当前状态为"+stateName);}public void stop(ThreadContext threadContext){threadContext.setThreadState(new Dead());}public void suspend(ThreadContext threadContext){if(stateName.equals("执行状态")){threadContext.setThreadState(new Blocked());}else {System.out.println("当前线程不是就绪状态,不能调用supend()方法.");}}
}
class Blocked extends ThreadState{public Blocked() {stateName="阻塞状态";System.out.println("当前状态为"+stateName);}public void resume(ThreadContext threadContext){if(stateName.equals("阻塞状态")){threadContext.setThreadState(new Runnable());}else {System.out.println("当前线程不是就绪状态,不能调用resume()方法.");}}
}
class Dead extends ThreadState{public Dead() {stateName="死亡状态";System.out.println("当前状态为"+stateName);}
}

18 观察者模式

观察者模式也叫发布-订阅模式,当多个对象存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
在 Java 中,通过 java.util.Observable 类和 java.util.Observer 接口定义了观察者模式,只要实现它们的子类就可以编写观察者模式实例。

 /**   模仿微信公众号发布消息* */@Testpublic void testObserver(){IPublisher iPublisher=new Publisher();Customer customer = new Customer("王二狗");Customer customer1 = new Customer("李二狗");Customer customer2 = new Customer("朱二狗");iPublisher.registerCustomer(customer);iPublisher.registerCustomer(customer1);iPublisher.registerCustomer(customer2);((Publisher) iPublisher).setInfomation("哈哈哈");}
//抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
interface IPublisher{void registerCustomer(ICustomer customer);void removeCustomer(ICustomer customer);void notifyCustomer();
}
//具体主题(Concrete    Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
class Publisher implements IPublisher{private List<ICustomer> list=new LinkedList<>();private String msg;@Overridepublic void registerCustomer(ICustomer customer) {if(null!=customer){for (ICustomer iCustomer : list) {if(iCustomer==customer){System.out.println("已经有这个用户了");break;}}list.add(customer);}}@Overridepublic void removeCustomer(ICustomer customer) {if(null!=customer){for (ICustomer iCustomer : list) {if(iCustomer==customer){list.remove(customer);}}}}@Overridepublic void notifyCustomer() {for (ICustomer iCustomer : list) {iCustomer.receive(msg);}}public void setInfomation(String msg){this.msg=msg;System.out.println("公众号更新消息如下:"+msg);this.notifyCustomer();}
}
//抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
interface ICustomer {void receive(String msg);
}
//具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
class Customer implements ICustomer{private String name;private String msg;public Customer(String name) {this.name = name;}@Overridepublic void receive(String msg) {this.msg=msg;read();}private void read() {System.out.println(name+":收到推送消息"+msg);}
}

19 中介者模式

中介者模式,定义了一个中介对象来封装一系列对象之间的交互关系。中介者使各个对象之间不需要显式地相互引用,从而使耦合性降低,而且可以独立地改变它们之间的交互行为。中介者模式又叫调停模式,它是迪米特法则的典型应用。

@Testpublic void testMediator(){ConcreteMediator concreteMediator = new ConcreteMediator();ConcreateColleague1 colleague1 = new ConcreateColleague1();ConcreateColleague2 colleague2 = new ConcreateColleague2();ConcreateColleague3 colleague3 = new ConcreateColleague3();concreteMediator.register(colleague1);concreteMediator.register(colleague2);concreteMediator.register(colleague3);colleague2.send();}//抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
abstract class AMediator{public abstract void register(Colleague colleague);//注册public abstract void relay(Colleague colleague,String msg);//转发
}
//具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
class ConcreteMediator extends AMediator{private List<Colleague> list = new LinkedList<>();@Overridepublic void register(Colleague colleague) {if(!list.contains(colleague)) {list.add(colleague);colleague.setaMediator(this);}}@Overridepublic void relay(Colleague colleague,String msg) {for (Colleague temp : list) {if(temp!=colleague){temp.receive(msg);}}}
}
//抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
abstract class Colleague{protected AMediator aMediator;public void setaMediator(AMediator aMediator) {this.aMediator = aMediator;}public abstract void receive(String msg);public abstract void send();
}
//具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
class ConcreateColleague1 extends Colleague{@Overridepublic void receive(String msg) {System.out.println("1号接收到的信息是:"+msg);}@Overridepublic void send() {aMediator.relay(this,"这条信息是1号发送的");}
}
class ConcreateColleague2 extends Colleague{@Overridepublic void receive(String msg) {System.out.println("2号接收到的信息是:"+msg);}@Overridepublic void send() {aMediator.relay(this,"这条信息是1号发送的");}
}
class ConcreateColleague3 extends Colleague{@Overridepublic void receive(String msg) {System.out.println("3号接收到的信息是:"+msg);}@Overridepublic void send() {aMediator.relay(this,"这条信息是1号发送的");}
}

19.1 简化中介者模式

  1. 不定义中介者接口,把具体中介者对象实现称为单例。
  2. 同事对象不持有中介者,而是在需要的时候直接获取中介者对象并调用。

19.2 中介模式和观察者模式的区别

观察者模式强调的是主题(Subject)改变之后对观察者(Observer)的统一通讯。
中介者模式强调的是同事(Colleague)之间的交互。

20 迭代器模式

提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。

@Testpublic void testIterator(){ConcreteAggregate aggregate=new ConcreteAggregate();aggregate.add("a");aggregate.add("b");aggregate.add("c");aggregate.add("d");Iterator iterator = aggregate.getIterator();System.out.println("第一个元素"+iterator.first());while(iterator.hasNext()){Object next = iterator.next();System.out.println(next);}}//抽象聚合(Aggregate)角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。
interface Aggregate{void add(Object o);void remove(Object o);Iterator getIterator();
}
//具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。
class ConcreteAggregate implements Aggregate{private List<Object> list = new LinkedList<>();@Overridepublic void add(Object o) {if(!list.contains(o)){list.add(o);}}@Overridepublic void remove(Object o) {if(list.contains(o)){list.remove(o);}}@Overridepublic Iterator getIterator() {return new Concretelterator(list);}
}
//抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
interface Iterator{Object first();Object next();boolean hasNext();
}
//具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。
class Concretelterator implements Iterator{private List<Object> list;private int index=-1;public Concretelterator(List<Object> list) {this.list = list;}@Overridepublic Object first() {index=0;return list.get(index);}@Overridepublic Object next() {Object o=null;if(this.hasNext())o=list.get(++index);return o;}@Overridepublic boolean hasNext() {return index<list.size()-1?true:false;}
}

21 访问者模式

将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。
对象结构中存在抽象元素的集合,调用对象结构中的某个抽象元素,让它去调用访问者。

 /** 艺术公司利用“铜”可以设计出铜像,利用“纸”做打印纸;造币公司利用“铜”可以印出铜币,利用“纸”可以印出纸币* */@Testpublic void testVisitor(){SetMaterial setMaterial = new SetMaterial();setMaterial.add(new Paper());setMaterial.add(new Cuprum());ArtCompany artCompany = new ArtCompany();String accept = setMaterial.accept(artCompany);System.out.println(accept);}
//抽象访问者(Visitor)角色:定义一个访问具体元素的接口,为每个具体元素类对应一个访问操作 visit() ,该操作中的参数类型标识了被访问的具体元素。
interface Company{String create(Paper paper);String create(Cuprum cuprum);
}
//具体访问者(ConcreteVisitor)角色:实现抽象访问者角色中声明的各个访问操作,确定访问者访问一个元素时该做什么。
class ArtCompany implements Company{@Overridepublic String create(Paper paper) {return "打印纸";}@Overridepublic String create(Cuprum cuprum) {return "铜像";}
}
class Mint implements Company{@Overridepublic String create(Paper paper) {return "纸币";}@Overridepublic String create(Cuprum cuprum) {return "铜钱";}
}
//抽象元素(Element)角色:声明一个包含接受操作 accept() 的接口,被接受的访问者对象作为 accept() 方法的参数。
interface Material{String accept(Company company);
}
//具体元素(ConcreteElement)角色:实现抽象元素角色提供的 accept() 操作,其方法体通常都是 visitor.visit(this) ,另外具体元素中可能还包含本身业务逻辑的相关操作。
class Cuprum implements Material{@Overridepublic String accept(Company company) {return company.create(this);}
}
class Paper implements Material{@Overridepublic String accept(Company company) {return company.create(this);}
}
//对象结构(Object Structure)角色:是一个包含元素角色的容器,提供让访问者对象遍历容器中的所有元素的方法,通常由 List、Set、Map 等聚合类实现。
class SetMaterial{private List<Material> list = new ArrayList<>();public String accept(Company vistor){Iterator<Material> iterator = list.iterator();String tmp="";while(iterator.hasNext()){tmp+=((Material) iterator.next()).accept(vistor)+" ";}return tmp;}public void add(Material Material){list.add(Material);}public void remove(Material Material){list.remove(Material);}
}

22 备忘录模式

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式。

@Testpublic void testMemento(){//发起人 备忘录 管理者Caretaker caretaker = new Caretaker();Originator originator = new Originator();originator.setState("first");System.out.println("当前状态为"+originator.getState());Memo memo = originator.createMemo();System.out.println("备忘录中的状态为"+memo.getState());caretaker.setMemo(memo);originator.setState("second");System.out.println("当前状态为"+originator.getState());originator.restoreMemo(memo);System.out.println("恢复之后的状态为"+originator.getState());}
//发起人(Originator)角色:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
class Originator{private String state;public String getState() {return state;}public void setState(String state) {this.state = state;}public Memo createMemo(){return new Memo(state);}public void restoreMemo(Memo memo){this.setState(memo.getState());}
}
//备忘录(Memento)角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
class Memo{private String state;public Memo(String state) {this.state = state;}public String getState() {return state;}public void setState(String state) {this.state = state;}
}
//管理者(Caretaker)角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。
class Caretaker{private Memo memo;public Memo getMemo() {return memo;}public void setMemo(Memo memo) {this.memo = memo;}
}

23 解释器模式

给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。
抽象表达式中定义解释的操作,非终结符表达式对象负责拆分请求信息,并把拆分出来的信息传给终结符表达式对象进行判断,环境类中负责维护终结者和非终结者对象。

/** 公交车读卡器可以判断乘客的身份,* 如果是“上海”或者“广州”的“老人” “妇女”“儿童”就可以免费乘车,其他人员乘车一次扣 2 元。* 文法规则* <expression> ::= <city>的<person>*     <city> ::= 韶关|广州*     <person> ::= 老人|妇女|儿童* */@Testpublic void testInterpreter(){Context bus=new Context();bus.freeRide("上海的老人");bus.freeRide("上海的年轻人");bus.freeRide("广州的妇女");bus.freeRide("广州的儿童");bus.freeRide("山东的儿童");}
//抽象表达式(Abstract Expression)角色:定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。
interface Expression{public boolean interpret(String info);
}
//终结符表达式(Terminal    Expression)角色:是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。
class TerminalExpression implements Expression{private Set<String> set = new HashSet<>();public TerminalExpression(String[] data) {for(int i=0;i<data.length;i++)set.add(data[i]);}public boolean interpret(String info) {if(set.contains(info)){return true;}return false;}
}
//非终结符表达式(Nonterminal Expression)角色:也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。
class AndExpression implements Expression{private Expression city=null;private Expression person=null;public AndExpression(Expression city,Expression person){this.city=city;this.person=person;}public boolean interpret(String info){String s[]=info.split("的");return city.interpret(s[0])&&person.interpret(s[1]);}
}
//环境(Context)角色:通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。
class Context{private String[] citys={"上海","广州"};private String[] persons={"老人","妇女","儿童"};private Expression cityPerson;public Context() {Expression city=new TerminalExpression(citys);TerminalExpression person = new TerminalExpression(persons);cityPerson=new AndExpression(city,person);}public void freeRide(String info){boolean interpret = cityPerson.interpret(info);if(interpret) System.out.println("您是"+info+",您本次乘车免费!");else System.out.println(info+",您不是免费人员,本次乘车扣费2元!");}
}

参考文献:
23种设计模式

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. Vue 中的父子组件传值

    文章目录父组件向子组件传值1. 父组件的 data 组件中定义要传的值2. 在父组件中引用的子组件标签进行传值3. 子组件通过 props 属性来接收4. 子组件中使用5. 注意点子组件向父组件传值1. 子组件通过 $emit 方法向父组件传值2. 父组件中引用的子组件标签上添加函数3. 父组件中使…...

    2024/4/13 6:16:44
  2. 正交相似于对角阵和酉相似于对称阵的充要条件

    ...

    2024/4/24 8:43:39
  3. [AcWing面向模型编程]区间DP

    题目&#xff1a;321. 棋盘分割 分析&#xff1a; dp[x1][y1][x2][y2][k]表示在(x1, y1) ~ (x2, y2)的区域内分成k个块所贡献的结果&#xff0c;然后分横竖枚举划分方式&#xff0c;这个dp要用记忆化搜索写&#xff0c;循环写太麻烦。 逐渐明白了记忆化搜索对于dp的意义 代码…...

    2024/4/24 23:27:48
  4. 大型数据库

    文章目录一、准备工作二、登录&#xff0c;连接&#xff0c;解锁一、准备工作 OracleDBConsoleorcl数据库控制台服务OracleOraDb11g_home1TNSListener监听服务OracleServiceORCL数据库服务二、登录&#xff0c;连接&#xff0c;解锁 sqlplus sys/Oraclel11 as sysdba注&#xf…...

    2024/4/23 7:11:50
  5. 使用retrofit进行网络请求

    一、需求 访问网络接口获取星座数据 二、网络框架 一个基于 OkHttp 的 RESTful API 请求工具 Retrofit 在使用时其实就充当了一个适配器&#xff08;Adapter&#xff09;的角色&#xff0c;主要是将一个 Java 接口翻译成一个 HTTP 请求对象&#xff0c;然后用 OkHttp 去发送这个…...

    2024/4/26 4:58:01
  6. Day26 HTML

    1.什么是HTML Hyper Text Markup Language&#xff08;超文本标记语言&#xff09; 2.发展史 3.HTML5的优势 4.W3C标准 5.HTML基本结构 6.网页基本信息 <!-- DOCTYPE:告诉浏览器&#xff0c;我们要使用什么规范 --> <!DOCTYPE html> <html lang"en"…...

    2024/4/17 4:14:34
  7. [GXYCTF2019]禁止套娃(.git泄露,php代码审计)

    1 .git泄露.直接到github中下载对应的工具. 跑一下. e 得到index.php源代码. <?php include "flag.php"; echo "flag在哪里呢&#xff1f;<br>"; if(isset($_GET[exp])){if (!preg_match(/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i, $_GET[e…...

    2024/4/27 1:12:27
  8. Java学习笔记-Day02 Eclipse软件的使用

    Java学习笔记-Day02 Eclipse软件的使用一、简介二、Eclipse的基本操作1、重置Eclipse窗口2、新建一个Java项目2、新建一个Java源代码文件3、Java源代码文件的运行4、Eclipse的快捷键5、代码对齐和自动补全6、代码注释一、简介 在实际开发工作中&#xff0c;不会使用记事本来开…...

    2024/4/23 15:50:24
  9. 基于单片机的指纹识别电子密码锁设计

    文末下载完整资料 1.1 指纹识别简介 1.1.1 指纹识别原理   指纹识别技术的原理和其它生物识别技术的原理相似。它是利用人体的指纹特征对个体身份进行区分和鉴定。在所有的生物识别技术中指纹识别技术是目前最为成熟&#xff0c;也被应用最广的生物识别技术。这主要因为指纹…...

    2024/4/14 5:26:37
  10. GCC 手册 5.5 学习03

    【原文】The language-independent component of GCC includes the majority of the optimizers, as well as the “back ends” that generate machine code for various processors. 【注释】 the majority of 大多数……the great majority of 大部分 ; 大部分…the vas…...

    2024/4/22 15:27:52
  11. 一致性哈希和哈希槽(redis)

    1、集群分片模式 如果 redis 只用复制功能做主从&#xff0c;那么当数据量巨大的情况下&#xff0c;单机情况下可能已经承受不下一份数据&#xff0c;更不用说是主从都要各自保存一份完整的数据。在这种情况下&#xff0c;数据分片是一个非常好的解决办法。 redis 的 custer …...

    2024/4/26 11:36:44
  12. Error:scalac: Error: scala.collection.immutable.$colon$colon.tl$1()Lscala/collection/immutable/List;

    intellij包错如下: Error:scalac: Error: scala.collection.immutable.$colon$colon.tl$1()Lscala/collection/immutable/List; java.lang.NoSuchMethodError: scala.collection.immutable.$colon$colon.tl$1()Lscala/collection/immutable/List;at org.apache.flink.api.scal…...

    2024/4/20 4:01:04
  13. 记录一次BIOS+MBR无损转换UEFI+GPT

    文章目录前情提要系统盘&#xff1a;利用windows内置的mbr2gpt.exe进行转换其他盘&#xff1a;用傲梅分区助手进行转换总结前情提要 最近在准备安装linux&#xff0c;一看自己电脑居然是BIOSMBR。 同时自己在看了相关的书之后对UEFIGPT比较有好感&#xff0c;于是便走上了瞎折…...

    2024/4/23 10:06:59
  14. LeetCode剑指 Offer 05. 替换空格

    //剑指 Offer 05. 替换空格 class Solution { public:string replaceSpace(string s) {string ans;for (auto x : s) if (x ) ans "%20";else ans x;return ans;} };...

    2024/4/13 16:49:49
  15. 浅谈远程过程调用——RPC

    在复习SpringCloud的时候总是会遇到RPC这一词&#xff0c;但又不知道是何方神圣&#xff0c;上网冲浪了解了一下RPC&#xff0c;在此记录下对RPC的初步认识。 1. 什么是RPC 1.1 本地过程调用 如果我们需要将本地的Student对象的age加1&#xff0c;那么就需要写一个Student a…...

    2024/4/24 12:35:35
  16. Linux系统优化与查看命令

    Linux系统优化与查看命令 配置防火墙 [rootyum-server ~]# firewall-cmd --permanent --add-serviceftp [rootyum-server ~]# firewall-cmd --reload or [rootyum-server ~]#systemctl stop firewalld && systemctl disable firewalld关闭SELinux [rootyum-server …...

    2024/4/26 17:27:39
  17. Android-自定义控件的学习

    1. 需求 : 做一个圆形的红色按钮中间有一个白色的数字数字起始为20每点击一次减少1 2. View是如何工作的? 构造器---->初始化 onMesure() 定大小 onLayout() 定位置 onDraw() 绘制 invalidate() 刷新 5.1 添加一个Button组件并设置点击事件 public class MainActiv…...

    2024/4/17 12:40:22
  18. 毕业论文相关

    四到五章内容&#xff0c;包括引言&#xff0c;背景&#xff0c;研究方法&#xff0c;自己所做的工作&#xff0c;和一章总结。 和本科毕业论文相比&#xff0c;内容的深度更深&#xff0c;体现研究更深入&#xff0c;有一章的自己工作原创性较强。 建议先完成研究方法部分。…...

    2024/4/19 13:01:26
  19. SSM聚合工程+ Vue+Axios前后端分离CRUD实战-----第一章

    统一工具类配置&#xff1a; email配置&#xff1a; 测试发送邮件环境是否搭建成功&#xff1a; SpringRedisTemplate配置&#xff1a; redis.properties: redis.xml: 测试是否搭建成功 前后端分离的跨域设置&#xff1a; 前端页面&#xff1a;...

    2024/4/23 18:43:17
  20. 1.Web开发探究

    Web开发探究 接下来呢&#xff0c;我们开始学习SpringBoot与Web开发&#xff0c;从这一章往后&#xff0c;就属于我们实战 部分的内容了&#xff1b; 其实SpringBoot的东西用起来非常简单&#xff0c;因为SpringBoot最大的特点就是自动装配。 使用SpringBoot的步骤&#xff…...

    2024/4/22 23:13:07

最新文章

  1. WebGL开发框架比较

    WebGL开发框架提供了一套丰富的工具和API&#xff0c;使得在Web浏览器中创建和操作3D图形变得更加容易。以下是一些流行的WebGL开发框架及其各自的优缺点。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.Three.js 优点&#xff1a…...

    2024/4/27 3:27:10
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. 探索进程控制第一弹(进程终止、进程等待)

    文章目录 进程创建初识fork函数fork函数返回值fork常规用法fork调用失败的原因 写时拷贝进程终止进程终止是在做什么&#xff1f;进程终止的情况代码跑完&#xff0c;结果正确/不正确代码异常终止 如何终止 进程等待概述进程等待方法wait方法waitpid 进程创建 初识fork函数 在…...

    2024/4/22 16:14:13
  4. C# 构建可定时关闭的异步提示弹窗

    C# 构建可定时关闭的异步提示弹窗 引言1、调用接口的实现2、自动定时窗口的实现 引言 我们在最常用最简单的提示弹框莫过于MessageBox.Show( )的方法了&#xff0c;但是使用久了之后&#xff0c;你会发现这个MessageBox并不是万能的&#xff0c;有事后并不想客户去点击&#x…...

    2024/4/23 6:37:29
  5. 416. 分割等和子集问题(动态规划)

    题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义&#xff1a;dp[i][j]表示当背包容量为j&#xff0c;用前i个物品是否正好可以将背包填满&#xff…...

    2024/4/27 1:53:53
  6. 【Java】ExcelWriter自适应宽度工具类(支持中文)

    工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

    2024/4/25 21:14:51
  7. Spring cloud负载均衡@LoadBalanced LoadBalancerClient

    LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon&#xff0c;直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件&#xff0c;我们讨论Spring负载均衡以Spring Cloud2020之后版本为主&#xff0c;学习Spring Cloud LoadBalance&#xff0c;暂不讨论Ribbon…...

    2024/4/26 8:22:40
  8. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

    一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;…...

    2024/4/26 11:10:01
  9. VB.net WebBrowser网页元素抓取分析方法

    在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…...

    2024/4/25 16:50:01
  10. 【Objective-C】Objective-C汇总

    方法定义 参考&#xff1a;https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...

    2024/4/25 13:02:58
  11. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

    &#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格…...

    2024/4/26 0:25:04
  12. 【ES6.0】- 扩展运算符(...)

    【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

    2024/4/26 6:06:14
  13. 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?

    文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕&#xff0c;各大品牌纷纷晒出优异的成绩单&#xff0c;摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称&#xff0c;在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁&#xff0c;多个平台数据都表现出极度异常…...

    2024/4/26 17:59:13
  14. Go语言常用命令详解(二)

    文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令&#xff0c;这些命令可以帮助您在Go开发中进行编译、测试、运行和…...

    2024/4/26 22:35:59
  15. 用欧拉路径判断图同构推出reverse合法性:1116T4

    http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b&#xff0c;我们在 a i a_i ai​ 和 a i 1 a_{i1} ai1​ 之间连边&#xff0c; b b b 同理&#xff0c;则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然&#xff0…...

    2024/4/26 17:00:23
  16. 【NGINX--1】基础知识

    1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息&#xff0c;并安装一些有助于配置官方 NGINX 软件包仓库的软件包&#xff1a; apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...

    2024/4/25 17:42:40
  17. Hive默认分割符、存储格式与数据压缩

    目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限&#xff08;ROW FORMAT&#xff09;配置标准HQL为&#xff1a; ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

    2024/4/26 9:43:47
  18. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

    文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…...

    2024/4/26 9:43:47
  19. --max-old-space-size=8192报错

    vue项目运行时&#xff0c;如果经常运行慢&#xff0c;崩溃停止服务&#xff0c;报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中&#xff0c;通过JavaScript使用内存时只能使用部分内存&#xff08;64位系统&…...

    2024/4/27 1:03:20
  20. 基于深度学习的恶意软件检测

    恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞&#xff0c;例如可以被劫持的合法软件&#xff08;例如浏览器或 Web 应用程序插件&#xff09;中的错误。 恶意软件渗透可能会造成灾难性的后果&#xff0c;包括数据被盗、勒索或网…...

    2024/4/27 3:22:12
  21. JS原型对象prototype

    让我简单的为大家介绍一下原型对象prototype吧&#xff01; 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定&#xff0c;每一个构造函数都有一个 prototype 属性&#xff0c;指向另一个对象&#xff0c;所以我们也称为原型对象…...

    2024/4/26 21:29:56
  22. C++中只能有一个实例的单例类

    C中只能有一个实例的单例类 前面讨论的 President 类很不错&#xff0c;但存在一个缺陷&#xff1a;无法禁止通过实例化多个对象来创建多名总统&#xff1a; President One, Two, Three; 由于复制构造函数是私有的&#xff0c;其中每个对象都是不可复制的&#xff0c;但您的目…...

    2024/4/25 17:31:15
  23. python django 小程序图书借阅源码

    开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索图书&#xff0c;轮播图&#xff0…...

    2024/4/26 23:53:24
  24. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

    C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...

    2024/4/26 9:43:45
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57