设计模式总结
1.单例模式
单例模式:在内存中存在(仅)有限(一)的对象。控制内存中对象存在的数量。
1.1懒汉模式
/**
* 单例模型-懒汉模式
*
* @author Administrator
*
*/
public class Singleton {
private static Singleton instance = null; // instance 一开始没有引用任何对象
private final static ReentrantLock lock = new ReentrantLock();
private Singleton() {
}
/**
* 调用getIntance()方法,才建立instance的引用对象
*
* @return
*/
public static Singleton getIntance() {
lock.lock();
try {
if (instance == null) {
instance = new Singleton();
}
} finally {
lock.unlock();
}
return instance;
}
}
或者可以使用 synchronized 和双重判断来保证安全问题
synchronized (xxx.class) {
if(instance==null)
}
1.2饿汉模式
/**
* 单例:饿汉模式
* @author Administrator
*
*/
public class Singleton2 {
private final static Singleton2 instance
= new Singleton2();//JVM保证线程安全
private Singleton2() {}
public static Singleton2 getIntance() {
return instance;
}
}
1.3 枚举式
public enum Singleton{
INSTANCE;
}
jvm保证枚举类型的单例,枚举类型默认为static,在类加载时由static构造方法创造出对象,由于static方法只调用一次,因此枚举式是单例的。
1.4 单例模式的应用
1.工具类:mybatisUtil
2.框架:spring
3.封装
2.适配器模式
应用场景:项目开发过程中,第一个版本(2019年开发),定义了接口IWalk(走路),发展到2022年,有了新的接口(IRun),原来的接口与新接口不匹配,故产生一个适配器,将两个接口连接。
接口(IWalk)
public interface IWalk {
void walk();
}
接口(IRun)
public interface IRun {
void run();
}
------------------------------------
public class RunImpl implements IRun {
@Override
public void run() {
System.out.println("跑的飞快");
}
}
适配器(adapter)
public class adapter implements IWalk{
private IRun irun;
public adapter(IRun irun) {
this.irun = irun;
}
@Override
public void walk() {
irun.run();
}
}
适配器实现了老接口(IWalk),创建新接口(IRun)的实现类的对象,然后重写老接口中的方法,用实现新接口的方法。
测试
public static void main(String[] args) {
IWalk iwalk = new adapter(new RunImpl());
iwalk.walk();
}
应用
1.第三方api,对原有的api进行适配
2.旧系统和新系统进行集成
3.工厂模式
场景:一个学生去吃饭,有几项选择:1.米线(XiaoAMei)2.米饭(RiceHouse)3.面条(Noodle)
public class XiaoAMei {
public void suply() {
System.out.println("米线");
}
public class RiceHouse {
public void suply() {
System.out.println("米饭");
}
public class Noodle {
public void suply() {
System.out.println("面条");
}
3.1 版本一
public class Student {
private String name;
public Student() {
}
public Student(String name) {
this.name=name;
}
public void eat() {
XiaoAMei xam = new XiaoAMei();
xam.suply();
}
}
public class testVersion01 {
public static void main(String[] args) {
Student s = new Student("tom");
s.eat();
}
}
类和类的关系:
1.关联
2.依赖
3.聚合/组合
4.继承
3.2 版本二:面向接口开发
分析第一个版本的缺点:XiaoAMei xam = new XiaoAMei();
1.类型:XiaoAMei ,对象:xam
2.等号左右类型一致,写死类型和对象
public interface suply {
void suply();
}
--------------------------
public class XiaoAMei implements suply{
@Override
public void suply() {
System.out.println("米线");
}
}
-----------------------
public class RiceHouse implements suply{
@Override
public void suply() {
System.out.println("米饭");
}
}
------------------------
public class Noodle implements suply{
@Override
public void suply() {
System.out.println("面条");
}
}
public class Student {
private String name;
public Student() {
}
public Student(String name) {
this.name=name;
}
public void eat() {
suply xam = new XiaoAMei();
xam.suply();
}
}
public class testVersion02 {
public static void main(String[] args) {
Student s = new Student("tom");
s.eat();
}
}
3.3 版本三:工厂模式
面向接口的不足,new XiaoAMei();
suply xam = new XiaoAMei();
Student类---->eat()------->创建XiaoAMei
面向对象--------->对象------>对象是什么
对象是具有一定职责的东西
因此,问题在于Student类的职责不清,Student类不需要创建,销毁XiaoAMei的职责
new---------->创建
改造:将职责进行分离---->抽象出一个工厂来完成创建销毁的职责
public interface suply {
void suply();
}
--------------------------
public class XiaoAMei implements suply{
@Override
public void suply() {
System.out.println("米线");
}
}
-----------------------
public class RiceHouse implements suply{
@Override
public void suply() {
System.out.println("米饭");
}
}
------------------------
public class Noodle implements suply{
@Override
public void suply() {
System.out.println("面条");
}
}
public class FoodFactory {
public static suply creat() {
suply is = null;
//获得菜单具体路径
String path = FoodFactory.class.getResource("Resource/Menu.txt").getPath();
System.out.println(path);
try {
BufferedReader in = new BufferedReader(new FileReader(path));//字符流读取菜单内容
String line = in.readLine();//将菜单内容转换为字符串
System.out.println(line);
String className = "com.dyit.version03."+line;//类的完整名称
System.out.println(className);
is=(suply) Class.forName(className).newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return is;
}
public static void main(String[] args) {
String path = FoodFactory.class.getResource("").getPath();
System.out.println(path);
}
}
public class Student {
private String name;
public Student() {
}
public Student(String name) {
this.name=name;
}
public void eat() {
suply xam = FoodFactory.creat();
xam.suply();
}
}
3.4工厂模式方法
工厂可以进行扩展,定义抽象的工厂接口,具体的工厂延迟到实现类完成。
public interface IFoodLFactory {
ISuply createFood(Class<? extends ISuply> is);
}
public class FoodFactoryImpl implements IFoodLFactory {
@Override
public ISuply createFood(Class<? extends ISuply> is) {
ISuply isu = null;
try {
isu =is.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return isu;
}
}
4.代理模式
为什么会产生代理模式?
当我们需要对类进行操作时,可以使用继承的思想,使软件(代码)能够复用。但是,当方法中出现重复代码时,该如何复用呢?面向切面(AOP)的思想便产生了
那么我们如何实现AOP呢?
答案就是今天我们学习的第四种设计模式--------代理模式。
实际场景:小明准备租三室一厅的房子上班,找房屋中介租房,房屋中介将房东的房子租给小明。
分析:房东(真正拥有房子):real ; 中介(代理):和小明打交道的对象
4.1 静态代理
public interface IRent {
void rent();
}
public class HouseKeeper implements IRent {
@Override
public void rent() {
System.out.println("出租豪华三室一厅");
}
}
public class HouseAgent implements IRent {
private IRent real;
public HouseAgent(IRent real) {
this.real=real;
}
@Override
public void rent() {
this.real.rent();
before();
after();
}
void before() {
System.out.println("收取租金1000元");
}
void after() {
System.out.println("每月检察一次卫生");
}
}
public class TestRent {
@Test
public void test() {
IRent real = new HouseKeeper();
IRent agent = new HouseAgent(real);
agent.rent();
}
}
优点:隐藏真实对象real;代理对象的方法进行功能添加修改
缺点: 接口不可变
4.2 动态代理
public interface IRent {
void rent();
void job();
void c();
}
public class HourseKeeper implements IRent {
@Override
public void rent() {
System.out.println("出租豪华三室一厅");
}
@Override
public void job() {
System.out.println("找工作");
}
@Override
public void c() {
System.out.println("c");
}
}
public class AngetMaker implements InvocationHandler {
private IRent real;
public AngetMaker(IRent real) {
this.real=real;
}
/**
* 产生代理对象
*/
public IRent creatAgent() {
return (IRent) Proxy.newProxyInstance(real.getClass().getClassLoader(),
real.getClass().getInterfaces(),
this);
}
/**
* 调用对象的真实方法
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
method.invoke(this.real, args);
before();
after();
return null;
}
private void before() {
System.out.println("收取2500押金");
}
private void after() {
System.out.println("每月检查卫生一次,不合格罚款100元");
}
}
@Test
public void test() {
HouseKeeper real = new HouseKeeper();
IRent r = new AgentMaker(real).createAgent();
r.c();
}