读完本文,你会有一个最佳的答案。html
Adapter:java
Bridge:
把抽象和实现解藕,因而接口和实现可在彻底独立开来。程序员
Composite:
让使用者把单独的对象和组合对象混用。web
Decorator:
为一个对象动态的加上一系列的动做,而不须要由于这些动做的不一样而产生大量的继承类。这个模式在JDK中几乎无处不在,因此,下面的列表只是一些典型的。面试
Facade:
用一个简单的接口包状一组组件,接口,抽象或是子系统。算法
Flyweight:
有效率地存储大量的小的对象。spring
Proxy:
用一个简单的对象来代替一个复杂的对象。sql
Abstract factory:**数据库
Builder:
主要用来简化一个复杂的对象的建立。这个模式也能够用来实现一个 Fluent Interface。编程
Factory:
简单来讲,按照需求返回一个类型的实例。
Prototype:
使用本身的实例建立另外一个实例。有时候,建立一个实例而后再把已有实例的值拷贝过去,是一个很复杂的动做。因此,使用这个模式能够避免这样的复杂性。
Singleton:
只容许一个实例。在 Effective Java中建议使用Emun.
Chain of responsibility:
把一个对象在一个连接传递直到被处理。在这个链上的全部的对象有相同的接口(抽象类)但却有不一样的实现。
Command:
把一个或一些命令封装到一个对象中。
Interpreter:
一个语法解释器的模式。
Iterator:
提供一种一致的方法来顺序遍历一个容器中的全部元素。
Mediator:
用来减小对象单的直接通信的依赖关系。使用一个中间类来管理消息的方向。
Memento:
给一个对象的状态作一个快照。Date类在内部使用了一个long型来作这个快照。
Null Object:
这个模式用来解决若是一个Collection中没有元素的状况。
Observer:
容许一个对象向全部的侦听的对象广播本身的消息或事件。
State:
这个模式容许你能够在运行时很容易地根据自身内部的状态改变对象的行为。
Strategy:
定义一组算法,并把其封装到一个对象中。而后在运行时,能够灵活的使用其中的一个算法。
Template method:
容许子类重载部分父类而不须要彻底重写。
Visitor:
做用于某个对象群中各个对象的操做. 它可使你在不改变这些对象自己的状况下,定义做用于这些对象的新操做.
MVC 模式表明 Model-View-Controller(模型-视图-控制器) 模式。这种模式用于应用程序的分层开发。
拦截过滤器模式(Intercepting Filter Pattern)用于对应用程序的请求或响应作一些预处理/后处理。定义过滤器,并在把请求传给实际目标应用程序以前应用在请求上。过滤器能够作认证/受权/记录日志,或者跟踪请求,而后把请求传给相应的处理程序。如下是这种设计模式的实体。
咱们将建立 FilterChain、FilterManager、Target、Client 做为表示实体的各类对象。AuthenticationFilter 和 DebugFilter 表示实体过滤器。
InterceptingFilterDemo,咱们的演示类使用 Client 来演示拦截过滤器设计模式。
建立过滤器接口 Filter。
Filter.java
public interface Filter { void execute(String request); } 12345
建立实体过滤器。
AuthenticationFilter.java
public class AuthenticationFilter implements Filter { @Override public void execute(String request){ System.out.println("Authenticating request: " + request); } }
DebugFilter.java
public class DebugFilter implements Filter { @Override public void execute(String request){ System.out.println("request log: " + request); } }
建立 Target。
Target.java
*/ public class Target { public void execute(String request){ System.out.println("Executing request: " + request); } }
建立过滤器链。
FilterChain.java
public class FilterChain { private List<Filter> filters = new ArrayList(); private Target target; public void addFilter(Filter filter){ filters.add(filter); } public void execute(String request){ for (Filter filter : filters) { filter.execute(request); } target.execute(request); } public void setTarget(Target target){ this.target = target; } }
建立过滤管理器。
FilterManager.java
public class FilterManager { FilterChain filterChain; public FilterManager(Target target){ filterChain = new FilterChain(); filterChain.setTarget(target); } public void setFilter(Filter filter){ filterChain.addFilter(filter); } public void filterRequest(String request){ filterChain.execute(request); } }
建立客户端 Client。
Client.java
public class Client { FilterManager filterManager; public void setFilterManager(FilterManager filterManager){ this.filterManager = filterManager; } public void sendRequest(String request){ filterManager.filterRequest(request); } }
使用 Client 来演示拦截过滤器设计模式。
InterceptingFilterDemo.java
public class InterceptingFilterPatternDemo { public static void main(String[] args) { FilterManager filterManager = new FilterManager(new Target()); filterManager.setFilter(new AuthenticationFilter()); filterManager.setFilter(new DebugFilter()); Client client = new Client(); client.setFilterManager(filterManager); client.sendRequest("HOME"); } }
验证输出。
Authenticating request: HOME request log: HOME Executing request: HOME
优势:
缺点:
private static boolean flag = false; private Singleton() { if (flag == false) { flag = !flag; } else { throw new RuntimeException("单例模式被侵犯!"); } } public static void main(String[] args) { }
(主要使用懒汉和懒汉式)
package com.lijie; //饿汉式 public class Demo1 { // 类初始化时,会当即加载该对象,线程安全,调用效率高 private static Demo1 demo1 = new Demo1(); private Demo1() { System.out.println("私有Demo1构造参数初始化"); } public static Demo1 getInstance() { return demo1; } public static void main(String[] args) { Demo1 s1 = Demo1.getInstance(); Demo1 s2 = Demo1.getInstance(); System.out.println(s1 == s2); } }
package com.lijie; //懒汉式 public class Demo2 { //类初始化时,不会初始化该对象,真正须要使用的时候才会建立该对象。 private static Demo2 demo2; private Demo2() { System.out.println("私有Demo2构造参数初始化"); } public synchronized static Demo2 getInstance() { if (demo2 == null) { demo2 = new Demo2(); } return demo2; } public static void main(String[] args) { Demo2 s1 = Demo2.getInstance(); Demo2 s2 = Demo2.getInstance(); System.out.println(s1 == s2); } }
package com.lijie; // 静态内部类方式 public class Demo3 { private Demo3() { System.out.println("私有Demo3构造参数初始化"); } public static class SingletonClassInstance { private static final Demo3 DEMO_3 = new Demo3(); } // 方法没有同步 public static Demo3 getInstance() { return SingletonClassInstance.DEMO_3; } public static void main(String[] args) { Demo3 s1 = Demo3.getInstance(); Demo3 s2 = Demo3.getInstance(); System.out.println(s1 == s2); } }
package com.lijie; //使用枚举实现单例模式 优势:实现简单、枚举自己就是单例,由jvm从根本上提供保障!避免经过反射和反序列化的漏洞 缺点没有延迟加载 public class Demo4 { public static Demo4 getInstance() { return Demo.INSTANCE.getInstance(); } public static void main(String[] args) { Demo4 s1 = Demo4.getInstance(); Demo4 s2 = Demo4.getInstance(); System.out.println(s1 == s2); } //定义枚举 private static enum Demo { INSTANCE; // 枚举元素为单例 private Demo4 demo4; private Demo() { System.out.println("枚举Demo私有构造参数"); demo4 = new Demo4(); } public Demo4 getInstance() { return demo4; } } }
package com.lijie; //双重检测锁方式 public class Demo5 { private static Demo5 demo5; private Demo5() { System.out.println("私有Demo4构造参数初始化"); } public static Demo5 getInstance() { if (demo5 == null) { synchronized (Demo5.class) { if (demo5 == null) { demo5 = new Demo5(); } } } return demo5; } public static void main(String[] args) { Demo5 s1 = Demo5.getInstance(); Demo5 s2 = Demo5.getInstance(); System.out.println(s1 == s2); } }
单例模式是 Java 中最简单的设计模式之一。这种类型的设计模式属于建立型模式,它提供了一种建立对象的最佳方式。
这种模式涉及到一个单一的类,该类负责建立本身的对象,同时确保只有单个对象被建立。这个类提供了一种访问其惟一的对象的方式,能够直接访问,不须要实例化该类的对象。
注意:
一、单例类只能有一个实例。
二、单例类必须本身建立本身的惟一实例。
三、单例类必须给全部其余对象提供这一实例。
明肯定义后,看一下代码:
public class SingletonEH { /** *是否 Lazy 初始化:否 *是否多线程安全:是 *实现难度:易 *描述:这种方式比较经常使用,但容易产生垃圾对象。 *优势:没有加锁,执行效率会提升。 *缺点:类加载时就初始化,浪费内存。 *它基于 classloder 机制避免了多线程的同步问题, * 不过,instance 在类装载时就实例化,虽然致使类装载的缘由有不少种, * 在单例模式中大多数都是调用 getInstance 方法, * 可是也不能肯定有其余的方式(或者其余的静态方法)致使类装载, * 这时候初始化 instance 显然没有达到 lazy loading 的效果。 */ private static SingletonEH instance = new SingletonEH(); private SingletonEH (){} public static SingletonEH getInstance() { System.out.println("instance:"+instance); System.out.println("加载饿汉式...."); return instance; } }
饿汉就是类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了。
public class SingletonLH { /** *是否 Lazy 初始化:是 *是否多线程安全:否 *实现难度:易 *描述:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。由于没有加锁 synchronized,因此严格意义上它并不算单例模式。 *这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工做。 */ private static SingletonLH instance; private SingletonLH (){} public static SingletonLH getInstance() { if (instance == null) { instance = new SingletonLH(); } return instance; } }
而懒汉比较懒,只有当调用getInstance的时候,才回去初始化这个单例。
一、线程安全:
饿汉式天生就是线程安全的,能够直接用于多线程而不会出现问题,
懒汉式自己是非线程安全的,为了实现线程安全有几种写法。
例:
public class SingletonLHsyn { /** *是否 Lazy 初始化:是 *是否多线程安全:是 *实现难度:易 *描述:这种方式具有很好的 lazy loading,可以在多线程中很好的工做,可是,效率很低,99% 状况下不须要同步。 *优势:第一次调用才初始化,避免内存浪费。 *缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。 *getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)。 */ private static SingletonLHsyn instance; private SingletonLHsyn (){} public static synchronized SingletonLHsyn getInstance() { if (instance == null) { instance = new SingletonLHsyn(); } return instance; } }
二、资源加载和性能:
饿汉式在类建立的同时就实例化一个静态对象出来,无论以后会不会使用这个单例,都会占据必定的内存,可是相应的,在第一次调用时速度也会更快,由于其资源已经初始化完成。
而懒汉式顾名思义,会延迟加载,在第一次使用该单例的时候才会实例化对象出来,第一次调用时要作初始化,若是要作的工做比较多,性能上会有些延迟,以后就和饿汉式同样了。
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
主要解决:一个全局使用的类频繁地建立与销毁。
什么时候使用:当您想控制实例数目,节省系统资源的时候。
如何解决:判断系统是否已经有这个单例,若是有则返回,若是没有则建立。
关键代码:构造函数是私有的。
应用实例:
一、一个党只能有一个主席。
二、Windows是多进程多线程的,在操做一个文件的时候,就不可避免地出现多个进程或线程同时操做一个文件的现象,因此全部文件的处理必须经过惟一的实例来进行。
三、一些设备管理器经常设计为单例模式,好比一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。
优势:
一、在内存里只有一个实例,减小了内存的开销,尤为是频繁的建立和销毁实例(好比管理学院首页页面缓存)。
二、避免对资源的多重占用(好比写文件操做)。
缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
使用场景:
一、要求生产惟一序列号。
二、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
三、建立的一个对象须要消耗的资源过多,好比 I/O 与数据库的链接等。 注意事项:getInstance() 方法中须要使用同步锁,synchronized (Singleton.class) 防止多线程同时进入形成instance 被屡次实例化。
1.Spring IOC
2.为何Spring IOC要使用工厂设计模式建立Bean呢
简单工厂 :用来生产同一等级结构中的任意产品。(不支持拓展增长产品) 工厂方法 :用来生产同一等级结构中的固定产品。(支持拓展增长产品) 抽象工厂 :用来生产不一样产品族的所有产品。(不支持拓展增长产品;支持增长产品族) 123 我下面来使用代码演示一下:
什么是简单工厂模式
代码演示:
package com.lijie; public interface Car { public void run(); }
package com.lijie; public class Bmw implements Car { public void run() { System.out.println("我是宝马汽车..."); } }
package com.lijie; public class AoDi implements Car { public void run() { System.out.println("我是奥迪汽车.."); } }
package com.lijie; public class CarFactory { public static Car createCar(String name) { if ("".equals(name)) { return null; } if(name.equals("奥迪")){ return new AoDi(); } if(name.equals("宝马")){ return new Bmw(); } return null; } }
package com.lijie; public class Client01 { public static void main(String[] args) { Car aodi =CarFactory.createCar("奥迪"); Car bmw =CarFactory.createCar("宝马"); aodi.run(); bmw.run(); } }
单工厂的优势/缺点
什么是工厂方法模式
代码演示:
package com.lijie; public interface Car { public void run(); }
package com.lijie; public interface CarFactory { Car createCar(); }
package com.lijie; public class AoDi implements Car { public void run() { System.out.println("我是奥迪汽车.."); } }
package com.lijie; public class Bmw implements Car { public void run() { System.out.println("我是宝马汽车..."); } }
package com.lijie; public class AoDiFactory implements CarFactory { public Car createCar() { return new AoDi(); } }
package com.lijie; public class BmwFactory implements CarFactory { public Car createCar() { return new Bmw(); } }
package com.lijie; public class Client { public static void main(String[] args) { Car aodi = new AoDiFactory().createCar(); Car jili = new BmwFactory().createCar(); aodi.run(); jili.run(); } }
什么是抽象工厂模式
package com.lijie; //汽车 public interface Car { void run(); } class CarA implements Car{ public void run() { System.out.println("宝马"); } } class CarB implements Car{ public void run() { System.out.println("摩拜"); } }
package com.lijie; //发动机 public interface Engine { void run(); } class EngineA implements Engine { public void run() { System.out.println("转的快!"); } } class EngineB implements Engine { public void run() { System.out.println("转的慢!"); } }
package com.lijie; public interface TotalFactory { // 建立汽车 Car createChair(); // 建立发动机 Engine createEngine(); } //总工厂实现类,由他决定调用哪一个工厂的那个实例 class TotalFactoryReally implements TotalFactory { public Engine createEngine() { return new EngineA(); } public Car createChair() { return new CarA(); } }
package com.lijie; public class Test { public static void main(String[] args) { TotalFactory totalFactory2 = new TotalFactoryReally(); Car car = totalFactory2.createChair(); car.run(); TotalFactory totalFactory = new TotalFactoryReally(); Engine engine = totalFactory.createEngine(); engine.run(); } }
什么是静态代理
代码演示:
package com.lijie; //接口类 public class UserDao{ public void save() { System.out.println("保存数据方法"); } } 12345678 package com.lijie; //运行测试类 public class Test{ public static void main(String[] args) { UserDao userDao = new UserDao(); userDao.save(); } }
修改代码,添加代理类
package com.lijie; //代理类 public class UserDaoProxy extends UserDao { private UserDao userDao; public UserDaoProxy(UserDao userDao) { this.userDao = userDao; } public void save() { System.out.println("开启事物..."); userDao.save(); System.out.println("关闭事物..."); } } 1234567891011121314151617 //添加完静态代理的测试类 public class Test{ public static void main(String[] args) { UserDao userDao = new UserDao(); UserDaoProxy userDaoProxy = new UserDaoProxy(userDao); userDaoProxy.save(); } }
什么是动态代理
package com.lijie; //接口 public interface UserDao { void save(); } 123456 package com.lijie; //接口实现类 public class UserDaoImpl implements UserDao { public void save() { System.out.println("保存数据方法"); } }
package com.lijie; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; // 每次生成动态代理类对象时,实现了InvocationHandler接口的调用处理器对象 public class InvocationHandlerImpl implements InvocationHandler { // 这其实业务实现类对象,用来调用具体的业务方法 private Object target; // 经过构造函数传入目标对象 public InvocationHandlerImpl(Object target) { this.target = target; } //动态代理实际运行的代理方法 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("调用开始处理"); //下面invoke()方法是以反射的方式来建立对象,第一个参数是要建立的对象,第二个是构成方法的参数,由第二个参数来决定建立对象使用哪一个构造方法 Object result = method.invoke(target, args); System.out.println("调用结束处理"); return result; } }
package com.lijie; import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { // 被代理对象 UserDao userDaoImpl = new UserDaoImpl(); InvocationHandlerImpl invocationHandlerImpl = new InvocationHandlerImpl(userDaoImpl); //类加载器 ClassLoader loader = userDaoImpl.getClass().getClassLoader(); Class<?>[] interfaces = userDaoImpl.getClass().getInterfaces(); // 主要装载器、一组接口及调用处理动态代理实例 UserDao newProxyInstance = (UserDao) Proxy.newProxyInstance(loader, interfaces, invocationHandlerImpl); newProxyInstance.save(); } }
CGLIB动态代理原理:
什么是CGLIB动态代理
代码演示:
package com.lijie; //接口 public interface UserDao { void save(); } 123456 package com.lijie; //接口实现类 public class UserDaoImpl implements UserDao { public void save() { System.out.println("保存数据方法"); } } 12345678 package com.lijie; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; //代理主要类 public class CglibProxy implements MethodInterceptor { private Object targetObject; // 这里的目标类型为Object,则能够接受任意一种参数做为被代理类,实现了动态代理 public Object getInstance(Object target) { // 设置须要建立子类的类 this.targetObject = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this); return enhancer.create(); } //代理实际方法 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("开启事物"); Object result = proxy.invoke(targetObject, args); System.out.println("关闭事物"); // 返回代理对象 return result; } } 123456789101112131415161718192021222324252627282930 package com.lijie; //测试CGLIB动态代理 public class Test { public static void main(String[] args) { CglibProxy cglibProxy = new CglibProxy(); UserDao userDao = (UserDao) cglibProxy.getInstance(new UserDaoImpl()); userDao.save(); } }
建造者模式一般包括下面几个角色:
使用场景:
package com.lijie; //装备类 public class Arms { //头盔 private String helmet; //铠甲 private String armor; //武器 private String weapon; //省略Git和Set方法........... }
package com.lijie; public interface PersonBuilder { void builderHelmetMurder(); void builderArmorMurder(); void builderWeaponMurder(); void builderHelmetYanLong(); void builderArmorYanLong(); void builderWeaponYanLong(); Arms BuilderArms(); //组装 }
package com.lijie; public class ArmsBuilder implements PersonBuilder { private Arms arms; //建立一个Arms实例,用于调用set方法 public ArmsBuilder() { arms = new Arms(); } public void builderHelmetMurder() { arms.setHelmet("夺命头盔"); } public void builderArmorMurder() { arms.setArmor("夺命铠甲"); } public void builderWeaponMurder() { arms.setWeapon("夺命宝刀"); } public void builderHelmetYanLong() { arms.setHelmet("炎龙头盔"); } public void builderArmorYanLong() { arms.setArmor("炎龙铠甲"); } public void builderWeaponYanLong() { arms.setWeapon("炎龙宝刀"); } public Arms BuilderArms() { return arms; } }
package com.lijie; public class PersonDirector { //组装 public Arms constructPerson(PersonBuilder pb) { pb.builderHelmetYanLong(); pb.builderArmorMurder(); pb.builderWeaponMurder(); return pb.BuilderArms(); } //这里进行测试 public static void main(String[] args) { PersonDirector pb = new PersonDirector(); Arms arms = pb.constructPerson(new ArmsBuilder()); System.out.println(arms.getHelmet()); System.out.println(arms.getArmor()); System.out.println(arms.getWeapon()); } }
例如:
package com.lijie; //模板方法 public abstract class RestaurantTemplate { // 1.看菜单 public void menu() { System.out.println("看菜单"); } // 2.点菜业务 abstract void spotMenu(); // 3.吃饭业务 public void havingDinner(){ System.out.println("吃饭"); } // 3.付款业务 abstract void payment(); // 3.走人 public void GoR() { System.out.println("走人"); } //模板通用结构 public void process(){ menu(); spotMenu(); havingDinner(); payment(); GoR(); } }
package com.lijie; public class RestaurantGinsengImpl extends RestaurantTemplate { void spotMenu() { System.out.println("人参"); } void payment() { System.out.println("5快"); } }
package com.lijie; public class RestaurantLobsterImpl extends RestaurantTemplate { void spotMenu() { System.out.println("龙虾"); } void payment() { System.out.println("50块"); } }
package com.lijie; public class Client { public static void main(String[] args) { //调用第一个模板实例 RestaurantTemplate restaurantTemplate = new RestaurantGinsengImpl(); restaurantTemplate.process(); } }
package com.lijie; //阿里短信消息 public interface AliSmsService { void sendSms(); } 123456 package com.lijie; public class AliSmsServiceImpl implements AliSmsService { public void sendSms() { System.out.println("阿里短信消息"); } }
package com.lijie; //发送邮件消息 public interface EamilSmsService { void sendSms(); } 123456 package com.lijie; public class EamilSmsServiceImpl implements EamilSmsService{ public void sendSms() { System.out.println("发送邮件消息"); } }
package com.lijie; //微信消息推送 public interface WeiXinSmsService { void sendSms(); } 123456 package com.lijie; public class WeiXinSmsServiceImpl implements WeiXinSmsService { public void sendSms() { System.out.println("发送微信消息推送"); } }
package com.lijie; public class Computer { AliSmsService aliSmsService; EamilSmsService eamilSmsService; WeiXinSmsService weiXinSmsService; public Computer() { aliSmsService = new AliSmsServiceImpl(); eamilSmsService = new EamilSmsServiceImpl(); weiXinSmsService = new WeiXinSmsServiceImpl(); } //只须要调用它 public void sendMsg() { aliSmsService.sendSms(); eamilSmsService.sendSms(); weiXinSmsService.sendSms(); } }
package com.lijie; public class Client { public static void main(String[] args) { //普通模式须要这样 AliSmsService aliSmsService = new AliSmsServiceImpl(); EamilSmsService eamilSmsService = new EamilSmsServiceImpl(); WeiXinSmsService weiXinSmsService = new WeiXinSmsServiceImpl(); aliSmsService.sendSms(); eamilSmsService.sendSms(); weiXinSmsService.sendSms(); //利用外观模式简化方法 new Computer().sendMsg(); } }
咱们Spring框架中的多例就是使用原型。
package com.lijie; import java.util.ArrayList; public class User implements Cloneable { private String name; private String password; private ArrayList<String> phones; protected User clone() { try { User user = (User) super.clone(); //重点,若是要连带引用类型一块儿复制,须要添加底下一条代码,若是不加就对因而复制了引用地址 user.phones = (ArrayList<String>) this.phones.clone();//设置深复制 return user; } catch (CloneNotSupportedException e) { e.printStackTrace(); } return null; } //省略全部属性Git Set方法...... }
package com.lijie; import java.util.ArrayList; public class Client { public static void main(String[] args) { //建立User原型对象 User user = new User(); user.setName("李三"); user.setPassword("123456"); ArrayList<String> phones = new ArrayList<>(); phones.add("17674553302"); user.setPhones(phones); //copy一个user对象,而且对象的属性 User user2 = user.clone(); user2.setPassword("654321"); //查看俩个对象是不是一个 System.out.println(user == user2); //查看属性内容 System.out.println(user.getName() + " | " + user2.getName()); System.out.println(user.getPassword() + " | " + user2.getPassword()); //查看对于引用类型拷贝 System.out.println(user.getPhones() == user2.getPhones()); } }
//默认引用类型为浅复制,这是设置了深复制 user.phones = (ArrayList<String>) this.phones.clone();
package com.lijie; //策略模式 定义抽象方法 全部支持公共接口 abstract class PayStrategy { // 支付逻辑方法 abstract void algorithmInterface(); }
package com.lijie; class PayStrategyA extends PayStrategy { void algorithmInterface() { System.out.println("微信支付"); } }
package com.lijie; class PayStrategyB extends PayStrategy { void algorithmInterface() { System.out.println("支付宝支付"); } }
package com.lijie; class PayStrategyC extends PayStrategy { void algorithmInterface() { System.out.println("银联支付"); } }
package com.lijie;// 使用上下文维护算法策略 class Context { PayStrategy strategy; public Context(PayStrategy strategy) { this.strategy = strategy; } public void algorithmInterface() { strategy.algorithmInterface(); } }
package com.lijie; class ClientTestStrategy { public static void main(String[] args) { Context context; //使用支付逻辑A context = new Context(new PayStrategyA()); context.algorithmInterface(); //使用支付逻辑B context = new Context(new PayStrategyB()); context.algorithmInterface(); //使用支付逻辑C context = new Context(new PayStrategyC()); context.algorithmInterface(); } }
实现有两种方式:
package com.lijie; //观察者的接口,用来存放观察者共有方法 public interface Observer { // 观察者方法 void update(int state); }
package com.lijie; // 具体观察者 public class ObserverImpl implements Observer { // 具体观察者的属性 private int myState; public void update(int state) { myState=state; System.out.println("收到消息,myState值改成:"+state); } public int getMyState() { return myState; } }
package com.lijie; import java.util.Vector; //定义主题,以及定义观察者数组,并实现增、删及通知操做。 public class Subjecct { //观察者的存储集合,不推荐ArrayList,线程不安全, private Vector<Observer> list = new Vector<>(); // 注册观察者方法 public void registerObserver(Observer obs) { list.add(obs); } // 删除观察者方法 public void removeObserver(Observer obs) { list.remove(obs); } // 通知全部的观察者更新 public void notifyAllObserver(int state) { for (Observer observer : list) { observer.update(state); } } }
package com.lijie; //具体主题 public class RealObserver extends Subjecct { //被观察对象的属性 private int state; public int getState(){ return state; } public void setState(int state){ this.state=state; //主题对象(目标对象)值发生改变 this.notifyAllObserver(state); } }
package com.lijie; public class Client { public static void main(String[] args) { // 目标对象 RealObserver subject = new RealObserver(); // 建立多个观察者 ObserverImpl obs1 = new ObserverImpl(); ObserverImpl obs2 = new ObserverImpl(); ObserverImpl obs3 = new ObserverImpl(); // 注册到观察队列中 subject.registerObserver(obs1); subject.registerObserver(obs2); subject.registerObserver(obs3); // 改变State状态 subject.setState(300); System.out.println("obs1观察者的MyState状态值为:"+obs1.getMyState()); System.out.println("obs2观察者的MyState状态值为:"+obs2.getMyState()); System.out.println("obs3观察者的MyState状态值为:"+obs3.getMyState()); // 改变State状态 subject.setState(400); System.out.println("obs1观察者的MyState状态值为:"+obs1.getMyState()); System.out.println("obs2观察者的MyState状态值为:"+obs2.getMyState()); System.out.println("obs3观察者的MyState状态值为:"+obs3.getMyState()); } }