1 设置模式之单例设计模式

概念:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

(1)饿汉式:

/*** @Description 饿汉式* @author refuel* @version v1.0*/
public class TestSingleton{public static void main(String[] args) {Singleton sing = Singleton.getInstance(); sing.show();}
}
class Singleton {   //1、将构造器私有化private Singleton() {}//2、定义创建一个私有对象 private static Singleton Sing = new Singleton();//3、定义公共静态方法返回该类类型的对象 public static Singleton getInstance() {return Sing;}
}

(2)饱汉式,线程不安全

/*** @Description 饱汉式,线程不安全* @author refuel* @version v1.0*/
public class TestSingleton{public static void main(String[] args) {Singleton sing = Singleton.getInstance(); sing.show();}
}
class Singleton {   //1、将构造器私有化private Singleton() {}//2、定义创建一个私有对象 private static Singleton Sing;//3、定义公共静态方法返回该类类型的对象 public static Singleton getSingleton() {if(Sing == null) {Sing = new Singleton();}return Sing;}
}

2 设置模式之工厂模式

2.1 简单工厂

简单工厂模式其实不是一个设计模式,反而比较像一种编程习惯。主要我们定义一个非常简单的类主要负责帮我们生产不同的产品。例子如下:

/*** @Description 简单工厂* @author refuel* @version v1.0*/
public class SimpleFactory {//④使用工厂方法,通过传递类型信息来获取实体类的对象public static void main(String[] args) {Factory1 w = new Factory1();//获取Student1Work的对象,并调用他的doWork方法Product1 product = w.getExamples("Student1Work");product.show();//获取Teacher1Work的对象,并调用他的doWork方法Product1 product1 = w.getExamples("Teacher1Work");product1.show();//获取Worker1Work的对象,并调用他的doWork方法Product1 product2 = w.getExamples("Worker1Work");product2.show();}}//①创建一个 Product接口
interface Product1{void show();
}
// ②实现Product 接口的实体类
class Student1 implements Product1 {@Overridepublic void show() {System.out.println("学生学习");}
}
class Teacher1 implements Product1 {@Overridepublic void show() {System.out.println("老师教书育人");}
}
class Worker1 implements Product1 {@Overridepublic void show() {System.out.println("工人建高楼大厦");}
}
//③定义工厂类 生成基于给定信息的实体类的对象
class Factory1 {//使用getExamples方法获取工作性质类型的对象public Product1 getExamples(String workType) {if(workType ==null) {return null;}if(workType.equalsIgnoreCase("Student1Work")) {return new Student1();}else if(workType.equalsIgnoreCase("Teacher1Work")) {return new Teacher1();}else if(workType.equalsIgnoreCase("Worker1Work")) {return new Worker1();}return null;}
}

2.2 工厂方法模式

简单工厂模式有一个缺点是不同的产品需要不同的额外参数的时候,是不支持的,而且如果使用时传递的type、Class出错,将不能得到正确的对象,容错率不高。而多方法的工厂模式为不同产品,提供不同的生产方法,使用时 需要哪种产品就调用该种产品的方法,使用方便、容错率高。

工厂方法模式概念:定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类

何时使用:主要解决接口选择的问题,我们明确地计划不同条件下创建不同实例时。

/*** @Description 工厂模式* @author refuel* @version v1.0*/
public class FactoryPattern {public static void main(String[] args) {Factory2 s = new StudentFactory2();s.getExamples().show();Factory2 t = new TeacherFactory2();t.getExamples().show();Factory2 w = new WorkerFactory2();w.getExamples().show();}}//①创建一个 Product接口
interface Product2{void show();
}
// ②实现Product 接口的实体类
class Student2 implements Product2 {@Overridepublic void show() {System.out.println("学生学习");}
}
class Teacher2 implements Product2 {@Overridepublic void show() {System.out.println("老师教书育人");}
}
class Worker2 implements Product2 {@Overridepublic void show() {System.out.println("工人建高楼大厦");}
}
//③定义一个工厂接口
interface Factory2 {Product2 getExamples();
}
//④定义一个学生工厂接口
class StudentFactory2 implements Factory2 {public Product2 getExamples() {return new Student2();}
}
//⑤定义一个老师工厂接口
class TeacherFactory2 implements Factory2 {public Product2 getExamples() {return new Teacher2();}
}
//⑥定义一个工人工厂接口
class WorkerFactory2 implements Factory2 {public Product2 getExamples() {return new Worker2();}
}

2.3 抽象工厂模式

为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

抽象工厂模式,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。

/*** @Description 抽象工厂模式* @author refuel* @version v1.0*/
public class AbstractFactoryPattern {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {AbstractFactory sbstractFactory = SuperFactory.getFactory("com.refuel.factory.StudentFactory");Product SmallStudent = sbstractFactory.getExamples("com.refuel.factory.SmallStudent");SmallStudent.show();}}//最高级抽象产品,用于抽象工厂的建造方法的返回值
abstract class Product{abstract void show();
}
//学生产品类
abstract class StudentProduct extends Product{}
//小学生产品
class SmallStudent extends StudentProduct{public void show() {System.out.println("小学生");}
}//中学生产品
class MiddleStudent extends StudentProduct{public void show() {System.out.println("小学生");}
}
//老师产品类
abstract class TeacherProduct extends Product{}
//数学老师产品
class MathTeacher extends TeacherProduct{public void show() {System.out.println("数学老师");}
}//历史老师产品
class HistoryTeacher extends TeacherProduct{public void show() {System.out.println("历史老师");}
}//超级工厂类
class SuperFactory {public static AbstractFactory getFactory(String type) throws ClassNotFoundException, InstantiationException, IllegalAccessException {Class cl = Class.forName(type);System.out.println("创建工厂" + type);return (AbstractFactory) cl.newInstance();}
}
//抽象工厂类
abstract class AbstractFactory {protected abstract Product getExamples(String type) throws ClassNotFoundException, InstantiationException, IllegalAccessException;
}//学生工厂类,覆盖所有学生的生产方法
class StudentFactory extends AbstractFactory{public Product getExamples(String type) throws ClassNotFoundException, InstantiationException, IllegalAccessException {Class cl = Class.forName(type);return (StudentProduct)cl.newInstance();}
}
//老师工厂类,覆盖所有老师的生产方法
class TeacherFactory extends AbstractFactory{public Product getExamples(String type) throws ClassNotFoundException, InstantiationException, IllegalAccessException {Class cl = Class.forName(type);return (TeacherProduct)cl.newInstance();}
}

2.4 简单工厂模式,工厂模式与抽象工厂模式的比较

简单工厂模式:(1)优点:工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。(2)缺点:没有遵守开放—封闭原则(开放接口,封闭修改)。如果将来需要添加一个产品,那么,在简单工厂模式中,就必须在简单工厂类中添加相应的判断语句,这对程序的扩展本身就不利。

工厂模式:(1)优点 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。(2)缺点每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

抽象工厂模式:(1)优点:能够从多个产品族的多个产品中,简洁的获取想要的具体产品。解决了工厂模式中的不符合开闭原则的问题(增加新的产品时候,不修改工厂,而是增加工厂)。(2)缺点:产品族扩展比较困难,要增加一个系列的某一产品,要增加具体的产品类,还要增加对应的工厂类(或者修改对应产品族的工厂类)。产品族难扩展,产品等级易扩展。】

3 代理模式

提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。如果需改别人写好的代码时,可以通过代理的方式来扩展该方法。

3.1 静态代理

静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类。

/*** @Description 静态代理* @author refuel* @version v1.0*/
public class TestProxy {public static void main(String[] args) {//客户租房子,找代理ProcyObject proxy = new ProcyObject(new SubjectImpl());proxy.action();}
}
//接口
interface Subject{void action();
}
//中介(代理)
class ProcyObject implements Subject {//中介和业主有关系,所以定义关联关系SubjectImpl subject = null;public ProcyObject(SubjectImpl subject) {this.subject = subject;}@Overridepublic void action() {//调用业主的方法,自己没有subject.action();}}
//业主
class SubjectImpl implements Subject{@Overridepublic void action() {System.out.println("业主的房子");}}

3.2 动态代理

动态代理也叫做:JDK代理,接口代理。代理对象不需要实现接口,但是目标对象一定要实现接口。代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)。

代理类所在包:java.lang.reflect.Proxy,JDK代理使用newProxyInstance方法。

/*** @Description 动态代理* @author refuel* @version v1.0*/
public class DynamicProxy {public static void main(String[] args) {//目标对象Subject1 s = new SubjectImpl1();//给目标对象创建代理对象,内存中动态生成的代理对象Subject1 proxy = (Subject1)new ProxyFactory(s).getProxyInstance();proxy.action();}
}interface Subject1 {void action();
}/*** @Description 业主类* @author refuel* @version v1.0*/
class SubjectImpl1 implements Subject1 {@Overridepublic void action() {System.out.println("业主的房子");}}/*** @Description 代理工厂类* @author refuel* @version v1.0*/
class ProxyFactory {// 中介和业主有关系,所以定义关联关系,来维护一个目标对象Object subject = null;public ProxyFactory(Object subject) {this.subject = subject;}// 给目标对象生成一个代理对象public Object getProxyInstance() {// ClassLoader loader:指定当前对象使用类加载器,获取类加载器的方法是固定的// Class<?>[] interfaces:目标对象实现的接口类型,使用泛型方式确认// InvocationHandler h:事件处理,执行目标对象时,会触发事件处理器的方法,会把当前执行的目标对象作为的方法作为参数传入return Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(),new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("开始事务");// 执行目标对象方法Object invokeValue = method.invoke(subject, args);System.out.println("提交事务");return invokeValue;}});}
}

3.3 Cglib代理

Cglib代理,也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展。静态代理和动态代理模式都是要求目标对象实现一个接口,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候就可以使用以目标对象子类的方式类实现代理,这种方法就叫做:Cglib代理。

/*** @Description Cglib类* @author refuel* @version v1.0*/
public class CglibProxy {public static void main(String[] args) {//目标对象SubjectImpl2 target = new SubjectImpl2();//代理对象SubjectImpl2 proxy = (SubjectImpl2)new ProxyFactory(target).getProxyInstance();//执行代理对象的方法proxy.action();}
}
/*** @Description 业主类,目标对象,没有实现任何接口* @author refuel* @version v1.0*/
class SubjectImpl2 {public void action() {System.out.println("业主的房子");}
}
/*** @Description Cglib子类代理工厂,对SubjectImpl2在内存中动态创建一个子类对象* @author refuel* @version v1.0*/
class ProxyFactory implements MethodInterceptor{// 中介和代理有关系,所以定义关联关系,来维护一个目标对象Object subject = null;public ProxyFactory(Object subject) {this.subject = subject;}// 给目标对象创建一个代理对象public Object getProxyInstance() {//1.工具类Enhancer en = new Enhancer();//2.设置父类en.setSuperclass(subject.getClass());//3.设置回调函数en.setCallback(this);//4.创建子类(代理对象)return en.create();}@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("开始");//执行目标对象的方法Object returnValue = method.invoke(subject, args);System.out.println("提交");return returnValue;}}

2.4 静态代理,动态代理,Cglib代理的比较

静态代理:(1)优点:可以做到在不修改目标对象的功能前提下,对目标功能扩展.。(2)缺点:因为目标对象要与代理对象实现一样的接口,所以会产生很多的代理类,导致类太多。接口增加方法,目标对象与代理对象都要进行维护。

动态代理:(1)优点:由于java封装了newProxyInstance这个方法的实现细节,所以使用起来非常方便。(2)缺点:静态代理和JDK代理有一个共同的缺点,就是目标对象必须实现一个或多个接口

Cglib代理:(1)优点:目标对象与代理对象都不用实现接口。(2)缺点:因为没有使用接口,所以系统的耦合性没有使用JDK的动态代理好。

在Spring的AOP编程中,如果加入容器的目标对象有实现接口,用JDK代理,如果目标对象没有实现接口,用Cglib代理

4 策略模式(Strategy Pattern)

4.1 什么是策略模式

针对一组算法,将每一种算法(策略类)都封装到具有共同接口的独立类中,从而他们可以相互替换,可以在不影响客户端的情况下发生改变,从而改变不同的功能。

一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

特点:封装变化的概念;面向接口编程(编程中使用接口而不是使用具体的实现类)。

组成部分:(1)抽象策略角色:是抽象的角色,一般使用接口或抽象类实现,如Comparator接口;

(2)具体策略角色:包装了具体的算法和行为,如一组实现了Comparator接口的实现类;

(3)环境角色:内部有一个抽象角色的引用,给客户端调用,如TreeSet类,内部一定有一个策略类的一个成员变量,这样在创建TreeSet对象的时候可以接收向它传递的具体的策略类。

4.2 为什么使用策略模式

在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。算法可以自由切换,扩展良好;不过策略类会增多,还要对外暴露。

4.3 什么情况下可以使用

(1)如果一个系统中有很多的类,他们之间的区别是他们的行为不同,就可以用策略模式让一个对象在那么多的行为中选择一种;

(2)一个系统需要动态的在几种算法中实现一种。

如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

4.4 案例

实现List集合增删查的功能

编写步骤:(1)定义抽象策略角色(定义一个策略对象的公共接口);(2)编写具体策略角色(实现抽象策略角色这个公共接口);(3)定义环境变量(内部一定要持有一个策略类的引用)。

(1) 定义抽象策略角色:

/*** @Description 定义抽象策略角色* @author refuel* @version v1.0*/
public interface AbstarctStrategy<T> {//实现对List集合的操作public Boolean handle(List<T> list,T t);
}

(2)编写具体策略角色

/*** @Description 定义增加策略* @author refuel* @version v1.0*/
public class AddStrategy<T> implements AbstarctStrategy<T> {//实现handle方法,完成增加元素操作@Overridepublic Boolean handle(List<T> list, T t) {return list.add(t);}}/*** @Description 定义删除策略* @author refuel* @version v1.0*/
public class RemoveStrategy<T> implements AbstarctStrategy<T> {//实现handle方法,完成删除元素操作@Overridepublic Boolean handle(List<T> list, T t) {return list.remove(t);}}/*** @Description 定义查询策略* @author refuel* @version v1.0*/
public class QueryStrategy<T> implements AbstarctStrategy<T> {//实现handle方法,完成查看元素是否存在操作@Overridepublic Boolean handle(List<T> list, T t) {return list.contains(t);}}

(3)定义环境变量

/*** @Description 环境角色* @author refuel* @version v1.0*/
public class Environment<T> {//策略类的引用private AbstarctStrategy<T> strategy;public Environment(AbstarctStrategy<T> strategy) {this.strategy = strategy;}public Boolean handleList(List<T> list,T t) {return strategy.handle(list, t);}
}

(4)测试

/*** @Description 测试类* @author refuel* @version v1.0*/
public class Test {public static void main(String[] args) {Environment<Integer> en = new Environment<>(new AddStrategy<Integer>());List<Integer> arrList = Arrays.asList(10,20,30,40,50);List<Integer> list = new ArrayList<>(arrList);en.handleList(list, 60);for (Integer i : list) {System.out.print(i + " ");  //运行结果 10 20 30 40 50 60 }}
}

java基础之设计模式相关推荐

  1. 黑马程序员-Java基础:设计模式总结

    --Java培训.Android培训.iOS培训..Net培训.期待与您交流! -- Java基础部分设计模式 一.设计模式概述 设计模式(Design pattern)是一套被反复使用.多数人知晓的 ...

  2. Java基础篇--设计模式

    目录 前言 设计模式 创建型模式 单例模式 工厂方法模式 抽象工厂模式 建造者模式 原型模式 结构型模式 适配器模式 桥接模式 组合模式 装饰模式 外观模式 亨元模式 代理模式 行为型模式: 访问者模 ...

  3. Java基础之设计模式七大原则

    设计模式 目的 代码重用性 可读性 可扩展性-可维护 可靠性 程序呈现高内聚.低耦合的特性 七大原则 -设计模式为什么这样设计的依据 单一职责原则 概念 对类来说的,即一个类应该只负责一项职责.如类A ...

  4. java基础_设计模式_设计基础(小鸭子游戏)

    小鸭子游戏,是好多爱好者接触设计模式.认知设计模式概念的一个入门. 每个初学者的理解不同,我加上自己的理解大体是这样的:前提是处理大规模时,假设池塘中有10000头小鸭子,有红头鸭,野鸭子,木头鸭子等 ...

  5. java基础(六)多线程/设计模式

