23种设计模式(JAVA)
为了对设计模型能够很好的运用并时常参考,为此在网络上进行了浏览和自己的整合
本文转自:http://blog.****.net/zhangerqing
设计模式就是一个软件的设计思想,为了升级和维护方便,降低依赖,降低耦合。不要死记硬背,要理解思想。
一、设计模式分类
总的分为三大类:
1、创建型模式(五种): 工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
2、结构型模式(七种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、亨元模式。
3、行为模式(十一种): 策略模式、摸版方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问模式、中介者模式、解释器模式。
4、还有两类模式:并发型模式和线程池模式。
二、设计模式的六大原则
1、开闭原则(Open Close Principle)
开闭原则就是对扩展开发,对修改关闭;为了使程序扩展性好,不能修改原代码,易于维护和升级。需要使用接口和抽象类。
2、里氏换代原则(Liskov Substitution Principle)
里氏换代原则是面向对象设计的基本原则之一。任何基类出现的地方,子类一定可以出现。当子类可以替换掉基类,程序不受影响时,基类才真正被复用,而子类也能在基类上增加新的行为。里氏换代原则是对实现抽象化的具体步骤规范。
3、依赖倒转原则(Dependence Inversion Principle)
针对接口编程,依赖于抽象而不是依赖于具体。
4、接口隔离原则(Interface Segregation Principle)
使用多个隔离接口,比使用单个接口要好,是为了降低类之间的耦合度。
5、迪米特法则(Demeter Principle)
迪米特法则也叫最少知道原则,一个实体应当减少与另一个实体发生相互作用,使得系统模块能够独立。
6、合成复用原则(Composite Reuse Principle)
尽量使用合成/聚合方式,而不是继承。
三、具体模式的讲解
1、工厂方法模式(Factory Method)
工厂方法模式分为三种:
1.1 普通工厂方法模式:建立一个工厂类,对实现了同一个接口的类进行实例创建。
举例如下:举一个发送短信和发送邮件的例子
//1.首先创建二者共同接口
public interface Sender{
public void send();
}
//2.创建邮件类
public class MailSender implements Sender{
@Override
public void send() {
System.out.println("发送邮件!");
}
}
//3.创建短信类
public class SmsSender implements Sender {
@Override
public void send() {
System.out.println("发送短信!");
}
}
//4.创建工厂类
public class SendFactory{
public 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 class FactoryTest {
public static void main(String[] args) {
SendFactory factory = new SendFactory();
Sender sender = factory.produce("sms");
sender.send();
}
}
输出结果:发送短信!
2、多个工厂方法模式:是普通工厂的改进版,普通工厂如果传递的字符串出错,则不能创建工厂,而多个工厂方法是创建多个工厂,分别创建对象。
//创建多个工厂(对普通工厂的改进)
public class SendFactory{
public Sender produceMail(){
return new MailSender();
}
public Sender produceSms(){
return new SmsSender();
}
}
//最后测试多个工厂
public class FactoryTest {
public static void main(String[] args) {
SendFactory factory = new SendFactory();
Sender sender = factory.produceSms();
sender.send();
}
}
输出结果:发送短信!
3、静态工厂方法模式:是工厂的改进版,将工厂方法设置为静态的,不需要创建实例,直接调用即可。
//创建静态工厂
public class SendFactory{
public static Sender produceMail(){
return new MailSender();
}
public static Sender produceSms(){
return new SmsSender();
}
}
//最后测试静态工厂
public class FactoryTest {
public static void main(String[] args) {
SendFactory factory = new SendFactory();
sender.send();
}
}
输出结果:发送短信!
总体来说,工厂方法模式适合:凡是出现了大量的产品需要创建,并有共同的接口时,通过工厂方法创建。以上三种工厂方法模式,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要创建对象,所以选用第三种。
2、抽象工厂模式(Abstract Factory)
抽象工厂是工厂方法的升级,因为工厂方法有一个弊端,想要扩展程序,就需要对工厂进行修改;为此用到了抽象工厂,抽象工厂就是创建多个工厂类,需要扩展程序时直接添加工厂即可。
//1.首先创建二者共同接口
public interface Sender{
public void send();
}
//2.创建邮件实现类
public class MailSender implements Sender{
@Override
public void send() {
System.out.println("发送邮件!");
}
}
//3.创建短信实现类
public class SmsSender implements Sender {
@Override
public void send() {
System.out.println("发送短信!");
}
}
//4.创建工厂类
public class SendMailFactory implements Provider{
@Override
public Sender produce() {
return new MailSender();
}
}
public class SendSmsFactory implements Provider{
@Override
public Sender produce() {
return new SmsSender();
}
}
//5.创建一个接口
public interface Provider{
public Sender produce();
}
//6.测试类
public class Text{
public static void main(String[] args) {
Provider provider=new SendSmsFactory();
Sender sender= provider.produce();
sender.send();
}
}
3、单例模式(Singleton)
单例模式:单例模式的类必须保证只有一个实例存在。单例模式还分为:懒汉式(只有外部对象第一次调用实例时才创建)、饿汉式(加载类比较慢,运行时得到对象速度比较快);单例模式的好处:(1)某些类创建比较频繁,对于大型对象,这是一笔很大的系统开销;(2)省去new操作符,降低系统内存使用频率,减少GC压力。
//1、饱汉式,线程不安全
public class Singleton{
//持有私有静态实例,防止被引用,目的是实现延迟加载
private static Singleton instance=null;
//定义私有的构造方法
private Singleton(){}
//获取实例的方法
public static Singleton getInstance(){
if (instance==null){
instance =new Singleton();
}
return instance;
}
//如果该对象被实例化,可以保证对象在实例化前后保持一致
public Object readResolve(){
return instance;
}
}
//2、对该方法改进(添加synchronized(同步锁)关键字)
//备注:synchronized是锁对象的,每次调用该方法都要给对象上锁,性能较低。
public static synchronized Singleton getInstance(){
if (instance==null){
instance =new Singleton();
}
return instance;
}
//3、对该方法改进,将synchronized(同步锁)方法内部,只有instance为null,并创建对象时才加锁,性能有所提高
public static Singleton getInstance(){
if (instance==null){
synchronized(instance){
if (instance==null){
instance =new Singleton();
}
}
}
return instance;
}
//4、改进单例模式最终结果(接近完美,但还有其它的实现方式)
public class Singleton{
//持有私有静态实例,防止被引用,目的是实现延迟加载
private static Singleton instance=null;
//定义私有的构造方法
private Singleton(){}
//创建内部类工厂
private static class SingletonFactory{
private static Singleton instance=new Singleton();
}
//获取实例的方法
//备注:该方法在第一次调用时是线程互斥的
public static Singleton getInstance(){
return SingletonFactory.instance;
}
//如果该对象被实例化,可以保证对象在实例化前后保持一致
public Object readResolve(){
return instance;
}
}
4、建造者模式(Builder)
建造者模式就是将各种类集中起来管理,创建复合对象,复合对象就是指某个类有不同的属性,建造者模式和工厂模式的区别就是:工厂模式关注的是创建单个类,而建造者模式是创建复合对象。
//建造者模式
public class Builder{
private List<Sender> list=new ArrayList<Sender>();
//发送邮件方法
public void produceMailSender(int count){
for (int i=0;i<count;i++){
list.add(new MailSender());
}
}
//发送短信方法
public void produceSmsSender(int count){
for (int i=0;i<count;i++){
list.add(new SmsSender());
}
}
}
public class Test{
public static void main(String[] args) {
Builder builder=new Builder();
builder.produceSmsSender(10);
}
}
5、原型模式(Prototype)
原型模式虽然是创建型模式,但与工厂模式无关,原型模式就是将一个对象作为原型,对其进行复制、克隆,产生一个新的对象,需要实现Cloneable接口,用clone()方法实现的( super.clone() );原型模式分为两种复制概念:浅复制和深复制。
1、浅复制:只会复制原有对象中的基本数据类型变量,而引用类型还是指向原有对象。
2、深复制:采用流的形式读取原对象的二进制输入,再写出二级制数据对应的对象。深复制会把原有对象中的数据类型全部复制,也就是完全彻底的复制。
public class Prototype implements Cloneable,Serializable{
private static final long serialVersionUID=1L;
private String string;
private SerializableObject obj;
//浅复制,只复制原有对象的基本数据类型变量
public Object clone() throws CloneNotSupportedException {
Prototype prototype=(Prototype) super.clone();
return prototype;
}
//深复制,用IO流复制所有属性
public Object deeClone() throws IOException, ClassNotFoundException {
//写入当前对象的二进制流
ByteArrayOutputStream bos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bos);
//读取二进制流产生对象
ByteArrayInputStream bis =new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois=new ObjectInputStream(bis);
return ois.readObject();
}
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
public SerializableObject getObj() {
return obj;
}
public void setObj(SerializableObject obj) {
this.obj = obj;
}
}
class SerializableObject implements Serializable{
private static final long serialVersionUID=1L;
}
6、适配器模式(Abapter)
适配器模式就是将类的接口转换成调用者期望的接口,消除接口不匹配和不兼容问题。主要有三类:类适配器模式、对象适配器模式、接口适配器模式。
//1、类适配器,有一个Source类,方法是method1(),目标接口是Targetable,通过Adapter类,将Source的功能扩展到Targetable
//使用场景:当希望将一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。
public class Source{
public void method1(){
System.out.print("这是第一个方法");
}
}
public interface Targetable{
//原类中的方法
public void method1();
//新类的方法
public void method2();
}
//类适配器,添加新的方法
public class Adapter extends Source implements Targetable{
@Override
public void method2() {
System.out.print("这是新类的方法");
}
}
//测试
public class AdapterTest{
public static void main(String[] args) {
Targetable targetable=new Adapter();
targetable.method1();
targetable.method2();
}
}
输出结果为:这是第一个方法
这是新类的方法
//2、对象适配器,对象适配器与类适配器模式一样,只需要改类的源码即可
//使用场景:希望将一个对象满足另一个新接口的对象时,创建一个类并持有原类的一个实例,在新类的方法中,调用实例的方法即可。
public class Wrapper implements Targetable{
private Source source;
public Wrapper(Source source){
super();
this.source=source;
}
@Override
public void method2() {
System.out.println("这是新加的方法!");
}
@Override
public void method1() {
source.method1();
}
}
public class AdapterTest{
public static void main(String[] args) {
Source source=new Source();
Targetable target=new Wrapper(source);
target.method1();
target.method2();
}
}
//3、接口适配器,创建一个abstract(抽象)类并实现接口,只需要把abstract(抽象)类提供给外部使用即可。
//使用场景:当不希望实现接口中所有方法时,可以创建一个抽象类,实现所有方法,调用时只需继承抽象类即可。
public interface Sourceable{
public void method1();
public void method2();
}
//创建抽象类
public abstract class Wrappper implements Sourceable{
public void method1(){}
public void method2(){}
}
public class SourceSub extends Wrappper{
public void method1(){
System.out.print("这是新的方法!");
}
}
//测试类
public class WrappperTest{
public static void main(String[] args) {
SourceSub ss=new SourceSub();
ss.method1();
}
}
输出结果:这是新的方法!
7、装饰模式(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 sourceable;
public Decorator(Sourceable sourceable){
super();
this.sourceable=sourceable;
}
@Override
public void method() {
System.out.print("开始!");
sourceable.method();
System.out.print("结束!");
}
}
//测试类
public class DecoratorTest{
public static void main(String[] args) {
Sourceable sourceable=new Sourceable();
Sourceable obj=new Decorator(sourceable);
obj.method();
}
}
输出结果:开始
被装饰类
结束
8、代理模式(Proxy)
代理模式就是用一个代理类调用原有的方法,且对产生的结果进行控制;比如在法院打官司时需要找律师,因为律师在法律方面比较专业,这就是代理。
//使用场景:需要对原有的方法进行改进,并需要对产生的结果进行控制,为此就需要代理。
public interface Sourceable{
public void method();
}
//实现类
public class Soure implements Sourceable{
@Override
public void method() {
System.out.print("这是接口的方法");
}
}
//创建代理模式
public class Proxy implements Sourceable{
private Soure soure;
public Proxy(){
super();
this.soure=new Soure();
}
@Override
public void method() {
atfer();
soure.method();
before();
}
private void atfer(){
System.out.print("atfer proxy");
}
private void before(){
System.out.print("before proxy");
}
}
//测试类
public class ProxyTest{
public static void main(String[] args) {
Sourceable soure=new Proxy();
soure.method();
}
}
9、外观模式(Facade)
外观模式是为解决类与类之间依赖关系的,外观模式就是将类之间的关系放在一起,降低类与类之间的耦合度,并实现解耦作用,这就是外观模式。
public class CPU{
public void startup(){
System.out.print("CPU startup");
}
public void shutdown(){
System.out.print("CPU shutdown");
}
}
public class Memory{
public void startup(){
System.out.print("Memory startup");
}
public void shutdown(){
System.out.print("Memory shutdown");
}
}
public class Disk {
public void startup(){
System.out.print("Disk startup");
}
public void shutdown(){
System.out.print("Disk shutdown");
}
}
//外观模式
public class Computer{
private CPU cpu;
private Memory memory;
private Disk disk;
public Computer(){
cpu=new CPU();
memory=new Memory();
disk=new Disk();
}
public void startup(){
System.out.print("start the computer!");
cpu.startup();
memory.startup();
disk.startup();
System.out.print("start computer finished!");
}
public void shutdown(){
System.out.print("begin to close the computer!");
cpu.startup();
memory.startup();
disk.startup();
System.out.print("computer closed!");
}
}
//测试类
public class User{
public static void main(String[] args) {
Computer computer=new Computer();
computer.shutdown();
computer.startup();
}
}
10、桥连接模式(Bridge)
桥链接模式就是把事物和具体实现分开,使各模块各自独立化;与JDBC原理一样。JDBC原理就是有一个统一的接口,每种数据库实现接口即可。
//1.定义统一的接口
public interface Sourceable{
public void method();
}
//2.第一个实现类
public class SourceSub1 implements Sourceable{
@Override
public void method() {
System.out.print("第一个实现类");
}
}
//3.第二个实现类
public class SourceSub2 implements Sourceable{
@Override
public void method() {
System.out.print("第二个实现类");
}
}
//4.定义桥连接
public abstract class Bridge{
private Sourceable sourceable;
public void method(){
sourceable.method();
}
public Sourceable getSourceable() {
return sourceable;
}
public void setSourceable(Sourceable sourceable) {
this.sourceable = sourceable;
}
}
//5.
public class MyBridge extends Bridge{
public void method(){
getSourceable().method();
}
}
//6.测试类
public class BridgeTest{
public static void main(String[] args) {
Bridge bridge=new MyBridge();
//调用第一个对象
SourceSub1 sourceSub1=new SourceSub1();
bridge.setSourceable(sourceSub1);
bridge.method();
//调用第二个对象
SourceSub2 sourceSub2=new SourceSub2();
bridge.setSourceable(sourceSub2);
bridge.method();
}
}
输出结果:第一个实现类
第二个实现类
11、组合模式(Composite)
组合模式又叫 部分-整体模式,在处理树形结构的问题时比较方便,常用与树形结构,二叉树等。
//将多个对象组合一起进行操作,常用于树形结构,比如二叉树
public class TreeNode {
private String name;
private TreeNode parent;
private Vector<TreeNode> children=new Vector<TreeNode>();
//set和get方法省略
//添加子节点
public void add(TreeNode t){
children.add(t);
}
//删除子节点
public void remove(TreeNode t){
children.remove(t);
}
//获取子节点
public Enumeration<TreeNode> getChildren(){
return children.elements();
}
}
//测试类
public class Tree{
TreeNode root=null;
public Tree(String name){
root=new TreeNode(name);
}
public static void main(String[] args) {
Tree tree=new Tree("A");
TreeNode t1=new TreeNode("B");
TreeNode t2=new TreeNode("C");
t1.add(t2);
tree.root.add(t1);
System.out.print("build the tree finished!");
}
}
12、亨元模式(Flyweight)
亨元模式主要目的是实现对象的共享,即共享池。通常与工厂模式一起使用,比如连接数据库的JDBC连接池。适用于共享的对象,都有一些共有属性。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Vector;
//以JDBC连接池举例,该模式适用于 共享对象
public class ConnectionPool {
private Vector<Connection> pool;
//共有属性
private String url="jdbc:mysql://localhost:3306/test";
private String username="root";
private String password="root";
private String driverClassName="com.mysql.jdbc.Driver";
private int poolSize=100;
private static ConnectionPool instance=null;
Connection conn=null;
//构造方法,做一些初始化工作
private ConnectionPool(){
pool=new Vector<Connection>(poolSize);
for (int i = 0; i <poolSize ; i++) {
try{
Class.forName(driverClassName);
conn= DriverManager.getConnection(url,username,password);
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (SQLException e){
e.printStackTrace();
}
}
}
//返回连接池
public synchronized void release(){
pool.add(conn);
}
//返回连接池中的一个数据库连接
public synchronized Connection getConnection(){
if (pool.size()>0){
Connection conn=pool.get(0);
pool.remove(conn);
return conn;
}else {
return null;
}
}
}
13、策略模式(strategy) 属于父类和子类的实现
策略模式定义了一系列算法,并将每个算法封装起来,使其可以相互替换,且算法的变化不会影响到用户。设计一个接口,为一系列实现类提供统一方法,设计一个抽象类(可有可无,属于辅助类),提供辅助函数,使用算法的决定权在用户,该模式多用在算法中。
//该模式主要适用于算法封装,决定权在用户
//1.定义统一接口
public interface ICalculator{
public int calculate(String exp);
}
//2.定义辅助类
public class AbstractCalculator {
public int[] split(String exp,String opt){
String array[] = exp.split(opt);
int arrayInt[] = new int[2];
arrayInt[0] = Integer.parseInt(array[0]);
arrayInt[1] = Integer.parseInt(array[1]);
return arrayInt;
}
}
//3.定义两个实现类
public class Plus extends AbstractCalculator implements ICalculator {
@Override
public int calculate(String exp) {
int arrayInt[] = split(exp,"\\+");
return arrayInt[0]+arrayInt[1];
}
}
public class Minus extends AbstractCalculator implements ICalculator {
@Override
public int calculate(String exp) {
int arrayInt[] = split(exp,"-");
return arrayInt[0]-arrayInt[1];
}
}
//测试类
public class StrategyTest{
public static void main(String[] args) {
String exp = "2+8";
ICalculator cal = new Plus();
int result = cal.calculate(exp);
System.out.println(result);
}
}
输出结果为:10
14、摸版方法模式(Template Method) 属于父类和子类的实现
摸版方法模式:一个抽象类中,有一个主方法,在定义多个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,通过调用抽象类,实现子类的调用。
//1.定义一个抽象类
public abstract class AbstractCalculator {
//主方法,实现对本类其他方法的调用
public final int calculate(String exp,String opt){
int array[] =split(exp,opt);
return calculate(array[0],array[1]);
}
//被子类重写的方法
abstract public int calculate(int num1,int num2);
public int[] split(String exp,String opt){
String array[] = exp.split(opt);
int arrayInt[] = new int[2];
arrayInt[0] = Integer.parseInt(array[0]);
arrayInt[1] = Integer.parseInt(array[1]);
return arrayInt;
}
}
//2.继承抽象类并重写方法
public class Plus extends AbstractCalculator{
@Override
public int calculate(int num1, int num2) {
return num1+num2;
}
}
//3.测试
public class StrategyTest {
public static void main(String[] args) {
String exp = "8+8";
AbstractCalculator cal = new Plus();
int result = cal.calculate(exp, "\\+");
System.out.println(result);
}
}
15、观察者模式(Observer) 属于两个类之间的实现
观察者模式:就是当一个对象变化时,依赖本对象的类都会收到通知,并且随着变化!对象之间是一对多的关系。
import java.util.Enumeration;
import java.util.Vector;
//1.定义一个接口
public interface Observer {
public void update();
}
//2.第一个实现类
public class Observer1 implements Observer {
@Override
public void update() {
System.out.println("observer1 has received!");
}
}
//3.第二个实现类
public class Observer2 implements Observer {
@Override
public void update() {
System.out.println("observer2 has received!");
}
}
//4.定义接口
public interface Subject{
/*增加观察者*/
public void add(Observer observer);
/*删除观察者*/
public void del(Observer observer);
/*通知所有的观察者*/
public void notifyObservers();
/*自身的操作*/
public void operation();
}
//5.定义监控对象列表类
public abstract class AbstractSubject implements Subject {
private Vector<Observer> vector = new Vector<Observer>();
@Override
public void add(Observer observer) {
vector.add(observer);
}
@Override
public void del(Observer observer) {
vector.remove(observer);
}
@Override
public void notifyObservers() {
Enumeration<Observer> enumo=vector.elements();
while (enumo.hasMoreElements()){
enumo.nextElement().update();
}
}
}
//6.定义主对象
public class MySubject extends AbstractSubject {
@Override
public void operation() {
System.out.print("update self!");
notifyObservers();
}
}
//7.测试类
public class ObserverTest{
public static void main(String[] args) {
Subject sub=new MySubject();
sub.add(new Observer1());
sub.add(new Observer2());
sub.notifyObservers();
}
}
输出: update self!
observer1 has received!
observer2 has received!
16、迭代子模式(Iterator) 属于两个类之间的实现
迭代器模式就是顺序访问聚集中的对象,第一就是遍历聚集的对象,第二就是对聚集的对象进行遍历访问。
//模拟集合类的过程
//1.定义操作集合类的接口
public interface Collection {
public Iterator iterator();
//取集合元素
public Object get(int i);
//取大小
public int size();
}
//2.定义迭代遍历集合类的接口
public interface Iterator{
//前移
public Object previous();
//后移
public Object next();
public boolean hasNext();
//取最后一个元素
public Object first();
}
//3.实现操作集合类的接口
public class MyCollection implements Collection{
public String string[]={"A","B","C","D","E"};
@Override
public Iterator iterator() {
return new MyIterator(this);
}
@Override
public Object get(int i) {
return string[i];
}
@Override
public int size() {
return string.length;
}
}
//4.实现迭代遍历集合的接口
public class MyIterator implements Iterator{
private Collection collection;
private int pos=-1;
public MyIterator(Collection collection){
this.collection=collection;
}
@Override
public Object previous() {
if (pos>0){
pos--;
}
return collection.get(pos);
}
@Override
public Object next() {
if (pos<collection.size()-1){
pos++;
}
return collection.get(pos);
}
@Override
public boolean hasNext() {
if (pos<collection.size()-1){
return true;
}else {
return false;
}
}
@Override
public Object first() {
pos=0;
return collection.get(pos);
}
}
//测试
public class Test{
public static void main(String[] args) {
Collection collection=new MyCollection();
Iterator it=collection.iterator();
while (it.hasNext()){
System.out.print(it.next());
}
}
}
//打印结果:A B C D E
17、责任链模式(Chain of Responsibility) 属于两个类之间的实现
责任链模式:有多个对象,每个对象持有对下一个对象的引用,请求在链上传递,直到某一个对象决定处理该请求。但发送请求者并不知道那个对象会处理该请求。链接上的一个请求可以是一条链,一个树,一个环。这个些需要我们自己去实现,在一个时刻,命令只允许由一个对象传给另一个对象,而不允许传给多个对象。
//1.创建一个设置和修改引用对象的核心接口
public interface Handler{
public void operator();
}
//2.创建私有的方法类
public abstract class AbstractHandler{
private Handler handler;
public Handler getHandler() {
return handler;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
}
//3.创建实现核心接口的类
public class MyHandler extends AbstractHandler implements Handler{
private String name;
public MyHandler(String name){
this.name=name;
}
@Override
public void operator() {
System.out.print(name+"deal!");
if (getHandler() !=null){
getHandler().operator();
}
}
}
//测试类
public class Test{
public static void main(String[] args) {
MyHandler h1 = new MyHandler("h1");
MyHandler h2 = new MyHandler("h2");
MyHandler h3 = new MyHandler("h3");
h1.setHandler(h2);
h2.setHandler(h3);
h1.operator();
}
}
//输出: h1deal!
h2deal!
h3deal!
18、命令模式(Command) 属于两个类之间的实现
命令模式就是:命令的发出者和执行者之间解耦,实现请求和执行分开。举个例子,比如司令员下令让士兵干件事情,口令传到士兵哪里并去执行,司令员只要结果,不关心执行过程。
//1.定义命令方法的接口
public interface Command{
public void exe();
}
//2.实现命令方法接口的实现类(核心类)
public class MyCommand implements Command{
private Recciver recciver;
public MyCommand(Recciver recciver){
this.recciver=recciver;
}
@Override
public void exe() {
recciver.action();
}
}
//3.创建士兵类
public class Recciver{
public void action(){
System.out.print("士兵执行命令!");
}
}
//4.创建司令员类
public class Invoker{
private Command command;
public Invoker(Command command){
this.command=command;
}
public void adtion(){
System.out.print("司令员发出命令!");
}
}
//测试类
public class Test{
public static void main(String[] args) {
Recciver recciver=new Recciver();
Command cmd=new MyCommand(recciver);
Invoker invoker=new Invoker(cmd);
invoker.adtion();
}
}
//输出:士兵执行命令!
19、备忘录模式(Memento) 类的状态
备忘录状态:就是要保存对象的某个状态,在适当的时候恢复对象。
//1.创建原始类
public class Original {
private String value; //需要保存的属性
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Original(String value) {
this.value = value;
}
//创建备忘录类
public Memento creatememento() {
return new Memento(value);
}
public void restoreMemento(Memento memento) {
this.value = memento.getValue();
}
}
//2.创建备忘录类
public class Memento{
private String value;
public Memento(String value){
this.value=value;
}
public String getValue() { return value;}
public void setValue(String value) {this.value = value;}
}
//3.创建存储备忘录类
public class Storage{
private Memento memento;
public Storage(Memento memento){
this.memento=memento;
}
public Memento getMemento() {return memento; }
public void setMemento(Memento memento) {this.memento = memento;}
}
//测试类
public class Test{
public static void main(String[] args) {
//创建原始类
Original original=new Original("agg");
//创建备忘录类
Storage storage=new Storage(original.creatememento());
//修改原始类状态
System.out.print("初始化状态为:"+original.getValue());
original.setValue("niu");
System.out.print("修改后的状态为:"+original.getValue());
//恢复原始类状态
original.restoreMemento(storage.getMemento());
System.out.print("恢复后的状态为:"+original.getValue());
}
}
// 输出结果为:初始状态为:egg
修改后的状态为:niu
恢复后的状态为:egg
20、状态模式(State) 类的状态
状态模式:当对象改变状态时,同时改变其行为,并且每个状态对应不同的操作。
//1.创建状态的核心类
public class State{
private String value;
public String getValue() {return value;}
public void setValue(String value) {this.value = value;}
public void method1(){System.out.print("execute the first opt!");}
public void method2(){System.out.print("execute the second opt!");}
}
//2.创建状态模式的切换类
public class Context{
private State state;
public Context(State state){this.state=state;}
public State getState() {return state;}
public void setState(State state) {this.state = state;}
public void method(){
if (state.getValue().equals("state1")){
state.method1();
}else if (state.getValue().equals("state2")){
state.method2();
}
}
}
//测试类
public class Test{
public static void main(String[] args) {
State state=new State();
Context context=new Context(state);
//设置第一种状态
state.setValue("state1");
context.method();
//设置第二种状态
state.setValue("state2");
context.method();
}
}
//输出结果:execute the first opt!
execute the second opt!
21、访问者模式(Visitor) 通过中间类
访问者模式就是把数据结构和操作解耦合,使操作集合相对*的演化。总的来说该模式添加数据结构很困难,添加操作很容易,并不会影响其它的操作效果。
//1创建存放要访问的对象接口
public interface Visitor{
public void visit(Subject sub);
}
//2.创建实现要访问对象接口的实现类
public class MyVisitor implements Visitor{
@Override
public void visit(Subject sub) {
System.out.print("visit the subject:"+sub.getSubject());
}
}
//3.创建访问的对象接口
public interface Subject{
//接受将要访问它的对象
public void accept(Visitor visitor);
//获取将要被访问的属性
public String getSubject();
}
//4.创建实现访问对象的实现类
public class MySubject implements Subject{
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
@Override
public String getSubject() {
return "love";
}
}
//测试类
public class Test{
public static void main(String[] args) {
Visitor visitor=new MyVisitor();
Subject sub=new MySubject();
sub.accept(visitor);
}
}
//输出:visit the subject:love
22、中介者模式(Mediator) 通过中间类
中介者模式就是降低类与类之间的耦合,类与类的关系与调度交给中间类就行,类似有Spring的容器。
//1.创建中间类的接口
public interface Mediator{
public void createMediator();
public void workAll();
}
//2.创建中间类的实现类
public class MyMediator implements Mediator{
private User user1;
private User user2;
public User getUser1(){return user1;}
public User getUser2(){return user2;}
@Override
public void createMediator() {
user1=new User1(this);
user2=new User2(this);
}
@Override
public void workAll() {
user1.work();
user2.work();
}
}
//3.创建私有的类
public abstract class User{
private Mediator mediator;
public Mediator getMediator(){return mediator;}
public User(Mediator mediator){
this.mediator=mediator;
}
public abstract void work();
}
//4.创建私有类的继承类
public class User1 extends User{
public User1(Mediator mediator){super(mediator);}
@Override
public void work() {
System.out.print("执行user1类!");
}
}
//5.创建私有类的继承类
public class User2 extends User{
public User2(Mediator mediator){super(mediator);}
@Override
public void work() {
System.out.print("执行user2类!");
}
}
//测试类
public class Test{
public static void main(String[] args) {
Mediator mediator=new MyMediator();
mediator.createMediator();
mediator.workAll();
}
}
//输出:执行user1类!
执行user2类!
23、解释器模式(Interpreter) 通过中间类
解释器模式用来做各种各样的解释器,一般应用在OOP开发中的编译器,比如:正则表达式解释器等。
//.创建计算 的接口
public interface Expression{
public int interpret(Context context);
}
//2.创建 实现计算类
public class Plus implements Expression{
@Override
public int interpret(Context context) {
return context.num1+context.num2;
}
}
//3.创建 实现计算类
public class Minus implements Expression{
@Override
public int interpret(Context context) {
return context.num1-context.num2;
}
}
//4.创建上下文环境类
public class Context{
private int num1;
private int num2;
public Context(int num1,int num2){
this.num1=num1;
this.num2=num2;
}
//get和set方法省略
}
//测试类
public class Text{
public static void main(String[] args) {
//计算9+2-8的值
int result=new Minus().interpret((new Context(new Plus().interpret(new Context(9,2)),8)));
System.out.print(result);
}
}
//输出结果:3