建议UML和设计模式去听听课,内容多,还需要记。这一部分内容较多
该博客不适合学习UML和设计模式,只适合考试。要学的不要在这浪费时间,切记切记
一、面向对象基础
面向过程和面向对象
面向过程:就像人。
面向对象:就像会魔法的魔仙。
例子
比如:刷碗这个动作。
面向过程(人):人将碗从桌子上拿到水池,拧开水龙头,用百洁布擦拭,倒入洗洁精,冲水,看到干净了就OK了
面向对象(魔仙):用魔法棒控制,碗从桌子上飞到水池中,水龙头拧开,百洁布自动擦拭,洗洁精飞起倒入,碗感觉自己干净了就OK了。
其中包含的对象和对象的方法:
碗: 飞起、落地、检查自身状态
水龙头:关闭、打开
百洁布:擦拭
洗洁精:飞起、倾倒
开发人员调用碗、水龙头、百洁布、洗洁精的方法实现刷碗这个动作。
(一)基本概念
面向对象 = 对象+分类+继承+通过消息的通信
1、类
类是对象的抽象
(1) 类别
- 实体类:实体类的对象表示现实世界中真实的实体
- 接口类(边界类):接口类的对象为用户提供一种与系统合作交互的方式,分为人和系统两种。
- 控制类:控制活动流,充当协调者
2、对象
由对象名、属性和方法三个部分组成。
是类的实例,既包括数据(属性或状态或成员变量),也包括作用于数据的操作(行为或方法或函数或成员函数)
3、消息
对象间进行通信的一种构造 。当一个消息发送给某个对象时,包含要求对象去执行某些活动的信息。接收到信息的对象经过解释,然后予以响应。这种通信机制叫做消息传递
4、方法重载(也叫操作、行为、函数)
- 同一个方法名,参数名不同
- 同一个方法名,参数类型不同
- 同一个方法名,参数顺序不同
5、三大特征
封装、继承、多态
(1)封装
封装是一种信息隐藏技术,实现对象的使用者和生产者分离。
对象是封装数据和行为的整体
数据和行为可声明为private(私有)和public(共有),声明为private的方法或属性只能在当前类中定义的方法中被访问到。
关键字this可以用于区分同名的对象属性和局部变量名。
(2)继承
父类、超类、基类
子类、派生类
父类和子类共享数据和方法的机制。子类是父类的特例,一个父类可以有多个子类,父类已有的非私有化属性和方法在子类中不必定义,可直接使用,子类可有自己的属性和方法。同一个方法名可在子类中被重写(覆盖),也就相当于方法重载。
单重继承:子类只继承一个父类
多重继承:子类继承多个父类,可能造成子类中出现二义性的成员
(3)多态
收到消息时,对象要予以响应。不同对象收到同一消息可以完全产生不同的结果,这一现象称为多态,由继承机制来支持,实现细节由接收对象自行决定。动态绑定是实现多态的基础
Person gll = new Student();
编译:编译时gll类为Person
运行:运行时gll类为Student
多态的不同形式(考的多)
6、动态绑定、静态绑定
绑定是一个把过程调用和响应调用所需要执行的代码加以结合的过程。一般的程序设计语言中,编译时进行静态绑定,运行时进行动态绑定。一个给定的过程调用和代码的结合直到调用发生时才进行
(二)面向对象分析(按顺序的,背)–OOA
(三)面向对象设计 – OOD
目标:定义系统的构造蓝图。理解解决方案,实现系统
1、面向对象设计的原则 (常考,背)
2、面向对象设计的活动
(四)面向对象程序设计
程序设计语言相关,下午题中记录
(五)面向对象测试
(六)其他知识点
- 静态方法只能访问同一类中的静态数据成员
- 静态数据成员可被同一类中的所有方法访问
- 同一类的对象共享静态数据成员的值。
- 静态数据成员的值可修改
- 面向对象技术中,对象拥有清晰的边界、良好的定义行为和可扩展性三个特性
- 领域类模型包含属性、操作、关联
二、UML(上午题3~5分,下午题15分)
UML(统一建模语言),构造块包含事物、关系、图。事物是对模型中最具有代表性的成分的抽象;关系把事物结合在一起;图聚集了相关事物。
(一)事物
各结构事物的图形化
各行为事物的图形表示
包和注解的图形表示
(二)关系
依赖关系图示
关联关系、聚合关系、组合关系图示
两个类之间可以有多个由不同角色标识的关联。
关联的多重度(重复度)指:一个类的实例能够被另一个类的多少实例相关联。
关联关系可不标注多重度和角色,若为实线单向箭头,则表示是单向关联(类似依赖,但是比依赖的强度要强。人依赖于食物活着,但不是时时刻刻需要;鱼单向关联水,需要时时刻刻在水中)。
下面关联代表的意思是:一个雇主对应0个或多个雇员,一个雇员对应0个或一个雇主。
当两个类关联,A类的实例重复关联B类的实例时,衍生出一个属性,放在这两个类中都不妥时,就定义一个关联类。
泛化关系图示
实现关系图示
(三)图
图:一组元素的图形表示,大多数情况下把图画成顶点(代表事物)和弧(代表关系)的连通图。
1、图的分类
(1) 类图补充
类
(2) 对象图补充(下午没考过)
对象
(3) 用例图补充(下午题常考,加油)
(4)交互图介绍
用于对系统的动态方面进行建模。一张交互图表现的是一个交互,由一组对象和他们之间的关系组成,包含传递的消息。包含序列图、通信图、交互概览图和计时图。序列图是强调消息时间顺序的交互图;通信图是强调接收和发送消息的对象的结构组织的交互图。一般包含对象、链和消息。
(5)序列图(也叫顺序图)
(6)通信图(协作图)
路径这一特点未在图中表现出来
(7)状态图(常考)
由状态、活动、转换、事件组成,分别介绍
状态和活动
转换和事件
(8)活动图(不常考)
状态图:从一个状态到另一个状态
活动图:从一个活动到另一个活动
(9)构件图(不常考)
(10)部署图(不常考)
2、图总结
UML构造块组织结构图附件
附件中是UML部分的全部结构图,本人使用的工具是 XMIND 。
三、设计模式
(一) 创建型模式设计
简单工厂模式(引入,便于后续,不在23种设计模式之内)
/**
* 简单工厂模式。以在饺子馆买饺子为例
*/
// main方法
public class SimpleFactory {
public static void main(String[] args) {
Product A = Factory.createProduct("A");
A.info();
Product B = Factory.createProduct("B");
B.info();
Product C = Factory.createProduct("C");
C.info();
}
}
// 工厂类,可直接被外界访问。该类相当于饺子馆,type为客户需求的饺子馅
class Factory {
public static Product createProduct(String type) {
Product product = null;
switch(type) {
case "A":
product = new ProductA();
break;
case "B":
product = new ProductB();
break;
default:
System.out.println("产品生产完成");
break;
}
return product;
}
}
// 抽象的产品类,不可被实例化,为父类。相当于饺子,但不知道是什么馅
abstract class Product {
public abstract void info();
}
// 具体的产品类,为子类。相当于韭菜馅饺子,是一个确定的个体了
class ProductA extends Product {
@Override
public void info() {
System.out.println("此为A产品");
}
}
// 具体的产品类,为子类。相当于猪肉大葱馅饺子,是一个确定的个体了
class ProductB extends Product {
@Override
public void info() {
System.out.println("此为B产品");
}
}
1、类模式
(1) 工厂方法模式(一个工厂只能创建一类产品)
/**
* 工厂方法模式。以手机零件生产工厂为例
*/
public class FactoryMethod {
public static void main(String[] args) {
Factory1A factory1A = new Factory1A();
Product1 product1A = factory1A.createProduct();
product1A.info();
Factory1B factory1B = new Factory1B();
Product1 product1B = factory1B.createProduct();
product1B.info();
}
}
/**
* 工厂类
*/
// 工厂父类。相当于工厂的管理部门,只知道要生产零件
interface Factory1 {
public Product1 createProduct();
}
// 工厂子类。相当于手机屏生产车间,明确知道自己的工作,且只做这份工作,不接受外来消息的影响
class Factory1A implements Factory1 {
@Override
public Product1 createProduct() {
return new Product1A();
}
}
// 工厂子类。相当于充电器生产车间,明确知道自己的工作,且只做这份工作,不接受外来消息的影响
class Factory1B implements Factory1 {
@Override
public Product1 createProduct() {
return new Product1B();
}
}
// 产品父类。相当于手机
interface Product1 {
public void info();
}
// 产品子类,相当于手机屏,明确知道自己是什么零件
class Product1A implements Product1 {
@Override
public void info() {
System.out.println("此为工厂方法的A产品");
}
}
// 产品子类,相当于充电器,明确知道自己是什么零件
class Product1B implements Product1 {
@Override
public void info() {
System.out.println("此为工厂方法的B产品");
}
}
2、对象模式
(1) 抽象工厂模式(一个工厂只能创建多类产品)
/**
* 抽象工厂模式
*/
public class AbstractFactory {
public static void main(String[] args) {
// 创建工厂子类A实例
ConcreateFactoryA concreateFactoryA = new ConcreateFactoryA();
AbstractProductA abstractProductA1 = concreateFactoryA.createAbstractProductA();
abstractProductA1.info();
AbstractProductB abstractProductB1 = concreateFactoryA.createAbstractProductB();
abstractProductB1.info();
// 创建工厂子类B实例
ConcreateFactoryB concreateFactoryB = new ConcreateFactoryB();
AbstractProductA abstractProductA2 = concreateFactoryB.createAbstractProductA();
abstractProductA2.info();
AbstractProductB abstractProductB2 = concreateFactoryB.createAbstractProductB();
abstractProductB2.info();
}
}
// 工厂父类
interface FactoryAbstract {
public AbstractProductA createAbstractProductA();
public AbstractProductB createAbstractProductB();
}
// 具体的工厂,工厂子类A,可生产两类产品,且这两类不相关
class ConcreateFactoryA implements FactoryAbstract {
@Override
public AbstractProductA createAbstractProductA() {
return new ProductA1();
}
@Override
public AbstractProductB createAbstractProductB() {
return new ProductB1();
}
}
// 具体的工厂,工厂子类B,可生产两类产品,且这两类不相关
class ConcreateFactoryB implements FactoryAbstract {
@Override
public AbstractProductA createAbstractProductA() {
return new ProductA2();
}
@Override
public AbstractProductB createAbstractProductB() {
return new ProductB2();
}
}
// 产品父类A
interface AbstractProductA {
public void info();
}
// 产品父类A的子类
class ProductA1 implements AbstractProductA {
@Override
public void info() {
System.out.println("此为ProductA1");
}
}
// 产品父类A的子类
class ProductA2 implements AbstractProductA {
@Override
public void info() {
System.out.println("此为ProductA2");
}
}
// 产品父类B
interface AbstractProductB {
public void info();
}
// 产品父类B的子类
class ProductB1 implements AbstractProductB {
@Override
public void info() {
System.out.println("此为ProductB1");
}
}
// 产品父类B的子类
class ProductB2 implements AbstractProductB {
@Override
public void info() {
System.out.println("此为ProductB2");
}
}
(2) 生成器模式
/**
* 生成器模式。以卖手机为例,有各种套餐
*/
public class BuilderMode {
public static void main(String[] args) {
Director director = new Director();
Builder1 builder1 = new Builder1();
director.Construct(builder1);
ProductBuilder product1 = builder1.getResult();
product1.show();
Builder2 builder2 = new Builder2();
director.Construct(builder2);
ProductBuilder product2 = builder2.getResult();
product2.show();
}
}
// 相当于客户,指定需要哪种套餐
class Director {
public void Construct(Builder builder) {
builder.BuildPart();
}
}
// 生成器父类。相当于手机套餐配送前的装箱小组
abstract class Builder {
public abstract void BuildPart();
public abstract ProductBuilder getResult();
}
// 生成器子类。相当于装箱小组中的成员1
class Builder1 extends Builder {
// 此时为还不知道套餐是什么的产品
ProductBuilder product = new ProductBuilder();
@Override
public void BuildPart() {
product.Add("手机");
product.Add("充电头");
product.Add("充电线");
}
@Override
public ProductBuilder getResult() {
return product;
}
}
// 生成器子类。相当于装箱小组中的成员2
class Builder2 extends Builder {
// 此时为还不知道套餐是什么的产品
ProductBuilder product = new ProductBuilder();
@Override
public void BuildPart() {
product.Add("手机");
product.Add("手环");
product.Add("耳机");
}
@Override
public ProductBuilder getResult() {
return product;
}
}
// 产品。相当于手机产品,里面有套餐数组
class ProductBuilder {
List<String> parts = new ArrayList<String>(); // 手机部件
// 向套餐中添加配件
public void Add(String part) {
parts.add(part);
}
public void show() {
System.out.println("产品包含:");
for (String part:parts
) {
System.out.println(part+",");
}
System.out.println("\n");
}
}
(3) 原型模式
/**
* 原型模式
*/
public class PrototypeMode {
public static void main(String[] args) {
ProductPrototype product1 = new ProductPrototype(2023, 5.28);
System.out.println(product1.getId()+"/"+product1.getPrice());
ProductPrototype product2 = product1.Clone();
System.out.println(product2.getId()+"/"+product2.getPrice());
}
}
// 类原型父类
interface Prototype {
public Object Clone();
}
// 类原型子类,意思是直接复制这个类创建的一个实例
class ProductPrototype implements Prototype {
private int id;
private double price;
// 构造函数
public ProductPrototype() {}
public ProductPrototype(int id,double price) {
this.id = id;
this.price = price;
}
public int getId() {
return id;
}
public double getPrice() {
return price;
}
@Override
public ProductPrototype Clone() {
ProductPrototype productPrototype = new ProductPrototype();
productPrototype.id = this.id;
productPrototype.price = this.price;
return productPrototype;
}
}
(4) 单例模式
/**
* 单例模式
*/
public class SingletonPattern {
public static void main(String[] args) {
// Singleton singleton1 = new Singleton(); // 这样会报错
// 下面的其实都是一个实例
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
Singleton instance3 = Singleton.getInstance();
System.out.println(instance1.getNumber()+"/"+instance2.getNumber()+"/"+instance3.getNumber());
instance1.setNumber(22222);
System.out.println(instance1.getNumber()+"/"+instance2.getNumber()+"/"+instance3.getNumber());
}
}
class Singleton {
private int number = 2023;
public void setNumber(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
private Singleton(){} // 设为私有,可保证只能通过全局访问点访问唯一的实例
private static Singleton instance = new Singleton();
public static Singleton getInstance(){
return instance;
}
}
(二) 结构型模式设计
1、类模式
(1) 适配器模式(不常考,可不看)
2、对象模式
(1) 适配器模式(一般考对象适配器模式)
/**
* 适配器模式。相当于转接头,此处以typec接口转USB接口为例
*/
public class AdapterPattern {
public static void main(String[] args) {
Target target = new Adapter();
target.Request();
}
}
// 最终需要的类。相当于USB口
class Target {
public void Request() {
System.out.println("我是目标类");
}
}
// 适配转换的类。相当于转接头,披着羊皮的狼。我外表是目标类,实际内心是现有的不匹配的类
class Adapter extends Target {
private Adaptee adaptee = new Adaptee();
@Override
public void Request() {
adaptee.specificRequest();
}
}
// 现有的类。与需要的类不同。相当于Typec接口
class Adaptee {
public void specificRequest() {
System.out.println("我是特殊的,需要转换一下的类");
}
}
(2) 桥接模式
/**
* 桥接模式。理解的意思就像是生产手机,可生产的机型可以有多种,手机的颜色可以有多种上色选择。
* 任意一种机型可以上各种不同的颜色。就是将两个都可实现的方法任意组合起来
*/
public class BridgePattern {
public static void main(String[] args) {
Abstraction abstractionA1 = new AbstractionA();
Abstraction abstractionA2 = new AbstractionA();
Implementor implementor1 = new Implementor1();
Implementor implementor2 = new Implementor2();
abstractionA1.setName("iphone 12");
abstractionA1.setImplementor(implementor1);
abstractionA1.Operation();
abstractionA2.setName("iphone 13");
abstractionA2.setImplementor(implementor2);
abstractionA2.Operation();
}
}
// 抽象父类
abstract class Abstraction {
private String name;
protected Implementor implementor;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setImplementor(Implementor implementor) {
this.implementor = implementor;
}
public abstract void Operation();
}
// 抽象子类。使用implementor类实现最终的操作
class AbstractionA extends Abstraction {
@Override
public void Operation() {
implementor.OperationImp(this.getName());
}
}
// 实现类接口父类
interface Implementor {
public void OperationImp(String name);
}
// 实现类接口子类
class Implementor1 implements Implementor {
@Override
public void OperationImp(String name) {
System.out.println(name+":涂为乳白色");
}
}
// 实现类接口子类
class Implementor2 implements Implementor {
@Override
public void OperationImp(String name) {
System.out.println(name+":涂为天蓝色");
}
}
(3) 组合模式
/**
* 组合模式,以树形结构展示部分-整体。此处以文件夹中包含文件、文件夹为例
*/
public class CompositePattern {
public static void main(String[] args) {
Component root = new Composite("root");
Component folderA = new Composite("folderA");
Component fileA = new Leaf("fileA");
Component folderB = new Composite("folderB");
Component fileB = new Leaf("fileB");
Component fileC = new Leaf("fileC");
Component fileD = new Leaf("fileD");
root.Add(folderA);
root.Add(fileA);
root.Add(folderB);
folderA.Add(fileB);
folderA.Add(fileC);
folderB.Add(fileD);
print(root);
}
// 该方法可打印某节点的所有儿子、孙子、重孙....后代们
static void print(Component com) {
com.printName();
List<Component> childrenList = com.getChildren();
if(childrenList == null) return;
for (Component children: childrenList
) {
// 递归
print(children);
}
}
}
// 父类
abstract class Component {
protected String name;
// 可打印当前结点的名称
public void printName() {
System.out.println(name);
};
public abstract boolean Add(Component com); // 此处的参数设为父类,可保证叶子结点和非叶子节点中都可正常使用
// 对应意图中的 “Composite使得用户对单个对象和组合对象的使用具有一致性”
public abstract boolean Remove(Component com);
public abstract List<Component> getChildren();
}
// 子类叶子结点。相当于文件,文件中不可再有文件或文件夹
class Leaf extends Component {
public Leaf(String name) {
this.name = name;
}
// 叶子结点不能有儿子了,所以直接在添加子节点的时候返回了false
@Override
public boolean Add(Component com) {
return false;
}
@Override
public boolean Remove(Component com) {
return false;
}
@Override
public List<Component> getChildren() {
return null;
}
}
// 子类可有子节点的节点。相当于文件夹,文件夹中还可添加文件或者文件夹
class Composite extends Component {
// 因为有多个儿子,所以此处用一个list来保存所有的儿子.
// 此处使用Component,是与上面方法的定义呼应的
List<Component> childrenList = new ArrayList<Component>();
public Composite(String name) {
this.name = name;
}
@Override
public boolean Add(Component com) {
return childrenList.add(com);
}
@Override
public boolean Remove(Component com) {
return childrenList.remove(com);
}
@Override
public List<Component> getChildren() {
return childrenList;
}
}
(4) 装饰器模式
/**
* 装饰器模式。在已有的基础上给你增加工作量
*/
public class DecoratorPattern {
public static void main(String[] args) {
ComponentDecorator you = new ConcreteComponent("老黄牛");
you.Operation(); // 本身已有的职责
// 添加职责
you = new DecoratorA(you); // 因为大boss都是ComponentDecorator,所有直接用you来接收,这样操作的就都是老黄牛
you.Operation();
}
}
// 父类,大boss,其他类都是它的儿子或孙子
abstract class ComponentDecorator {
protected String name;
public abstract void Operation();
}
// 子类,作用是保存已有的职责
class ConcreteComponent extends ComponentDecorator {
public ConcreteComponent(String name) {
this.name = name;
}
@Override
public void Operation() {
System.out.println(name+"的职责:写一个列表页面");
}
}
// 装饰器。其实就是为你添加工作量的领导,具体领导是谁还不确定
abstract class Decorator extends ComponentDecorator {
protected ComponentDecorator componentDecorator;
}
// 装饰器子类。给你添加工作量的领导之一,可以有千千万万个这样的领导
class DecoratorA extends Decorator {
public DecoratorA(ComponentDecorator componentDecorator) {
this.componentDecorator = componentDecorator;
}
@Override
public void Operation() {
componentDecorator.Operation(); // 已有的职责
System.out.println("为其添加职责 ");
}
}
(5) 外观模式
/**
* 外观模式。相当于一个大工厂,工厂的管理人员知道哪个部门生产什么部件
*/
public class FacadePattern {
public static void main(String[] args) {
Facade facade = new Facade();
facade.Method1();
facade.Method2();
facade.Method3();
}
}
// 工厂对外的大门
class Facade {
SubsystemA subsystemA;
SubsystemB subsystemB;
SubsystemC subsystemC;
public Facade() {
subsystemA = new SubsystemA();
subsystemB = new SubsystemB();
subsystemC = new SubsystemC();
}
public void Method1() {
subsystemA.MethodA();
}
public void Method2() {
subsystemB.MethodB();
}
public void Method3() {
subsystemC.MethodC();
}
}
// 子系统。工厂内部部门
class SubsystemA {
public void MethodA() {
System.out.println("子系统A的方法");
}
}
// 子系统。工厂内部部门
class SubsystemB {
public void MethodB() {
System.out.println("子系统B的方法");
}
}
// 子系统。工厂内部部门
class SubsystemC {
public void MethodC() {
System.out.println("子系统C的方法");
}
}
(6) 享元模式
/**
* 享元模式。已有多个白色石块了,但是客户要彩色的,无需再次生产,直接将石块喷上各种颜色的漆就可以。
* 内部状态:石块大小、石块位置
* 外部状态:石块颜色
*
* 此处以圆形包含各种颜色的为例
*/
public class FlyweightPattern {
public static void main(String[] args) {
FlyweightFactory flyweightFactory = new FlyweightFactory();
Random random = new Random();
String[] colors = {"red","green","blue","pink","black"};
for (int i = 0; i < 20; i++) {
int x = random.nextInt(colors.length); // 区间是[0,5)
Flyweight flyweight = flyweightFactory.getFlyweight(colors[x]);
System.out.println("第"+i+"个圆");
flyweight.draw(random.nextInt(2222), random.nextInt(3333) );
}
}
}
// 享元工厂。保存各种对象的仓库
class FlyweightFactory {
private Map<String,Flyweight> map = new HashMap<String,Flyweight>(); // 用map来保存颜色以及圆本身
// map里面已有了红色的圆之后,就不再生成了,直接返回;否则,生成保存到map中再返回
public Flyweight getFlyweight(String key) {
if(!map.containsKey(key)) {
Flyweight concreteFlyweight = new ConcreteFlyweight(key);
map.put(key,concreteFlyweight);
System.out.println("创建了一个"+key+"色的圆");
}
return map.get(key);
}
}
//享元父类
abstract class Flyweight {
protected String color;
public abstract void draw(int x,int y); // 画圆,标明位置
}
// 享元子类。具体的享元
class ConcreteFlyweight extends Flyweight {
public ConcreteFlyweight(String color){
this.color = color;
}
@Override
public void draw(int x, int y) {
System.out.println("画一个颜色为"+color+"的圆,位置是x: "+x+" y: "+y);
}
}
(7) 代理模式
/**
* 代理模式。例如代购、律师。此处以代购为例
*/
public class ProxyPattern {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Proxy proxy = new Proxy(realSubject);
proxy.buy();
}
}
interface Subject {
public void buy();
}
class Proxy implements Subject {
public RealSubject realSubject;
public Proxy(RealSubject realSubject){
this.realSubject = realSubject;
}
@Override
public void buy() {
System.out.println("找到商品");
System.out.println("讨价还价");
realSubject.buy(); // 实际的买主付钱
}
}
class RealSubject implements Subject {
@Override
public void buy() {
System.out.println("付款");
}
}
(三) 行为模式设计
1、类模式
(1) 解释器模式
/**
* 解释器模式。说实话,没听太懂,不理解什么情境下能用到。感觉作用就是做了个判断
*/
public class InterpreterPattern {
public static void main(String[] args) {
Context context = new Context();
context.check("朝阳区的开发人员");
context.check("昌平区的测试人员");
context.check("东城区的闲散人员");
}
}
class Context {
private String[] regions = {"朝阳区","东城区","西城区","丰台区"};
private String[] persons = {"开发人员","测试人员","行政人员","审计人员"};
private NonterminalExpression nonterminalExpression;
public Context() {
TerminalExpression region = new TerminalExpression(regions);
TerminalExpression person = new TerminalExpression(persons);
nonterminalExpression = new NonterminalExpression(region,person);
}
public void check(String info) {
boolean bool = nonterminalExpression.Interprete(info);
if(bool) {
System.out.println("识别成功");
}else {
System.out.println("识别失败");
}
}
}
interface Expression {
public boolean Interprete(String info);
}
class NonterminalExpression implements Expression {
private TerminalExpression region;
private TerminalExpression person;
public NonterminalExpression(TerminalExpression region,TerminalExpression person) {
this.region = region;
this.person = person;
}
@Override
public boolean Interprete(String info) {
String[] str = info.split("的");
return region.Interprete(str[0]) && person.Interprete(str[1]);
}
}
class TerminalExpression implements Expression {
private Set<String> set = new HashSet<>();
public TerminalExpression(String[] data) {
for (String str:data
) {
set.add(str);
}
}
@Override
public boolean Interprete(String info){
return set.contains(info);
}
}
(2) 模板方法模式
package module;
/**
* 模板方法模式。将相同处理提取出来,根据子类的不同为其执行不同的操作。
* 此处以老师和学生上下课为例
*/
public class TemplateMethodPattern {
public static void main(String[] args) {
Person student = new Student();
Person teacher = new Teacher();
student.TemplateMethod();
teacher.TemplateMethod();
}
}
// 父类,具有相同的操作
abstract class Person {
public void TemplateMethod() {
System.out.println("上课,去教室");
PrimitiveOperation1();
System.out.println("下课,离开教室");
PrimitiveOperation2();
}
public abstract void PrimitiveOperation1(); // 原语操作1:老师--讲课;学生--听课
public abstract void PrimitiveOperation2(); // 原语操作2:老师--布置作业(老师都是下课的时候再布置作业吧);学生--写作业
}
class Student extends Person {
@Override
public void PrimitiveOperation1() {
System.out.println("学生:听课,打盹");
}
@Override
public void PrimitiveOperation2() {
System.out.println("学生:写作业,抄作业");
}
}
class Teacher extends Person {
@Override
public void PrimitiveOperation1() {
System.out.println("老师:讲课,抓打盹的学生");
}
@Override
public void PrimitiveOperation2() {
System.out.println("老师:批改作业,抓抄作业的学生");
}
}
2、对象模式
(1) 责任链模式
/**
* 责任链模式。类似审批流、也可以理解为连带责任。各处理对象间有条隐形的链。
* 此处以请假审批流为例
*/
public class ChainOfResponsibilityPattern {
public static void main(String[] args) {
Handler concreteHandler1 = new ConcreteHandler1();
Handler concreteHandler2 = new ConcreteHandler2();
concreteHandler1.setNext(concreteHandler2);
concreteHandler1.HandleRequest(8);
}
}
// 处理类父类
abstract class Handler {
protected Handler next; // 我处理不了,要将这个请求转给next
public void setNext(Handler next){
this.next = next;
}
abstract public void HandleRequest(int request);
}
// 处理类子类。明确知道了谁处理了我的请求,我处理不了,就给ConcreteHandler2
// 可以理解成甩锅,这锅我背不了,甩给另一个。
class ConcreteHandler1 extends Handler{
@Override
public void HandleRequest(int request) {
if(request <=7){
System.out.println("ConcreteHandler1 审批通过");
}else {
if(next != null){
next.HandleRequest(request);
}else {
System.out.println("无法审批");
}
}
}
}
// 处理类子类。明确知道了谁处理了我的请求,我处理不了,就给ConcreteHandler2
class ConcreteHandler2 extends Handler {
@Override
public void HandleRequest(int request) {
if(request < 20){
System.out.println("ConcreteHandler2 审批通过");
}else {
if(next != null){
next.HandleRequest(request);
}else {
System.out.println("无法审批");
}
}
}
}
(2) 命令模式
/**
* 命令模式。此处以遥控器发出命令控制电视机的开关为例
*/
public class CommandPattern {
public static void main(String[] args) {
Receiver receiver = new Receiver();
Command commandOne = new CommandOne(receiver);
Command commandTwo = new CommandTwo(receiver);
Invoker invoker = new Invoker();
// 开机操作
invoker.setCommand(commandOne);
invoker.call();
// 关机操作
invoker.setCommand(commandTwo);
invoker.call();
}
}
// 请求者。类似遥控器
class Invoker {
private Command command;
public void setCommand(Command command){
this.command = command;
}
public void call() {
command.Execute();
}
}
// 命令接口
interface Command {
public void Execute();
}
// 明确的命令1
class CommandOne implements Command {
private Receiver recevier;
public CommandOne(Receiver recevier){
this.recevier = recevier;
}
@Override
public void Execute() {
recevier.open();
}
}
// 明确的命令2
class CommandTwo implements Command {
private Receiver recevier;
public CommandTwo(Receiver recevier){
this.recevier = recevier;
}
@Override
public void Execute() {
recevier.close();
}
}
// 命令的接收者。类似于电视机
class Receiver {
public void open() {
System.out.println("开机操作");
}
public void close() {
System.out.println("关机操作");
}
}
(3) 迭代器模式
package module;
import javax.swing.text.html.HTMLDocument;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
public class IteratorPattern {
public static void main(String[] args) {
List<Book> bookList = new ArrayList<>(); // 聚合对象
String[] bookName = {"大学英语", "C语言", "java编程语言", "高等数学"};
double[] bookPrice = {10, 20, 30, 40};
// 向聚合对象中添加值
for (int i = 0; i < 4; i++) {
bookList.add(new Book(bookName[i], bookPrice[i]));
}
// 获取聚合对象中的值
// 方法一:
for (int i = 0; i < bookList.size(); i++) {
Book book1 = bookList.get(i);
System.out.println(book1.getName() + " " + book1.getPrice());
}
// 方法二:
System.out.println("==============");
for (Book book2 : bookList
) {
System.out.println(book2.getName() + " " + book2.getPrice());
}
// 方法三:
System.out.println("==============");
Iterator iterator = (Iterator) bookList.iterator();
// 只要有下一个,就输出它的内容
while (iterator.hasNext()) {
Book book3 = (Book) iterator.next();
System.out.println(book3.getName() + " " + book3.getPrice());
}
Iterator iterator1 = (Iterator) bookList.iterator();
Object next = iterator1.next(); // 此时返回的就是个Object类型,需要强制转换
Book bookNext = (Book) iterator1.next();
// 自己实现迭代器调用
BookAggregate bookAggregate = new BookAggregate();
for (int i = 0;i<4;i++){
bookAggregate.Add(new Book(bookName[i],bookPrice[i]));
}
Iterator1 bookIterator11 = bookAggregate.CreateIterator();
while(bookIterator11.hasNext()){
Book book2 = (Book) bookIterator11.next();
System.out.println(book2.getName()+" "+book2.getPrice());
}
}
}
/**
* 迭代器的实现
*/
// 迭代器父类
interface Iterator1 {
public boolean hasNext();
public Object next();
}
// 迭代器子类
class BookIterator implements Iterator1 {
private int index;
private BookAggregate bookAggregate;
public BookIterator(BookAggregate bookAggregate) {
this.index = 0;
this.bookAggregate = bookAggregate;
}
@Override
public boolean hasNext() {
if(index < bookAggregate.getSize()){
return true;
}
return false;
}
@Override
public Object next() {
Object obj = bookAggregate.get(index);
index++;
return obj;
}
}
// 聚合对象父类
interface Aggregate {
public Iterator1 CreateIterator();
}
// 聚合对象子类
class BookAggregate implements Aggregate {
private List<Book> list = new ArrayList<Book>();
public void Add(Book book) {
list.add(book);
}
public Book get(int index) {
return list.get(index);
}
public int getSize() {
return list.size();
}
@Override
public Iterator1 CreateIterator() {
return new BookIterator(this);
}
}
class Book {
private String name;
private double price;
public Book(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
}
(4) 中介者模式
package module;
/**
* 中介者模式,相当于一个传话筒,
* 随着交流的人增多,人与人之间的联系就会变得复杂,就像现在你的朋友,我的朋友一起玩,要互相都能联系到,就需要逐个添加微信
* 中介者就相当于我们直接建个群,在群里说话。不需要每个人都互相加微信。
*/
public class MediatorPattern {
public static void main(String[] args) {
// 编译看左边,运行看右边
ConcreteMediator mediator = new ConcreteMediator();
Colleague1 colleague1 = new Colleague1(mediator);
Colleague2 colleague2 = new Colleague2(mediator);
mediator.setColleague1(colleague1);
mediator.setColleague2(colleague2);
colleague1.sendMessage("你好,我是colleague1,很高兴认识你");
colleague2.sendMessage("你好,我是colleague2,希望我们可以成为朋友");
}
}
// 同事类
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;
}
public void sendMessage(String message,Colleague colleague) {
// 判断发送者是不是同事1,是就发送给同事2,不是就发送给同事1
if(colleague == colleague1) {
colleague2.Notify(message);
}else {
colleague1.Notify(message);
}
}
}
(5) 备忘录模式
package module;
import java.util.ArrayList;
import java.util.List;
public class MementoPattern {
public static void main(String[] args) {
Caretaker caretaker = new Caretaker();
Originator originator = new Originator();
originator.setState("2023");
Memento memento1 = originator.createMemento();
caretaker.setMementoList(memento1);
originator.setState("2025");
Memento memento2 = originator.createMemento();
caretaker.setMementoList(memento2);
originator.setState("2027");
Memento memento3 = originator.createMemento();
caretaker.setMementoList(memento3);
// 第一次的状态
System.out.println(originator.getState());
caretaker.showMemento();
Memento mementoGet = caretaker.getMementoList(2);
originator.setMemento(mementoGet);
System.out.println("根据第二次备份还原后的状态为:"+originator.getState());
}
}
// 原发器
class Originator {
private String state;
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
public Memento createMemento() {
return new Memento(state);
}
public void setMemento(Memento memento) {
state = memento.getState();
}
}
// 备忘录
class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
// 管理者
class Caretaker {
private List<Memento> mementoList = new ArrayList<>();
public void setMementoList(Memento memento) {
mementoList.add(memento);
}
public Memento getMementoList(int index) {
return mementoList.get(index-1);
}
public void showMemento() {
int cnt =1;
for (Memento memento: mementoList
) {
System.out.println("第"+cnt+"次备份,备忘录状态为"+memento.getState());
// memento.
}
}
}
(6) 观察者模式
package module;
import java.util.ArrayList;
import java.util.List;
/**
* 观察者模式
*/
public class ObserverPattern {
public static void main(String[] args) {
SubjectSubject subjectSubject = new ConcreteSubject("目标");
Observer observer1 = new ConcreteObserver("嘟嘟", subjectSubject);
Observer observer2 = new ConcreteObserver("喔喔", subjectSubject);
Observer observer3 = new ConcreteObserver("呦呦", subjectSubject);
// System.out.println("目标状态发生改变");
subjectSubject.setState("状态更新");
// subjectSubject.Notify();
subjectSubject.Detach(observer3);
subjectSubject.setState("停更了");
}
}
// 目标接口
interface SubjectSubject {
public void Attach(Observer observer); // 添加观察者
public void Detach(Observer observer); // 删除观察者
public void Notify(); // 状态变更后生成通知
public void setState(String state); // 设置状态
public String getState(); // 获取状态
}
class ConcreteSubject implements SubjectSubject {
private String state;
private String name;
private List<Observer> observerList;
public ConcreteSubject(String name) {
state = "未更新";
this.name = name;
observerList = new ArrayList<>();
}
public void setState(String state) {
this.state = state;
System.out.println(name+"的状态发生变化,变化后的状态为"+state);
Notify();
}
public String getState() {
return state;
}
public void Attach(Observer observer){
observerList.add(observer);
}
public void Detach(Observer observer){
observerList.remove(observer);
}
public void Notify() {
for (Observer obs : observerList
) {
obs.update();
}
}
}
// 观察者接口
interface Observer {
// 收到通知,更新观察者状态
public void update();
}
class ConcreteObserver implements Observer {
private String state;
private String name;
private SubjectSubject subject;
public ConcreteObserver(String name,SubjectSubject subject) {
this.name = name;
this.subject = subject;
this.state = subject.getState();
subject.Attach(this);
}
@Override
public void update() {
System.out.println(name +"收到通知");
state = subject.getState();
System.out.println("改变后的状态为:"+state);
}
}
(7) 状态模式
package module;
/**
* 状态模式
* 不知道前端的watch有没有受到这种设计模式的影响,个人感觉两者还是有共通之处。
* 前端可将任意一个属性当做监听对象,当其发生变化,根据自身状态值,决定需要执行的操作
*
* 此处以贩卖机为例,状态为有货和无货
*/
public class StatePattern {
public static void main(String[] args) {
ContextEnv contextEnv = new ContextEnv();
contextEnv.request(); // 购买一瓶,count= 2
contextEnv.request(); // 购买一瓶,count= 1
contextEnv.request(); // 购买一瓶,count= 0
System.out.println(contextEnv.getState()); // 状态转为B,无货
contextEnv.request(); // 无货、补货成功
System.out.println(contextEnv.getState() + " "+ contextEnv.getCount());
contextEnv.request();
}
}
// 上下文,此处为贩卖机
class ContextEnv {
private int count;
private State state;
public ContextEnv() {
count = 3;
state = new StateA();
}
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;
}
// 购买饮料
public void request() {
state.Handle(this);
}
}
// 状态父类
interface State {
public void Handle(ContextEnv contextEnv);
}
// 有货
class StateA implements State {
@Override
public void Handle(ContextEnv contextEnv) {
int count = contextEnv.getCount();
if(count >= 1){
System.out.println("购买成功");
contextEnv.setCount(count -1);
if(contextEnv.getCount() == 0){
contextEnv.setState(new StateB());
}
}else {
System.out.println("购买失败");
}
}
}
// 无货
class StateB implements State {
@Override
public void Handle(ContextEnv contextEnv) {
int count = contextEnv.getCount();
if(count ==0){
System.out.println("库存不足,购买失败");
contextEnv.setCount(5);
System.out.println("补货成功,请重新购买");
contextEnv.setState(new StateA());
}
}
}
(8) 策略模式
package module;
/**
* 策略模式
*/
public class StrategyPattern {
public static void main(String[] args) {
AddStrategy addStrategy = new AddStrategy();
SubstractionStrategy substractionStrategy = new SubstractionStrategy();
MultiplyStrategy multiplyStrategy = new MultiplyStrategy();
OperationContext operationContext = new OperationContext(addStrategy);
operationContext.Operation(2023,807);
operationContext = new OperationContext(substractionStrategy);
operationContext.Operation(2023,807);
operationContext = new OperationContext(multiplyStrategy);
operationContext.Operation(2023,807);
}
}
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 SubstractionStrategy 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);
}
}
(9) 访问者模式
package module;
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);
System.out.println("学生年龄总和:"+visitor1.getStudentAgeSum()+" 老师年龄总和:"+visitor1.getTeacherWorkYearSum());
Visitor2 visitor2 = new Visitor2();
System.out.println("访问者2的访问记录:");
personStructure.Accept(visitor2);
System.out.println("学生最高成绩为:"+visitor2.getMaxScore()+" 老师最高工龄:"+visitor2.getMaxWorkYear());
}
}
interface Visitor {
public void VisitStudent(StudentVis student);
public void VisitTeacher(TeacherVis teacher);
}
// 访问者1:计算学生和老师的年龄总和
class Visitor1 implements Visitor {
private int studentAgeSum = 0;
private int teacherWorkYearSum = 0;
public int getStudentAgeSum() {
return studentAgeSum;
}
public int getTeacherWorkYearSum() {
return teacherWorkYearSum;
}
@Override
public void VisitStudent(StudentVis student) {
System.out.println("访问者1访问学生:" + student.getName()+" 年龄:"+student.getAge());
studentAgeSum += student.getAge();
}
@Override
public void VisitTeacher(TeacherVis teacher) {
System.out.println("访问者1访问老师:" + teacher.getName()+" 年龄:"+teacher.getAge());
teacherWorkYearSum += teacher.getAge();
}
}
// 访问者2:计算出学生最高成绩和老师最高工龄
class Visitor2 implements Visitor {
private int maxScore = -1;
private int maxWorkYear = -1;
public int getMaxScore() {
return maxScore;
}
public int getMaxWorkYear() {
return maxWorkYear;
}
@Override
public void VisitStudent(StudentVis student) {
System.out.println("访问者2访问学生:" + student.getName()+" 成绩:"+student.getScore());
maxScore = Math.max(maxScore,student.getScore());
}
@Override
public void VisitTeacher(TeacherVis teacher) {
System.out.println("访问者2访问老师:" + teacher.getName()+" 工龄:"+teacher.getWorkYear());
maxWorkYear = Math.max(maxWorkYear,teacher.getWorkYear());
}
}
class PersonStructure {
private List<PersonVis> personVisList = new ArrayList<>();
public PersonStructure() {
personVisList.add(new StudentVis("王一博",25,100));
personVisList.add(new StudentVis("肖战",31,90));
personVisList.add(new StudentVis("邓为",24,90));
personVisList.add(new TeacherVis("顾老师",40,40));
personVisList.add(new TeacherVis("李老师",60,50));
personVisList.add(new TeacherVis("赵老师",80,70));
}
public void Accept(Visitor visitor) {
for (PersonVis person : personVisList
) {
person.Accept(visitor);
}
}
}
abstract class PersonVis {
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public PersonVis(String name, int age) {
this.name = name;
this.age = age;
}
public abstract void Accept(Visitor visitor);
}
class StudentVis extends PersonVis {
private int score;
public StudentVis(String name, int age, int score) {
super(name, age);
this.score = score;
}
public int getScore() {
return score;
}
@Override
public void Accept(Visitor visitor) {
visitor.VisitStudent(this);
}
}
class TeacherVis extends PersonVis {
private int workYear;
public TeacherVis(String name, int age, int workYear) {
super(name, age);
this.workYear = workYear;
}
public int getWorkYear() {
return workYear;
}
@Override
public void Accept(Visitor visitor) {
visitor.VisitTeacher(this);
}
}