    这辈子没办法做太多事情,所以每一件都要做到精彩绝伦! People can't do too many things in my life,so everything will be wonderfu ...

  6. Java基础再回首之设计模式系列①-----StrategyPattern 策略者模式(案列教程,附带demo)

    一.前言 自己学java学的也熟悉了.踏入工作的不归路之后,身为一个Android开发工程师,不仅要Java基础扎实,还要对其的设计模式有所掌握,最近在群听到<Head First>这本书 ...

  7. 从Java类库看设计模式

    //From http://www.uml.org.cn/j2ee/201010214.asp 很多时候,对于一个设计来说(软件上的,建筑上的,或者它他工业上的),经验是至关重要的.好的经验给我们以指 ...

  8. 我的面试标准:第一能干活,第二Java基础要好,第三最好熟悉些分布式框架!...

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:hsm_computer www.cnblogs.com/J ...

  9. java 多态判断非空_跳槽涨薪季面试题之java基础(一)

    点击上方[全栈开发者社区]→右上角[...]→[设为星标⭐] 为迎接金九银十跳槽涨薪季,小编汇总了java精编版面试题,大概从java基础.java8特性.多线程.spring.springboot. ...

最新文章

  1. java log 封装_工具类之LogUtils
  2. Ubuntu下hadoop的安装与简单应用
  3. python表白代码弹窗-python实现祝福弹窗效果
  4. 推荐升级版PDF在线转Word转换器
  5. Oracle查询优化-07日期运算
  6. 鸿蒙硬件HI3861点灯
  7. 华为 5G 遭受致命一击!
  8. 大规模细粒度分类和特定领域的迁移学习
  9. html开发列表搜索,前端实例练习 - 可搜索列表
  10. jQuery 左侧滑动
  11. navicat 12 for mac 中文破解版使用说明
  12. opencv实现人脸识别中过曝光人脸图片处理
  13. 【IT项目管理】第7章 保证项目质量
  14. 网络摄像机如何安装拾音器?进行同步录音
  15. CTF之MISC练习一
  16. 堡垒机(运维审计系统)的基本原理与部署方式
  17. 魔戒显示网络错误 或者服务器停机,指环王安装和运行过程中的常见问题及解决办法(汇总)...
  18. 全球PM25实时可视化
  19. 爬取今日头条收藏夹文章列表信息
  20. 通用后台管理系统,管理后台框架模板演示地址

热门文章

  1. @RequestMapping 和 @GetMapping @PostMapping 区别
  2. asp.net登录状态验证
  3. 学习微信公众号oauth2.0
  4. Splay初步【bzoj1503】
  5. bzoj:2018 [Usaco2009 Nov]农场技艺大赛
  6. 手脱ACProtect V1.4X(有Stolen Code)之补区段
  7. C#微信公众号开发系列教程二(新手接入指南)
  8. windows系统c++多线程开发
  9. 快学好这个去给学妹修热水器
  10. c语言画谢宾斯基三角形