您的位置:首页 > 其它

常用设计模式(design pattern)

2018-03-25 23:42 471 查看
之前学的MVC算是一种设计模式的具体实现

那么设计模式有什么优点呢?

5大设计原则 solid

s 单一职责原则(一个类只做一件事)

一个模块负责一个功能

一个类负责一个业务

一个API去实现一个功能

不同的功能分隔开。一个类如果需要变化,最好只能有一个维度的原因。

o 开放封闭原则(对扩展开放,对修改封闭)

扩展:新功能—>可以去增加代码(增加类)

尤其是项目不断迭代(增加新的需求)

不建议去修改代码 (尤其是一些底层的API)牵一发而动全身。

对于不用的API使用Deprecate废弃

l liskov原则()

任何一个基类可以出现的地方,子类一定可以出现。

i 接口隔离原则

不同功能的接口,最好放在不同的interface里。

同时一个接口里最好不要集成太多的功能,否则用户去实现该接口会比较麻烦。

d 依赖倒置原则

具体依赖于抽象,而非抽象依赖于具体。

先设计好impl,再具体去实现

常见的设计模式

单例模式

1、单例类只能有一个实例。

2、单例类必须自己创建自己的唯一实例。

3、单例类必须给所有其他对象提供这一实例。

public class Singleton {
private Singleton(){};
private static Singleton singleton;
public static Singleton getSingleton(){
if(singleton==null){
singleton=new Singleton();
return singleton;
}else
return singleton;
}
}


如何实现一个懒加载、线程安全且不用锁的单例

package com.bamzhy.homework;

import javax.xml.ws.Holder;

public class homework1 {
public homework1() {
}
//内部类和一般的类一样,都被编译成单独的class文件,而在加载的时候是根据需要加载
static class InnerClass{
public static com.bamzhy.homework.homework1 getHomework1() {
return homework1;
}

private static homework1 homework1=new homework1();
}

public static homework1 getHomeWork1(){
return InnerClass.getHomework1();
}
}
/*
因为使用了内部类,所以加载class时innerclass不会被加载,只有在调用innerclass中的
方法时才会加载innerclass,同时,innerclass只会被加载一次,这样保证了线程安全。
同时没有锁,效率没有受到影响
*/


工厂模式

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

package com.bamzhy.factory;
import com.bamzhy.factory.bean.Animal;

public abstract class AbstractFactory {
abstract public Animal getInstacne(String name);
}
//下面的代码是用来使用工厂模式的
AbstractFactory factory =null;
String name ;
Animal instacne = factory.getInstacne("");


建造者模式 BuilderPattern

Builder:给出一个抽象接口,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建。

ConcreteBuilder:实现Builder接口,针对不同的业务逻辑,具体化复杂对象的各部分的创建。 在建造过程完成后,提供产品的实例。

Director:调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建

Product:要创建的复杂对象。

装饰器模式

被包装对象是实现了一个接口的具体对象

包装对象实现同一个接口

通过包装对象的构造方法把被包装对象设置到包装对象内部

不需要修改的方法依然使用被包装对象的

需要修改的方法要使用自己重写的

- 包装设计模式

1、定义一个类,实现被包装(增强)对象的相同的接口

2、定义一个变量,引用被包装(增强)对象

3、构造方法接收被包装(增强)对象

4、覆盖要被增强的方法

5、对于不想增强的方法,调用被包装(增强)对象的对应方法

适配器模式

代理模式

动态代理:可以直接给某一个目标对象生成一个代理对象,而不需要代理类存在

静态代理:包装就是一种静态代理

Java动态代理:Java动态代理机制的出现,使得Java开发人员不用手动编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类

动态代理有两种实现方式

1、JDK提供一个Proxy类可以实现接口类的对象直接生成代理对象

2、cglib(spring中的)

静态代理:

package com.bamzhy.proxy;
//静态代理
public class lianjia implements Housekeeper {
Housekeeper housekeeper;
public lianjia(Housekeeper housekeeper) {
this.housekeeper = housekeeper;
}
@Override
public int makeContract() {
System.out.println("链家跑了很多趟!");
int i = housekeeper.makeContract();
System.out.println("链家收到钱了");
return i*100;
}
}

package com.bamzhy.proxy;
import org.junit.Test;
public class Test {
@Test
public void test1(){
Housekeeper housekeeper =new ThuHouseKeeper();
lianjia lianjia = new lianjia(housekeeper);
lianjia.makeContract();
}
}


动态代理

package com.bamzhy.dynamicproxy;

import org.junit.Test;
import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.cglib.proxy.Proxy;

import java.lang.reflect.Method;

public class TestCC {

//jdk提供一个proxy类可以为实现了某些接口的对象 直接生成代理对象
//static Object newProxyInstance
//(ClassLoader loader ,要求传入于被代理对象相同的类加载器)
//Class<?>[]interfaces 要传入被代理对象实现的接口的数组
//InvocationHandler h) 执行处理器
//返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序

@Test
public void test1(){
final HouseKeeper housekeeper = new ThuHouseKeeper();
HouseKeeper lianjia = (HouseKeeper) Proxy.newProxyInstance(housekeeper.getClass().getClassLoader(),
housekeeper.getClass().getInterfaces(),
new InvocationHandler() {
@Override
//Object o 被调用该方法的代理实例
//Method method 被代理对象的方法
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("args="+objects[0]);
System.out.println("链家跑了很多趟");
Integer invoke = (Integer) method.invoke(housekeeper, objects);
System.out.println("invoke="+invoke);
System.out.println("链家收到钱了");
return invoke-1000;
}
});
lianjia.makeContract(10000);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: