写这篇文章的目的主要是为了纪录学习的,然后查漏补缺,欢迎指正。文章如果有发现引用他人的名言警句,不要慌张,给我留言,毕竟站在伟人的肩膀上。
设计模式GOF23(group of four)
前言:
在软件中,模式是帮助人类向“变化”战斗,但是在软件中还需要和“变化”直接面对面战斗的武器:人的思维,特别是创造,分析思维等等,这些是软件真正的灵魂,这种思维可以说只要有实践需求(如有新项目)就要求发生,发生频度高,人类的创造或者分析思维决定了软件的质量合和特点。
而在建筑中,模式可以构成建筑全部只是,当有新的需求(如有新的项目),一般使用旧的模式都可以完成,因此对人类的创造以及分析思维不是每个项目都必须的,也不是非常重要的,对创造性的思维的需求只是属于锦上添花(除非人类以后离开地球居住了)。
以上两段是借鉴他人的,具体摘抄信息无法提供,不过如果我有引用到您的成果,请联系我。
设计模式有以下类型:
创建型模式:
-单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式。
结构型模式:
-适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
行为型模式:
-模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。
一、设计模式之单例模式
核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。
常见应用场景:
--Windows的Task Manager(任务管理器)就是很典型的单例模式;(由一个对象组成的,不管你启动多少个任务管理器,页面显示只会有一个)
--windows的回收站,也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例
--项目中,读取配置文件的类,一般也只有一个对象。没有必要每次使用配置文件数据,每次new一个对象去读取
--网站的计数器,一般也是采用单例模式实现,否则难以同步
--应用程序的日志应用,一般都可用单例模式实现。这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加
--数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源
--操作系统的文件系统,也是采用的单例模式实现的及具体例子,一个操作系用只能有一个文件系统
--Application也是单例的典型应用(Servlet变成中会涉及到)
--在Spring中,每个Bean默认就是单例的,这样做的有点是Spring容器可以管理
--在servlet编程中,每个Servlet也是单例
--在spring MVC框架/struts1框架中,控制器对象也是单例
--常常看到工厂模式中类装入器(class loader)中也用Singleton模式实现的,因为被装入的类实际也属于资源。
单例模式的优点:
--由于单例模式只生成一个实例,减少了系统性能开销(限制实例个数,节省了内存,利于java垃圾回收(garbage collection)),当一个对象的产生需要比较多的资源时,如读取配置、产生其它依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决
--单例模式可以在系统设置全局的访问点,优化环境共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理
常见的五种单例模式实现方式:
--主要:
饿汉式(线程安全,调用效率高。但是,不能延时加载。)
懒汉式(线程安全,调用效率不高,但是,可以延时加载。)
--其他:
双重检测锁式(由于JVM底层内部模型原因,偶尔会出现问题。不建议使用)
静态内部类式(线程安全,调用效率高,可以延时加载)
枚举单例(线程安全,调用效率高,不能延时加载)
代码:
① 饿汉式
public class Singleton(){
private Singleton(){};//私有构造器
private static Singleton instance= new Singleton();//在自己内部定义一个实例
public static Singleton getInstance(){//创建一个访问方法
return instance;
}
}
② 懒汉式
public class LazeSingleton(){
private LazeSingleton(){} ;//私有构造方法
private static LazeSingleton instance; //创建私有变量
public static synchronized LazeSingleton getInstance(){
//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次
//使用时生成实例,提高了效率
if(instance==null){
return instance = new LazeSingleton();
}else{
return instance;
}
}
}
比较上述两个单例模式:
相同点:都是通过getInstance()可以访问单态类;
不同点:
a.第一种是饿汉式,不管三七二十一,不管对象用不用,上面就new;第二种是懒汉式,用的时候才new,并且new一次,无需再new,节省资源开支,减少了内存的使用;
b.第一种中没有使用synchronized,这个关键词在第二种方法中很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个LazeSingleton实例。
c.一般认为第一种形式更加安全些。
二、设计模式之工厂模式(Factory)
工厂模式定义:实现了创建者和调用者的分离。
详细分类:
简单工厂模式
工厂方法模式
抽象工厂模式
面向对象大合集的基本原则:
OCP (开闭原则,Open-Closed Principle):一个软件的实体应当对扩展开放,对修改关闭;
DIP (依赖倒转原则,Dependence Inversion Principle):要针对接口编程,不要针对实现编程;
LOD (迪米特法则,Law of Demeter):只与你直接的朋友通信,而避免和陌生人通信。
核心本质:
实例化对象,用工厂方法代替new操作。
将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。
工厂模式:
简单工厂模式:用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改已有的代码)
工厂方法模式:用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂模式:用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
简单工厂模式代码:
接口:
/**
* @author happy
* time goes by without time.
*/
public interface Car {
void run();
}
bean类:
/**
* @author happy
* time goes by without time.
*/
public class AuDi implements Car{
@Override
public void run() {
System.out.println("this is AoDi.");
}
}
public class HaFo implements Car {
@Override
public void run() {
System.out.println("this is HaFo.");
}
}
public class SimpleFactory {
public static Car createFactory(String a){
if ("AoDi"==a){
return new AuDi();
}else if ("HaFo"==a){
return new HaFo();
}else
return null;
}
}
//主方法
public class Factory {
public static void main(String[] args) {
Car c1 = SimpleFactory.createFactory("AoDi");
c1.run();
}
}
小结:简单工厂模式也叫静态工厂模式,就是工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。项目开发中,通常多使用简单工厂模式。不修改代码的话,是无法扩展的,与开闭原则冲突。
工厂方法模式代码:
//其它的bean类与上面简单工厂模式相同
//工厂方法:每个牌子的汽车创建一个工厂类
public interface CarFactory {
Car createCar();
}
public class HaFoFactory implements CarFactory {
@Override
public Car createCar() {
return new HaFo();
}
}
public class Client {
public static void main(String[] args) {
Car c1 = new HaFoFactory().createCar();
c1.run();
}
}
小结:较简单工厂模式:结构复杂度提高(类增多);代码复杂度提高(代码复杂);客户端编程难度提高(需要实例化);管理难度上,工厂方法模式完全满足OCP,但是为了满足其扩展性,要用增加类,提高代码复杂度和客户端编程难度为前提。理论上采用,工厂方法模式。但实际上开发中,我们一般采用简单工厂模式。
代码:
/**
* @author happy
* time goes by without time.
*/
public interface Engine {
void run();
void start();
}
class LuxuryEngine implements Engine{
@Override
public void run() {
System.out.println("力气大!");
}
@Override
public void start() {
System.out.println("启动快!");
}
}
class LowerEngine implements Engine{
@Override
public void run() {
System.out.println("力气小!");
}
@Override
public void start() {
System.out.println("启动慢!");
}
}
/**
* @author happy
* time goes by without time.
*/
public interface Seat {
void massage();
}
class LuxurySeat implements Seat{
@Override
public void massage() {
System.out.println("做起来舒服!");
}
}
class LowerSeat implements Seat{
@Override
public void massage() {
System.out.println("做起来不舒服!");
}
}
/**
* @author happy
* time goes by without time.
*/
public interface Tyre {
void revolve();
}
class LuxuryTyre implements Tyre{
@Override
public void revolve() {
System.out.println("跑的远!");
}
}
class LowerTyre implements Tyre{
@Override
public void revolve() {
System.out.println("跑的不远!");
}
}
/**
* @author happy
* time goes by without time.
*/
public interface CarFactory {
Engine createEngine();
Seat createSeat();
Tyre createTyre();
}
/**
* @author happy
* time goes by without time.
*/
public class LuxuryCarFactory implements CarFactory {
@Override
public Engine createEngine() {
return new LuxuryEngine();
}
@Override
public Seat createSeat() {
return new LuxurySeat();
}
@Override
public Tyre createTyre() {
return new LuxuryTyre();
}
}
/**
* @author happy
* time goes by without time.
*/
public class LowerCarFactory implements CarFactory {
@Override
public Engine createEngine() {
return new LowerEngine();
}
@Override
public Seat createSeat() {
return new LowerSeat();
}
@Override
public Tyre createTyre() {
return new LowerTyre();
}
}
/**
* @author happy
* time goes by without time.
*/
public class Client {
public static void main(String[] args) {
CarFactory fac1 = new LuxuryCarFactory();
fac1.createEngine().run();
fac1.createSeat().massage();
fac1.createTyre().revolve();
}
}
小结:抽象工厂模式要点:简单工厂模式(静态工厂模式)虽然某种程度不符合设计原则,但实际使用最多;工厂方法模式不修改已有类的前提下,通过增加新的工厂类实现扩展;抽象工厂模式不可以增加产品,可以增加产品族!应用场景(多):
--jdk中Calendar的getInstance方法
--JDBC中Connection对象的获取
--spring中IOC容器创建管理bean对象
--反射中Class对象的newInstance()
--XML解析时的DocumentBuilderFactory创建解析器对象
更多推荐
Java中23中设计模式
发布评论