面向对象基础
客观世界由许多具体的事物,事件,概念和规则组成,这些均可以被看做成对象。面向对象==(Object-Oriented,OO)==方法是一种非常实用的系统化软件开发方法,它以客观世界中的对象为中心,其分析和设计思想符号人们的思维方式,分析和设计的结果与客观世界的实际比较接近,容易被人接受。
面向对象=对象(object)+分类(Classification)+继承(Inheritance)+通过消息的通信(Communication with Messages)
面向对象的设计原则
1,单一责任原则:就一个类而言,应该仅有一个引起他变化的原因。即,当需要修改某个类的时候原因有且只有一个,让一个类只做一种类型责任。
2,开放封闭原则:软件实体(类,模块,函数等)应该是可扩展的,即开放的,但是不可修改的,即封闭的。
3,里氏替换原则:子类型必须能够替换掉他们的基类型。即,在任何父类可以出现的地方,都可以用子类的实例来赋值给父类型的引用。当一个子类的实例应该能够替换任何其超类的实例时,它们之间才具有是一个(is-a)关系。
4,依赖倒置原则,抽象不应该依赖于细节,细节应该依赖于抽象,即,高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
5,接口分离原则:不强迫客户依赖于它们不同的方法,接口属于客户,不属于它所在的类层次结构。即:依赖于抽象,不要依赖于具体,同时在抽象级别不应该有对于细节的依赖。这样做的好处就在可以最大限度地应对可能的变化。
6,重用发布等价原则:重用的粒度就是发布的粒度。
7,共同封闭原则:包中的所有类对于同一类性质的变化应该是共同封闭的。一个变化若对一个包产生影响,则将对包中的所有类产生影响,而对于其他的包不造成任何影响。
8,共同重用原则:一个包中的所有类应该是共同重用的。如果重用了包中的一个类,那么就要重用包中的所有类。
9,无环依赖原则: 在包的依赖关系图中不允许存在环,即包之间的结构必须是一个直接的五环图形。
10,稳定依赖原则:朝着稳定方向进行依赖。
11,稳定抽象原则:包的抽象程度应该和其稳定程度一致。
面向对象分析
面向对象分析的目的是获得对应用问题的理解,理解的目的是确定系统的功能和性能要求。面向对象分析技术可以将系统的行为和信息间的关系表示为迭代构造特征。
主要活动: 1,认定对象。2,组织对象。3,对象间的相互作用。4,定义对象的操作。5,定义对象的内部信息。
面向对象设计
面向对象设计的含义是设计分析模型和实现相应的源代码。在目标代码环境中,这种源代码可以被执行。通常情况下,由概念模型生成的分析模型被装入到相应的执行环境中,还需要被修改。
主要活动:1,识别类及对象,2,定义属性、3,定义服务,4,识别关系、5,识别包。
面向对象程序设计
面向对象程序设计的实质是选用一种面向对象程序设计语言,采用对象,类及相关概念所进行的程序设计。它的关键在于加入了类的继承性,从而进一步提高了抽象程序。
面向对象测试。
4个层次
1,算法层,用于测试类中定义每个方法,基于上相当于传统软件测试中的单元测试。
2,类层,用于测试封装在同一个类中的所有方法与属性之间的相互作用,在面向对象软件中,类是基本模块,因此可以认为这是面向对象测试中所特有的模块测试。
3,模板层,用于测试一组协同工作的类之间的相互作用,大体上相当于传统软件测试中的集成测试。但是也有面向对象软件的特点。如对象之间通过发送消息相互作用。
4,系统层,把各个子系统组装成完整的面向对象的软件系统,在组装过程中进行测试。
UML
UML(统一建模语言)是面向对象软件的标准化建模语言。
UML的词汇表包含3种构造块:事物,关系和图。事物是对模型中最具有代表性的成分的抽象。 关系把事物结合在一起;图聚集了相关的事物。
事物
uml中有4种事物:结构事物,行为事物,分组事物和注解事物
🍀结构事物,结构事物是UML模型中的名词,他们通常是模型的静态部分,描述概念或物理元素。结构事物包括类(class),接口(Interface),协作(Collaboration),用例(Use Case),主动类(Active Class),构件(Component),制品(Artifact)和结点(Node)
🍀行为事物,行为事物是UML模型的动态部分,它们是模型中的动词,描述了跨越时间和空间的行为。行为事物包括交互(Interaction),状态机(State Machine)和活动(Activity)
🍀分组事物,分组事物是UML模型的组织部分,是一些由模型分解成的“盒子模型”。在所在的分组事物中,最主要的分组事物是包(Package),包是把元素组织成组的机制,这种机制具有多种用途。
🍀注解事物,注解事物是UML模型的解释部分,这些注解事物用来描述,说明和标注模型的任何元素。注解(Note)是一种主要的注解事物。注解是一个依附于一个元素或者一组元素之上,对它进行约束或者解释的简单符号。
关系
UML中有4种关系:依赖,关联,泛化 和实现
🍅依赖(Dependency):依赖是两个事物间的语义关系,其中一个事物(独立事物)发生变化会影响另一个事物(依赖事物)
如:汽车需要依赖车牌才可以上路,这两者的关系表现非固定关系但是有依赖
变体: 🍁聚合(聚集)(Aggregation)描述的是整体与部分生命周期不同的关系。
🍁组合: 描述的是整体与部分生命周期相同的关系。
🍅关联(Association):关联是一种结构关系,它描述了一组链,链是对象之间的连接。
🍅泛化(Generaliation):泛化是一种特殊/一般关系,特殊元素(子元素)的对象可替代一般元素(父元素)的对象,用这种方法,子元素共享了父元素的结构和行为。(父子关系)
🍅实现(Realization):实现是类元之间的语义关系,其中一个类元指定了由另一个类元保证执行的契约。在两种情况下会使用实现关系:一种是在接口和实现它们的类或构件之间;另一种是在用例和他们的协作之间。
图
类图(Class Diagram)
展现了一组对象,接口,协作和它们的关系。
对象图(Object Diagram)
展现了某一时刻一组对象以及它们之间的关系,描述了在类图中所建立的事物的实例的静态快照。
用例图(Use Case Diagram)
展现了一组用例,参与者(Actor)以及它们的关系。用例图通常包括
🍂1,用例。
🍂2,参与者。
🍂3,用例之间的扩展关系(<<extend>>)和包含关系(<<include>>),参与者和用例之间的关联关系,用例与用例以及参与者与参与者之间的泛化关系。
include表示包含关系,含义为:如果系统用例较多,不同的用例之间存在共同的行为,可以将这些行为提取出来,单独组成一个用例,当其他用例使用这个用例时,它们就构成了包含关系。
extend包含扩展关系,含义为:在用例的执行过程中,可能出现一些异常行为,也可能会在不同的分支行为中选择执行,这时可将异常行为与可选分支抽象为一个单独的扩展用例,这样扩展用例与主用例之间就构成了扩展关系,一个用例常常有多个扩展关系。
序列图(Sequence DIagram)
序列图是场景(Scenario)的图形化表述,描述了以时间顺序组织的对象之间的交互活动。
通信图/协作图(Communication Diagram)
通信图(Communication Diagram)强调收发信息的对象的结构组织。
交互概览图(Interaction Overview Diagram)
交互预览图是UML2.0新增的交互图之一,它是活动图的变体,描述业务过程中的控制流概览,软件过程中国的详细逻辑概览,以及将多个图进行连接,抽象掉了消息和生命线。
计时图(Timing Diagram)
计时图是另一种新增的,特别适合实时和嵌入式系统建模的交互图,关注沿着时间轴,生命线内部和生命线之间的条件改变。
状态图(state Diagram)
状态图展现了一个状态机,它由状态,转换,事件和活动组成。状态图关注系统的动态视图,对于接口,类和协作的行为建模尤为重要,强调对象行为的事件顺序。
活动图(Activity Diagram)
活动图是一种特殊的状态图,它展现了在系统内从一个活动到另一个活动的流程。
构件图(Component Diagram)
构件图展现了一组构件之间的组织和依赖。
组合结构图(Component Diagram)
组合结构图用于描述一个分类器(如类,构件或用例)的内部结构,分类器与系统中其他组成部分之间的交互端口,展示了一组相互协作的实例如何完成特定的任务,描述设计,架构模式或策略。
部署图
部署图是用来对面向对象系统的物理方面的建模方法,展现了运行时的处理结点及其中构件(制品)的配置,一般对于系统的静态部署视图进行建模,与构件相关。
包图
包图用于把模型本身组织成层次结构的通用机制,不能执行,展现了由模型本身分解而成的组织单元及之间的依赖关系。
设计模式
设计模式要素
💧 模式名称(pattern name):一个助记词,它用一两个词来描述模式的问题,解决方案和效果。
💧 问题(problem):问题描述了应该在何时使用模式。
💧 解决方案(solution):解决方案描述了设计的组成成分,它们之间的相互关系及各自的责任和协作方式。
💧 效果(consequences):效果描述了模式应用的效果及使用模式应权衡的问题,
设计模式
🍅 创建型模式: 工厂方法,抽象工厂,原型,单例,构建器
🍅 结构型模式:适配器,桥接,组合,装饰,外观,享元,代理
🍅行为型模式:责任链, 命令,解释器,迭代器,中介者,备忘录,观察者,状态,策略,模板方法 访问者
创建型设计模式
创建型设计模式是把实例化过程进行抽象化,以使一个系统可以从创建,组合和表示对象的过程独立出来。
工厂方法(Factory Method)
工厂方法是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。
package factoryMethod;
//发送器接口
public interface Sender {
void send();
}
public class MailSender implements Sender {
@Override
public void send() {
System.out.println("这是邮件发送器");
}
}
public class SmsSender implements Sender {
@Override
public void send() {
System.out.println("这是短信发送器");
}
}
public interface Provider {
// 这是一个工厂方法
Sender produce();
}
public class SendMailFactory implements Provider {
@Override
public Sender produce() {
return new MailSender();
}
}
public class SendSmsFactory implements Provider {
@Override
public Sender produce() {
return new SmsSender();
}
}
public static void main(String[] args) {
Provider provider = new SendMailFactory();
Sender sender = provider.produce();
sender.send();
}
抽象工厂(Abstract Factory)
抽象工厂提供一个接口,可以创建一系列相关或相互依赖的对象,而无需指定他们具体的类。
package abstractFactory;
//发送器接口
public interface Sender {
void send();
}
public class SmsSender implements Sender {
@Override
public void send() {
System.out.println("这是短信发送器");
}
}
public class MailSender implements Sender {
@Override
public void send() {
System.out.println("这是邮件发送器");
}
}
public abstract class AbstractFactory {
abstract Sender produce(String type);
}
public class SenderFactory extends AbstractFactory {
@Override
Sender produce(String type) {
if ("mail".equals(type)) {
return new MailSender();
} else if ("sms".equals(type)) {
return new SmsSender();
} else {
System.out.println("请输入正确的类型!");
return null;
}
}
}
public static void main(String[] args) {
// SenderFactory factory = new SenderFactory();
SenderFactory factory = new SenderFactory();
Sender sender = factory.produce("sms");
sender.send();
}
构建器(Builder)
将一个复杂类的表示与其构造相分离,使得相同的构建过程能够得出不同的表示。
package builder;
public class User {
private final int id;// 身份证号
private final String name;// 姓名
private int age;// 年龄
private boolean sex;// 性别
private String desc;// 个人描述
User(Builder builder) {
this.id = builder.id;
this.name = builder.name;
this.age = builder.age;
this.sex = builder.sex;
this.desc = builder.desc;
}
@Override
public String toString() {
return "id:" + this.id + " 姓名:" + this.name + " 年龄:" + this.age + " 性别:" + this.sex + " 描述:" + this.desc;
}
}
public class Builder {
final int id;
final String name;
int age;
boolean sex;
String desc;
public Builder(int id, String name) {
this.id = id;
this.name = name;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Builder setSex(boolean sex) {
this.sex = sex;
return this;
}
public Builder setDesc(String desc) {
this.desc = desc;
return this;
}
public User build() {
return new User(this);
}
}
public static void main(String[] args) {
Builder builder = new Builder(1, "张三");
User user = builder.setAge(18).setSex(true).setDesc("这是一个测试").build();
System.out.println(user.toString());
}
原型(Prototype)
将一个对象作为原型,对其进行复制、克隆后产生一个和原对象类似的新对象
package prototype;
public class UserPrototype implements Cloneable {
private final int id;// 身份证号
private final String name;// 姓名
public UserPrototype(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return super.toString();
}
@Override
protected UserPrototype clone() {
UserPrototype user = null;
try {
user = (UserPrototype) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return user;
}
}
public static void main(String[] args) {
// UserPrototype.clone();
UserPrototype user1 = new UserPrototype(1, "张三");
UserPrototype user2 = user1.clone();
System.out.println(user1.toString());
System.out.println(user2.toString());
}
单例(Singleton)
保证一个类只有一个实例,并提供一个访问它的全局访问
package singleton;
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return singleton;
}
}
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
System.out.println(singleton.toString());
}
结构型设计模式
结构类设计模式主要是为了解决类或对象之间的组合关系的。
适配器(Adapter)
将一个类的接口转换成用户希望得到的另一种接口,它使原本不相容的接口得以协同工作。
//插网线上网 网线有上网功能,但是它的接口与电脑不匹配
package adapter;
//要适配的类:网线
public class Adaptee {
// 功能:上网
public void request() {
System.out.println("链接网线上网");
}
}
//接口转换器的抽象实现
public interface NetToUsb {
// 作用:处理请求,网线=>usb
public void handleRequest();
}
public class Adapter extends Adaptee implements NetToUsb {
@Override
public void handleRequest() {
// 作用:处理请求,网线=>usb 适配器
super.request();
}
}
//客户端类:想上网,插不上网线
public class Computer {
// 电脑需要连接上转接器才可以上网
public void net(NetToUsb adapter) {
// 上网的具体实现:找一个转接头
adapter.handleRequest();
}
public static void main(String[] args) {
// 电脑,适配器,网线
Computer computer = new Computer();// 电脑
Adapter adapter = new Adapter();// 转接器
computer.net(adapter);// 电脑直接连接转接器就可以
}
}
桥接(Bridge)
将类的抽象部分和它的实现部分分离开来,使它们可以独立地变化。
package bridge;
public interface Brand {
void open();// 打开手机
void close();// 关闭手机
void call();// 打电话
}
public class Oppo implements Brand {
@Override
public void open() {
System.out.println("Oppo手机开机");
}
@Override
public void close() {
System.out.println("Oppo手机关机");
}
@Override
public void call() {
System.out.println("Oppo手机打电话");
}
}
public class HuaWei implements Brand {
@Override
public void open() {
System.out.println("HuaWei手机开机");
}
@Override
public void close() {
System.out.println("HuaWei手机关机");
}
@Override
public void call() {
System.out.println("HuaWei手机打电话");
}
}
public abstract class Phone {
private Brand brand;
public Phone() {
}
public Phone(Brand brand) {
super();
this.brand = brand;
}
protected void open() {
this.brand.open();
}
protected void close() {
this.brand.close();
}
protected void call() {
this.brand.call();
}
}
//折叠屏手机类,继承抽象类Phone
public class FoldedPhone extends Phone {
public FoldedPhone(Brand brand) {
super(brand);
}
public void open() {
super.open();
System.out.println("折叠样式手机");
}
public void close() {
super.close();
System.out.println("折叠样式手机");
}
public void call() {
super.call();
System.out.println("折叠样式手机");
}
}
public static void main(String[] args) {
Phone phone = new FoldedPhone(new Oppo());
phone.open();
phone.call();
phone.close();
}
组合(Composite)
将对象组合成树型结构以表示“整体-部分”的层次结构,是的用户对单个对象和组合对象的使用具有一致性。
package component;
// 抽象公司
public abstract class Company {
protected String name;
public Company(String name) {
this.name = name;
}
public abstract void add(Company company);// 添加
public abstract void remove(Company company);// 移除
public abstract void display(int depth);// 显示
public abstract void lineOfDuty();// 履行职责
}
public class HRDepartment extends Company {
public HRDepartment(String name) {
super(name);
}
@Override
public void add(Company company) {
}
@Override
public void remove(Company company) {
}
@Override
public void display(int depth) {
for (int i = 0; i < depth; i++) {
System.out.print("-");
}
System.out.println(name);
}
@Override
public void lineOfDuty() {
System.out.println(name + " 员工招聘培训管理");
}
}
// 财务部
public class FinanceDepartment extends Company {
public FinanceDepartment(String name) {
super(name);
}
@Override
public void add(Company company) {
}
@Override
public void remove(Company company) {
}
@Override
public void display(int depth) {
for (int i = 0; i < depth; i++) {
System.out.print("-");
}
System.out.println(name);
}
@Override
public void lineOfDuty() {
System.out.println(name + " 公司财务收支管理");
}
}
import java.util.ArrayList;
// 具体公司
public class ConcreteCompany extends Company {
private ArrayList<Company> companies = new ArrayList<Company>();
public ConcreteCompany(String name) {
super(name);
}
@Override
public void add(Company company) {
companies.add(company);
}
@Override
public void remove(Company company) {
}
@Override
public void display(int depth) {
toDisplay(depth);
for (Company company : companies) {
company.display(depth + 2);
}
}
private void toDisplay(int depth) {
for (int i = 0; i < depth; i++) {
System.out.print("-");
}
System.out.println(name);
}
@Override
public void lineOfDuty() {
for (Company company : companies) {
company.lineOfDuty();
}
}
}
ConcreteCompany root = new ConcreteCompany("北京总公司");
root.add(new HRDepartment("总公司人力资源部"));
root.add(new FinanceDepartment("总公司财务部"));
ConcreteCompany comp = new ConcreteCompany("上海华东分公司");
comp.add(new HRDepartment("华东分公司人力资源部"));
comp.add(new FinanceDepartment("华东分公司财务部"));
root.add(comp);
ConcreteCompany comp1 = new ConcreteCompany("南京办事处");
comp1.add(new HRDepartment("南京办事处人力资源部"));
comp1.add(new FinanceDepartment("南京办事处财务部"));
comp.add(comp1);
System.out.println("结构图");
root.display(1);
System.out.println("职责");
root.lineOfDuty();
装饰(Decorator)
动态地给一个对象添加一些额外的职责,它提供了用子类扩展功能的一个灵活的替代,比派生一个子类更加灵活。
package decorator;
public interface Sourceable {
public void method();
}
public class Source implements Sourceable {
@Override
public void method() {
System.out.println("星麦罗小黄蜂");
}
}
public class Decorator implements Sourceable {
private Sourceable source;
public Decorator(Sourceable source) {
super();
this.source = source;
}
@Override
public void method() {
source.method(); // 调用原始对象的方法
System.out.println("科迈罗大黄蜂");
}
}
public static void main(String[] args) {
Sourceable source = new Source();
Sourceable obj = new Decorator(source);
obj.method();
}
外观(Facade)
定义一个高层接口,为子系统中的一组接口提供一个一致的外观,从而简化了该子系统的使用。
package facade;
public class SubSysteomA {
public void methodA() {
System.out.println("子系统A的方法");
}
}
public class SubSysteomB {
public void methodB() {
System.out.println("子系统B的方法");
}
}
public class SubSysteomC {
public void methodC() {
System.out.println("子系统C的方法");
}
}
public class Facade {
private SubSysteomA a = new SubSysteomA();
private SubSysteomB b = new SubSysteomB();
private SubSysteomC c = new SubSysteomC();
public void method() {
a.methodA();
b.methodB();
c.methodC();
}
}
public static void main(String[] args) {
Facade facade = new Facade();
facade.method();
}
享元(FlyWeight)
提供支持大量细粒度对象共享的有效方法,它通过共享已经存在的对象来减少需要创建的对象数量,从而提高系统资源的利用率。
public interface Flyweight {
void operate();
}
public class ConcreteFlyweight implements Flyweight {
private String key;
public ConcreteFlyweight(String key) {
this.key = key;
System.out.println("具体享元" + key + "被创建!");
}
@Override
public void operate() {
System.out.println("具体享元" + key + "被调用!");
}
}
public class FlyweightFactory {
private Map<String, Flyweight> flyWeightMap = new HashMap<>();
public Flyweight getFlyweight(String key) {
Flyweight flyweight = flyWeightMap.get(key);
if (flyweight == null) {
flyweight = new ConcreteFlyweight(key);
flyWeightMap.put(key, flyweight);
}
return flyweight;
}
}
public static void main(String[] args) {
FlyweightFactory factory = new FlyweightFactory();
factory.getFlyweight("1").operate();
factory.getFlyweight("2").operate();
factory.getFlyweight("3").operate();
}
代理(Proxy)
为其他对象提供一种代理以控制这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
package proxy;
public interface Movie {
void play();
}
public class RealMovie implements Movie {
@Override
public void play() {
System.out.println("播放金刚大战哥斯拉");
}
}
public class ProxyMovie implements Movie {
Movie movie;
public ProxyMovie(Movie movie) {
this.movie = movie;
}
@Override
public void play() {
System.out.println("电影还没开始,买点爆米花");
movie.play();
System.out.println("电影结束了,买个哥斯拉模型");
}
}
public static void main(String[] args) {
RealMovie movie = new RealMovie();
ProxyMovie proxyMovie = new ProxyMovie(movie);
proxyMovie.play();
}
行为型设计模式
行为型设计模式涉及算法和对象间的职责的分配,行为设计模式不仅描述对象或类的行为模式,还描述了它们之间的通信模式。这些模式刻画了在运行时难以跟踪的,复杂的控制流。它们将用户的注意力从控制流转义到对象间的练习方式上来。
责任链(Chain of Responsibility)
通过给多个对象处理请求的机会,减少请求的发送者与接受者之间的耦合,将接收对象链接起来,在链中传递请求,直到有一个对象处理这个请求。
package chainofResponsibility;
public abstract class Handler {
private Handler next;
public Handler getNext() {
return next;
}
public void setNext(Handler next) {
this.next = next;
}
public abstract void handleRequest(String name, int days);
}
public class PMHandler extends Handler {
@Override
public void handleRequest(String name, int days) {
if (days <= 3) {
System.out.println("PM批准了" + name + "的请假");
} else {
if (getNext() != null) {
getNext().handleRequest(name, days);
} else {
System.out.println("请假天数太多,没有人批准");
}
}
}
}
public class MinisterHandler extends Handler {
@Override
public void handleRequest(String name, int days) {
if (days <= 15) {
System.out.println("部长批准了" + name + "的请假");
} else {
if (getNext() != null) {
getNext().handleRequest(name, days);
} else {
System.out.println("请假天数太多,没有人批准");
}
}
}
}
public class DirectorHandler extends Handler {
@Override
public void handleRequest(String name, int days) {
if (days <= 7) {
System.out.println("中心总监批准了" + name + "的请假");
} else {
if (getNext() != null) {
getNext().handleRequest(name, days);
} else {
System.out.println("请假天数太多,没有人批准");
}
}
}
}
public static void main(String[] args) {
// 创建具体处理者
Handler pm = new PMHandler();
Handler director = new DirectorHandler();
Handler minister = new MinisterHandler();
// 构建责任链
pm.setNext(director);
director.setNext(minister);
// 使用责任链
pm.handleRequest("张三", 5);
}
命令(Command)
将一个请求封装成一个对象,从而可用不同的请求对客户进行参数化,将请求排队或记录请求日志,支持可撤销的操作。
package command;
public interface Command {
// 执行动作(操作)
void execute();
// 撤销动作(操作)
void undo();
}
// 电灯关闭命令类
public class LightOffCommand implements Command {
// 聚合LightReceiver
LightReceiver lightReceiver;
// 构造器
public LightOffCommand(LightReceiver lightReceiver) {
this.lightReceiver = lightReceiver;
}
@Override
public void execute() {
// 调用接收者的方法
lightReceiver.off();
}
@Override
public void undo() {
// 调用接收者的方法
lightReceiver.on();
}
}
public class LightOnCommand implements Command {
// 聚合LightReceiver
LightReceiver lightReceiver;
// 构造器
public LightOnCommand(LightReceiver lingReceiver) {
this.lightReceiver = lingReceiver;
}
@Override
public void execute() {
// 调用接收者的方法
lightReceiver.on();
}
@Override
public void undo() {
// 调用接收者的方法
lightReceiver.off();
}
}
public class NoCommand implements Command {
@Override
public void execute() {
System.out.println("空命令");
}
@Override
public void undo() {
System.out.println("空命令");
}
}
public class LightReceiver {
public void on() {
System.out.println("电灯打开了");
}
public void off() {
System.out.println("电灯关闭了");
}
}
public class RemoteController {
// 开关按钮的命令数组
Command[] onCommands;
Command[] offCommands;
// 执行撤销按钮操作
Command undoCommand;
public RemoteController() {
onCommands = new Command[5];
offCommands = new Command[5];
// 初始化开关按钮的命令数组
for (int i = 0; i < 5; i++) {
onCommands[i] = new NoCommand();
offCommands[i] = new NoCommand();
}
}
// 给我们的按钮设置你需要的命令即可
public void setCommand(int no, Command onCommand, Command offCommand) {
onCommands[no] = onCommand;
offCommands[no] = offCommand;
}
// 按下开按钮
public void onButtonWasPushed(int no) {
onCommands[no].execute();
// 记录这次操作,用于撤销
undoCommand = onCommands[no];
}
// 按下关按钮
public void offButtonWasPushed(int no) {
offCommands[no].execute();
undoCommand = offCommands[no];
}
// 撤销
public void undoButtonWasPushed() {
undoCommand.undo();
}
}
public static void main(String[] args) {
// 通过遥控器控制不同家电,因为每个家电的厂家不同,APP不同,所以可以提高命令模式实现解耦。
// 创建电灯的对象(接收者)
LightReceiver lightReceiver = new LightReceiver();
// 创建电灯的开关命令
LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver);
LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver);
// 需要一个遥控器
RemoteController remoteController = new RemoteController();
// 给遥控器设置命令,比如no=0是电灯的开和关的操作
remoteController.setCommand(0, lightOnCommand, lightOffCommand);
System.out.println("------按下灯的开按钮------");
remoteController.onButtonWasPushed(0);
System.out.println("------按下灯的关按钮------");
remoteController.offButtonWasPushed(0);
System.out.println("------按下撤销按钮------");
remoteController.undoButtonWasPushed();
}
解释器(Interpreter)
给定一种语言,定义它的文法表示,并定义一个解释器该解释器用来根据文法表示来解释语言中的句子。
package interpreter;
/**
* 解释器模式
*/
public interface Expression {
// 解释方法
public boolean interpret(String info);
}
import java.util.HashSet;
import java.util.Set;
/** 终结符表达式 **/
public class TerminalExpression implements Expression {
private Set<String> set = new HashSet<String>();
public TerminalExpression(String[] data) {
for (int i = 0; i < data.length; i++) {
set.add(data[i]);
}
}
@Override
public boolean interpret(String info) {
if (set.contains(info)) {
return true;
}
return false;
}
}
/** 非终结符表达式类 **/
public class AndExpression implements Expression {
private Expression city = null;
private Expression person = null;
public AndExpression(Expression city, Expression person) {
this.city = city;
this.person = person;
}
@Override
public boolean interpret(String info) {
String s[] = info.split("的");
return city.interpret(s[0]) && person.interpret(s[1]);
}
}
public class Context {
private String[] citys = { "上海", "北京", "广州", "深圳" };
private String[] persons = { "老人", "小孩", "残疾人", "孕妇" };
private Expression expression = null;
public Context() {
Expression city = new TerminalExpression(citys);
Expression person = new TerminalExpression(persons);
expression = new AndExpression(city, person);
}
// 调用相关表达式类的解释方法
public void freeRide(String info) {
boolean ok = expression.interpret(info);
if (ok) {
System.out.println("您是" + info + ",您本次乘车免费!");
} else {
System.out.println(info + ",您不是免费人员,本次乘车扣费2元!");
}
}
}
public static void main(String[] args) {
Context bus = new Context();
bus.freeRide("北京的老人");
bus.freeRide("北京的小孩");
bus.freeRide("北京的妇女");
bus.freeRide("广州的小孩");
bus.freeRide("山东的小孩");
}
迭代器(Iterator)
提供一种方法来顺序访问一个聚合对象的各个元素,而不需要暴露该对象的内部表示。
package iterator;
public interface Iterator {
public boolean hasNext();
public Object next();
}
public interface Container {
public Iterator getIterator();
}
public class SpecificContainer implements Container {
private String[] mStrings;
public SpecificContainer(String[] strings) {
mStrings = strings;
}
@Override
public Iterator getIterator() {
return new SpecificIterator();
}
// 内部类
public class SpecificIterator implements Iterator {
int index;
@Override
public boolean hasNext() {
if (index < mStrings.length) {
return true;
}
return false;
}
@Override
public Object next() {
if (this.hasNext()) {
return mStrings[index++];
}
return null;
}
}
}
public static void main(String[] args) {
String[] s = { "ab", "cd", "ef", "gh" };
SpecificContainer specificContainer = new SpecificContainer(s);
Iterator iterator = specificContainer.getIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
中介器(Mediator)
用一个中介对象来封装一系列的对象交互,它使各对象不需要显示地相互调用,从而达到低耦合,还可以独立地改变对象间的交互。
package mediator;
//中介者抽象类
public abstract class Mediator {
// 将给中介者对象,加入到集合中
public abstract void register(String colleagueName, Colleague colleague);
// 接收消息, 具体的同事对象发出
public abstract void getMessage(int stateChange, String colleagueName);
// 同事对象在自身改变的时候来通知中介者的方法
// 让中介者去负责相应的与其他同事对象的交互
public abstract void sendMessage();
}
// 同事类
public abstract class Colleague {
private Mediator mediator;
public String name;
public Colleague(Mediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}
public Mediator getMediator() {
return mediator;
}
public abstract void sendMessage(int stateChange);
}
//闹钟
public class Alarm extends Colleague {
public Alarm(Mediator mediator, String name) {
super(mediator, name);
// 在创建Alarm 同事对象时,将自己放入到ConcreteMediator 对象中[集合]
mediator.register(name, this);
}
public void sendAlarm(int stateChange) {
sendMessage(stateChange);
}
@Override
public void sendMessage(int stateChange) {
this.getMediator().getMessage(stateChange, this.name);
}
}
// 咖啡机
public class CoffeeMachine extends Colleague {
public CoffeeMachine(Mediator mediator, String name) {
super(mediator, name);
mediator.register(name, this);
}
public void startCoffee() {
System.out.println("是时候泡咖啡了");
}
public void finishCoffee() {
System.out.println("5分钟后咖啡好了");
System.out.println("咖啡好了,通知其他同事");
sendMessage(0);
}
@Override
public void sendMessage(int stateChange) {
this.getMediator().getMessage(stateChange, this.name);
}
}
// 窗帘
public class Curtains extends Colleague {
public Curtains(Mediator mediator, String name) {
super(mediator, name);
mediator.register(name, this);
}
public void upCurtains() {
System.out.println("我 要 抬 起 窗 帘 了");
}
@Override
public void sendMessage(int stateChange) {
this.getMediator().getMessage(stateChange, this.name);
}
}
//电视
public class TV extends Colleague {
public TV(Mediator mediator, String name) {
super(mediator, name);
mediator.register(name, this);
}
public void startTV() {
System.out.println("是时候打开电视了");
}
public void stopTV() {
System.out.println("关闭电视");
}
@Override
public void sendMessage(int stateChange) {
this.getMediator().getMessage(stateChange, this.name);
}
}
import java.util.HashMap;
//具体的中介者类
public class ConcreteMediator extends Mediator {
// 集合,放入所有的同事对象
private HashMap<String, Colleague> colleagueMap;
private HashMap<String, String> interMap;
public ConcreteMediator() {
colleagueMap = new HashMap<String, Colleague>();
interMap = new HashMap<String, String>();
}
@Override
public void register(String colleagueName, Colleague colleague) {
colleagueMap.put(colleagueName, colleague);
if (colleague instanceof Alarm) {
interMap.put("Alarm", colleagueName);
} else if (colleague instanceof CoffeeMachine) {
interMap.put("CoffeeMachine", colleagueName);
} else if (colleague instanceof TV) {
interMap.put("TV", colleagueName);
} else if (colleague instanceof Curtains) {
interMap.put("Curtains", colleagueName);
}
}
// 具体中介者的核心方法
// 1. 根据得到消息,完成对应任务
// 2. 中介者在这个方法,协调各个具体的同事对象,完成任务
@Override
public void getMessage(int stateChange, String colleagueName) {
// 处理闹钟发出的消息
if (colleagueMap.get(colleagueName) instanceof Alarm) {
if (stateChange == 0) {
((CoffeeMachine) (colleagueMap.get(interMap
.get("CoffeeMachine")))).startCoffee();
((TV) (colleagueMap.get(interMap.get("TV")))).startTV();
} else if (stateChange == 1) {
((TV) (colleagueMap.get(interMap.get("TV")))).stopTV();
}
} else if (colleagueMap.get(colleagueName) instanceof CoffeeMachine) {
((Curtains) (colleagueMap.get(interMap.get("Curtains"))))
.upCurtains();
} else if (colleagueMap.get(colleagueName) instanceof TV) {// 如果TV发现消息
} else if (colleagueMap.get(colleagueName) instanceof Curtains) {
// 如果是以窗帘发出的消息,这里处理...
}
}
@Override
public void sendMessage() {
}
}
public static void main(String[] args) {
// 智能家居项目,智能家庭包括各种设备,闹钟,咖啡机,电视机,窗帘等
// 主人要看电视时,各个设备可以完成看电视的准备工作,比如流程为:闹铃响起,咖啡机开始做咖啡,窗帘自动落下,电视开始播放。
// 创建一个中介者对象
Mediator mediator = new ConcreteMediator();
// 创建Alarm 并且加入到 ConcreteMediator 对象的HashMap
Alarm alarm = new Alarm(mediator, "alarm");
// 创建了CoffeeMachine 对象,并 且加入到 ConcreteMediator 对象的HashMap
CoffeeMachine coffeeMachine = new CoffeeMachine(mediator, "coffeeMachine");
// 创建 Curtains , 并 且加入到 ConcreteMediator 对象的HashMap
Curtains curtains = new Curtains(mediator, "curtains");
TV tV = new TV(mediator, "TV");
// 让闹钟发出消息
alarm.sendAlarm(0);
coffeeMachine.finishCoffee();
alarm.sendAlarm(1);
}
备忘录(Memento)
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,从而可以在以后将该对象回复到最先保存的状态。
package memento;
public class Memento {
// 角色名称
private String name;
// 攻击力
private int vit;
// 防御力
private int def;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setVit(int vit) {
this.vit = vit;
}
public int getVit() {
return vit;
}
public void setDef(int def) {
this.def = def;
}
public int getDef() {
return def;
}
public Memento(String name, int vit, int def) {
this.name = name;
this.vit = vit;
this.def = def;
}
}
//守护对象,用于保存游戏角色状态
public class Caretaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
public class GameRole {
private String name;
private int vit;
private int def;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setVit(int vit) {
this.vit = vit;
}
public int getVit() {
return vit;
}
public void setDef(int def) {
this.def = def;
}
public int getDef() {
return def;
}
// 创建Memento,即根据当前的状态得到 Memento
public Memento createMemento() {
return new Memento(this.name, this.vit, this.def);
}
// 从备忘录对象,恢复GameRole的状态
public void recoverGameRoleFromMemento(Memento memento) {
this.name = memento.getName();
this.vit = memento.getVit();
this.def = memento.getDef();
}
public void display() {
System.out.println("角色当前状态:");
System.out.println("角色名字:" + this.name);
System.out.println("角色生命力:" + this.vit);
System.out.println("角色防御力:" + this.def);
}
}
public static void main(String[] args) {
GameRole gameRole = new GameRole();
gameRole.setVit(100);
gameRole.setDef(100);
gameRole.setName("亚瑟");
System.out.println("和boss大战前的状态");
gameRole.display();
// 把当前状态保存到备忘录对象 Caretaker
Caretaker caretaker = new Caretaker();
caretaker.setMemento(gameRole.createMemento());
// 对象状态改变
gameRole.setName("亚瑟");
gameRole.setDef(50);
gameRole.setVit(60);
System.out.println("和boss大战后的状态");
gameRole.display();
// 从备忘录对象,恢复GameRole的状态
gameRole.recoverGameRoleFromMemento(caretaker.getMemento());
System.out.println("恢复后的状态");
gameRole.display();
}
观察者(Observer)
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
package observer;
public interface Observer {
// 响应
public void response();
}
import java.util.Vector;
public class Subject {
private Vector<Observer> oVector = new Vector<Observer>();
// 增加一个观察者,相当于观察者注册
public void addObserver(Observer observer) {
this.oVector.add(observer);
}
// 删除一个观察者
public void deleteObserver(Observer observer) {
this.oVector.remove(observer);
}
// 通知所有观察者,主题有变化时通知观察者
public void notifyObserver() {
for (Observer observer : this.oVector) {
observer.response();
}
}
}
public class ConcreteSubject extends Subject {
// 具体的业务
public void doSomething() {
// do something
System.out.println("具体目标发生改变...");
System.out.println("--------------");
super.notifyObserver();
}
}
public class ConcreteObserver1 implements Observer {
@Override
public void response() {
System.out.println("具体观察者1作出反应!");
}
}
public class ConcreteObserver2 implements Observer {
@Override
public void response() {
System.out.println("具体观察者2作出反应!");
}
}
public static void main(String[] args) {
// 创建一个主题
ConcreteSubject subject = new ConcreteSubject();
// 创建一个观察者
Observer observer1 = new ConcreteObserver1();
// 创建一个观察者
Observer observer2 = new ConcreteObserver2();
// 将观察者注册到主题中
subject.addObserver(observer1);
subject.addObserver(observer2);
// 改变主题状态
subject.doSomething();
}
状态(State)
允许一个对象在其内部状态改变时改变它的行为。
package state;
public abstract class UserState {
protected AppContext context;
public void setContext(AppContext context) {
this.context = context;
}
public abstract void favorite();
public abstract void comment(String comment);
}
public class LoginState extends UserState {
@Override
public void favorite() {
System.out.println("收藏成功");
}
@Override
public void comment(String comment) {
System.out.println("评论成功");
}
}
public class UnLoginState extends UserState {
@Override
public void favorite() {
context.setState(AppContext.STATE_LOGIN);
context.getState().favorite();
}
@Override
public void comment(String comment) {
context.setState(AppContext.STATE_LOGIN);
context.getState().comment(comment);
}
}
public class AppContext {
public static final UserState STATE_LOGIN = new LoginState();
public static final UserState STATE_UNLOGIN = new UnLoginState();
private UserState currentState = STATE_UNLOGIN;
public AppContext() {
STATE_LOGIN.setContext(this);
STATE_UNLOGIN.setContext(this);
}
public void setState(UserState state) {
this.currentState = state;
this.currentState.setContext(this);
}
public UserState getState() {
return currentState;
}
public void favorite() {
this.currentState.favorite();
}
public void comment(String comment) {
this.currentState.comment(comment);
}
}
public static void main(String[] args) {
// 当我们浏览博客园的文章时,如果我们觉得文章很好,忍不住想评论、收藏。但是如果我们处于未登录的状态,就会自动跳转到登录页面
// 这里涉及到的状态有两种登录和未登录,行为有评论和收藏。下面使用状态模式来实现这个逻辑,代码如下。
AppContext context = new AppContext();
context.favorite();
context.comment("很不错");
}
策略(Strategy)
定义一系列算法,把他们一个个封装起来,并且使它们之间可互相替换,从而让算法可以独立于使用它的用户而变化。
package strategy;
public interface MemberStrategy {
// 一个计算价格的抽象方法
// price商品的价格 n商品的个数
public double calcPrice(double price, int n);
}
// 普通会员——不打折
public class PrimaryMemberStrategy implements MemberStrategy {
@Override
public double calcPrice(double price, int n) {
System.out.println("对于初级会员的没有折扣");
return price * n;
}
}
// 中级会员 打百分之10的折扣
public class IntermediateMemberStrategy implements MemberStrategy {
@Override
public double calcPrice(double price, int n) {
System.out.println("对于中级会员的折扣为10%");
return price * n * 0.9;
}
}
// 高级会员类 20%折扣
public class AdvanceMemberStrategy implements MemberStrategy {
@Override
public double calcPrice(double price, int n) {
System.out.println("对于高级会员的折扣为20%");
return price * n * 0.8;
}
}
/**
* 负责和具体的策略类交互
* 这样的话,具体的算法和直接的客户端调用分离了,使得算法可以独立于客户端独立的变化。
*/
// 上下文类/环境类
public class MemberContext {
// 用户折扣策略接口
private MemberStrategy memberStrategy;
// 注入构造方法
public MemberContext(MemberStrategy memberStrategy) {
this.memberStrategy = memberStrategy;
}
// 计算图书的价格
public double calcPrice(double price, int n) {
return memberStrategy.calcPrice(price, n);
}
}
public static void main(String[] args) {
// 具体行为策略
MemberStrategy primaryMemberStrategy = new PrimaryMemberStrategy(); // 接口回调(向上转型)
MemberStrategy intermediateMemberStrategy = new IntermediateMemberStrategy();
MemberStrategy advanceMemberStrategy = new AdvanceMemberStrategy();
// 用户选择不同策略
MemberContext primaryContext = new MemberContext(primaryMemberStrategy);
MemberContext intermediateContext = new MemberContext(intermediateMemberStrategy);
MemberContext advanceContext = new MemberContext(advanceMemberStrategy);
// 计算一本300块钱的书
System.out.println("普通会员的价格:" + primaryContext.calcPrice(300, 1));// 普通会员:300
System.out.println("中级会员的价格:" + intermediateContext.calcPrice(300, 1));// 中级会员 270
System.out.println("高级会员的价格:" + advanceContext.calcPrice(300, 1));// 高级会员240
}
模板方法(Template Method)
定义一个操作中的算法骨架,而将一些步骤延迟到子类中。似的子类可以不改变一个算法的接口即可重新定义算法的某些特定步骤。
package templateMethod;
public abstract class AbstractClass {
// 基本方法
protected abstract void doSomething();
protected abstract void doAnything();
// 模板方法
public void templateMethod() {
/*
* 调用基本方法,完成相关的逻辑
*/
this.doSomething();
if (this.isDoAnything()) {
this.doAnything();
}
System.out.println(this.toString());
}
public boolean isDoAnything() {
return true;
}
}
public class ConcreteClass1 extends AbstractClass {
private boolean isFlag = true;
@Override
public void doSomething() {
System.out.println("我是1 doSomething");
}
@Override
public void doAnything() {
System.out.println("我是1 doAnything");
}
@Override
public boolean isDoAnything() {
return this.isFlag;
}
// 要不要doAnything,使用时决定
protected void setIsDoAnything(boolean isDo) {
this.isFlag = isDo;
}
}
public class ConcreteClass2 extends AbstractClass {
@Override
protected void doSomething() {
System.out.println("我是2 doSomething");
}
@Override
protected void doAnything() {
System.out.println("我是2 doSomething");
}
@Override
public boolean isDoAnything() {
return false;
}
}
public static void main(String[] args) {
AbstractClass class1 = new ConcreteClass1();
AbstractClass class2 = new ConcreteClass2();
((ConcreteClass1) class1).setIsDoAnything(false);
class1.templateMethod(); // 输出this代表的对象
System.out.println(class1.toString());
class2.templateMethod(); // 输出this代表的对象
System.out.println(class2.toString());
}
访问者(Visitor)
表示一个作用于某些对象结构中的各元素的操作,使得在不改变各元素的类的前提下定义作用于这些元素的新操作。
package visitor;
public abstract class Person {
// 提供一个方法,让访问者可以访问
public abstract void accept(Action action);
}
public class Man extends Person {
// 提供一个方法,让访问者可以访问
public void accept(Action action) {
action.getManResult(this);
}
}
public class Woman extends Person {
// 提供一个方法,让访问者可以访问
public void accept(Action action) {
action.getWomanResult(this);
}
}
public abstract class Action {
// 得到男性 的测评
public abstract void getManResult(Man man);
// 得到女的 测评
public abstract void getWomanResult(Woman woman);
}
public class Success extends Action {
@Override
public void getManResult(Man man) {
System.out.println(" 男人给的评价该歌手很成功 !");
}
@Override
public void getWomanResult(Woman woman) {
System.out.println(" 女人给的评价该歌手很成功 !");
}
}
public class Fail extends Action {
@Override
public void getManResult(Man man) {
System.out.println(" 男人给的评价该歌手失败 !");
}
@Override
public void getWomanResult(Woman woman) {
System.out.println(" 女人给的评价该歌手失败 !");
}
}
public class Wait extends Action {
@Override
public void getManResult(Man man) {
System.out.println(" 男人给的评价是该歌手待定 ..");
}
@Override
public void getWomanResult(Woman woman) {
System.out.println(" 女人给的评价是该歌手待定 ..");
}
}
public class ObjectStructure {
// 维护了一个集合
private List<Person> persons = new LinkedList<>();
// 增加到list
public void attach(Person p) {
persons.add(p);
}
// 移除
public void detach(Person p) {
persons.remove(p);
}
// 显示测评情况
public void display(Action action) {
for (Person p : persons) {
p.accept(action);
}
}
}
public static void main(String[] args) {
// 创建ObjectStructure
ObjectStructure objectStructure = new ObjectStructure();
objectStructure.attach(new Man());
objectStructure.attach(new Woman());
// 成功
Success success = new Success();
objectStructure.display(success);
System.out.println("===============");
Fail fail = new Fail();
objectStructure.display(fail);
System.out.println("=======给的是待定的测评========");
Wait wait = new Wait();
objectStructure.display(wait);
}