四、原型模式
优点:
底层直接复制,不通过构造方法,也不受权限修饰符影响
因为调用的是本地native方法,性能好
具体:
类实现Cloneable接口
重写clone()方法 (ps: 底层native的)
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
浅拷贝
public class Address {
private String city;
//...省略构造getset
}
public class Student implements Cloneable{
private int id;
private String name;
private Address address; //引用类型
@Override //要把默认的protected改成public 且 强转类型
public Student clone() throws CloneNotSupportedException {
return (Student) super.clone();
}
//....省略getset构造
}
public static void main(String[] args) throws CloneNotSupportedException {
Student s1 = new Student(1,"张三");
s1.setId(10); //id大家一起变了
Student s2 = s1.clone();
s2.setName("李四"); //name只有s2改成了李四
Student s3 = s1.clone();
s1.setId(2); //只有s1自己变成了2
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
}
深拷贝
浅拷贝中,拷贝后的Student的引用类型成员变量Address跟原来的还是同一个地址,也就是s1、s2、s3用的是同一个Address,任意一个改动了Address,其他的Address也会跟着改
而深拷贝中,在拷贝Student的同时也把Address也拷贝了一份,所以s1、s2、s3的Address会重新在空间中拷贝一份,不是共享的了
public class Address implements Cloneable{
private String city;
@Override
protected Address clone() throws CloneNotSupportedException {
return (Address) super.clone();
}
public class Student implements Cloneable{
private int id;
private String name;
private Address address;
@Override //要把默认的protected改成public 且 强转类型
public Student clone() throws CloneNotSupportedException {
Student obj = null;
//浅复制
obj = (Student) super.clone();
//深复制:要加上引用类型的clone()
obj.address = this.address.clone();
return obj;
}
//....省略getset构造
}
五、外观模式
可以理解为MVC的业务层,一个service可以来处理很多不同的dao
六、装饰模式
装饰模式是继承的一种替代解决方法
应用在IO流InputStream里面
完整的装饰模式包括4部分
- 一个抽象的蛋糕类 Cake
- 多个具体的蛋糕类 ChocolateCake、IceCreamCake
- 一个抽象的装饰类 Decorator
- 多个具体的装饰类 CardDecorator、NutDecorator
ChocolateCake、IceCreamCake、Decorator都继承抽象类Cake
CardDecorator、NutDecorator继承Decorator
- Cake有个抽象方法make
- ChocolateCake、IceCreamCake实现了make
- Decorator传入Cake : private Cake cake;
重写make方法:调用 传入的cake的make方法
public void make() { cake.make(); }- CardDecorator、NutDecorator构造方法里面调用父类的构造:super(cake);
重写make方法:先调用父类的make方法,在写自己的make方法
public void make() {
super.make();
System.out.println(“添加坚果---------------”);
}
public abstract class Cake {
public abstract void make();
}
public class ChocolateCake extends Cake{
@Override
public void make() {
System.out.println("制作———————————巧克力蛋糕");
}
}
public class IceCreamCake extends Cake{
@Override
public void make() {
System.out.println("制作———————————冰淇淋蛋糕");
}
}
/**
* 装饰类
* card、nut、flower
* 继承抽象的蛋糕类,重写cake里面的make方法
* 关联抽象的蛋糕类,调用关联对象的make方法
*/
public abstract class Decorator extends Cake{
private Cake cake; //可以传入Cake的任意一个子类对象,也可以是具体的装饰类型(卡片、鲜花)
public Decorator() {
}
public Decorator(Cake cake) {
this.cake = cake;
}
@Override
public void make() {
cake.make(); //不是抽象类Cake的,看传进来的子类是谁(巧克力、冰淇淋)的真实make
}
}
public class CardDecorator extends Decorator{
public CardDecorator() {}
public CardDecorator(Cake cake) {
super(cake);
}
@Override
public void make() {
//先调用父类的make
super.make();
//再继续自己的make
System.out.println("添加卡片---------");
}
}
public class NutDecorator extends Decorator{
public NutDecorator() {}
public NutDecorator(Cake cake) {
super(cake);
}
@Override
public void make() {
super.make();
System.out.println("添加坚果---------------");
}
}
七、代理模式
静态代理
优点: 符合开闭原则下对目标进行功能拓展
缺点:
一个代理类只能代理一个接口,工作量太大;
代理类的代码是运行前已经完成的;
必须先有接口,再有代理;
接口一旦发生改变,代理类也要改变;
public interface Object {
public void request();
}
public class RealObject implements Object{
@Override
public void request() {
System.out.println("真实对象的行为");
}
}
public class Proxy implements Object{
private Object object;
public Proxy(Object object) {
this.object = object;
}
@Override
public void request() {
before();
object.request();
after();
}
public void before(){
System.out.println("前置");
}
public void after(){
System.out.println("后置");
}
}
JDK动态代理
只能代理接口(Subject)
public class ProxyHandle implements InvocationHandler {
private Object target;
public ProxyHandle(Object target) {
this.target = target;
}
@Override //代理对象(律师)/ 要调方法(request1...)/ 参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
//通过反射来调用方法
Object result = method.invoke(target, args);
after();
return result;
}
private void before(){
System.out.println("前···········");
}
private void after(){
System.out.println("后···········");
}
//动态创建代理对象
public Object getProxy(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
}
CGLIB动态代理
改为类 依然可以动态代理
public abstract class Subject {
public abstract void request();
}
public class ProxyInterceptor implements MethodInterceptor { //要导入CGLIBjar包
Object target;
public ProxyInterceptor(Object target) {
this.target = target;
}
@Override
public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
before();
Object result = method.invoke(target, objects);
after();
return result;
}
private void before(){
System.out.println("前···········");
}
private void after(){
System.out.println("后···········");
}
public Object getProxy(){
Enhancer enhancer = new Enhancer(); //类似于Proxy
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
}
八、模板模式
//模板
public abstract class Game {
//模板方法
public final void play(){
initialize();
startGame();
endGame();
}
abstract void initialize();
abstract void startGame();
abstract void endGame();
}
class CrossFire extends Game{
@Override
void initialize() {
System.out.println("初始化游戏------cf");
}
@Override
void startGame() {
System.out.println("开始游戏------cf");
}
@Override
void endGame() {
System.out.println("结束游戏------cf");
}
}
class nba2k extends Game{
@Override
void initialize() {
System.out.println("初始化游戏------nba2k");
}
@Override
void startGame() {
System.out.println("开始游戏------nba2k");
}
@Override
void endGame() {
System.out.println("结束游戏------nba2k");
}
}
九、责任链模式
abstract class Handle{
private Handle handle;
public Handle getHandle() {
return handle;
}
public void setNextHandle(Handle handle) {
this.handle = handle;
}
public abstract void doHandle(int money);
}
class GroupLeader extends Handle{
@Override
public void doHandle(int money) {
if(money < 10000){
System.out.println("组长决策");
}else{
System.out.println("组长权限不够-->上报部长");
getHandle().doHandle(money);
}
}
}
class DeptLeader extends Handle{
@Override
public void doHandle(int money) {
if(money < 50000){
System.out.println("部长决策");
}else{
System.out.println("部长权限不够-->上报董事长");
getHandle().doHandle(money);
}
}
}
class TopLeader extends Handle{
@Override
public void doHandle(int money) {
System.out.println("董事长决策");
}
}
public static void main(String[] args) {
GroupLeader groupLeader = new GroupLeader();
DeptLeader deptLeader = new DeptLeader();
TopLeader topLeader = new TopLeader();
//设置责任链
groupLeader.setNextHandle(deptLeader);
deptLeader.setNextHandle(topLeader);
//执行
groupLeader.doHandle(200000);
/**
* 结果:
* 组长权限不够-->上报部长
* 部长权限不够-->上报董事长
* 董事长决策
*/
}