设计模式: 1、模板设计模式(了解):抽象类 2、单例设计模式(重点):多线程时 3、装饰者设计模式(IO流体系结构就体现了) 4、迭代器设计模式(集合,在集合的内部设计迭代器类型) 5、工厂设计模式(了解) 6、代理设计模式(了解)
一、工厂设计模式:目的(好处面试)为了解耦合,把对象的创建者与对象的使用者分开。 生活中:批量生产产品 Java中:批量生产对象
生活中: 最早没有工厂,自给自足,男耕女织 作坊 大工厂 Java: 没有工厂,需要对象,自己new
分工: 把生产(创建)对象与使用对象分开了,目的:解耦合(不需要创建对象,直接get就行)
没有工厂举例
@Test public void test01(){ //没有工厂 BMW b = new BMW(); //使用对象,调用方法 b.run(); } interface Car{ void run(); } class BMW implements Car{ @Override public void run() { System.out.println("宝马让你在车里面哭"); } }可以运行,但是创建对象和使用对象要同时完成,很麻烦,有时new对象会很麻烦,比如spring容器new一个对象需要读整个spring配置文件,要初始化很多信息,就很麻烦,所以为了简便,将new一个对象交给工厂来做
1、简单工厂模式
优点:代码比较简洁缺点:如果增加新的产品类型,需要修改工厂类 违反了面向对象的一个开发原则:对扩展开放,对修改关闭
//工厂类 class SimpleFactory{ //专门造车对象,可以不用static,使用时先创建一个car对象就行,加static不用创建,更简便 public static Car getCar(){ return new BMW(); } } class Benz implements Car{ @Override public void run() { System.out.println("奔驰让你在车盖上哭"); } } class Audi implements Car{ @Override public void run() { System.out.println("奥迪让你在..."); } @Test public void test02(){ Car c = SimpleFactory.getCar(); c.run();//这里也是运行宝马的run(),但是从头至尾没有出现BMW类型,没有依赖 }若是复杂一点
public class TestFactory { @Test public void test03(){ //使用第二个版本的工厂 Car c = SimpleFactory2.getCar("奔驰"); c.run(); } } interface Car{ void run(); } class BMW implements Car{ @Override public void run() { System.out.println("宝马让你在车里面哭"); } } class Benz implements Car{ @Override public void run() { System.out.println("奔驰让你在车盖上哭"); } } class Audi implements Car{ @Override public void run() { System.out.println("奥迪让你在..."); } } //工厂类 class SimpleFactory{ public static Car getCar(){ return new BMW(); } } //第二个版本的工厂 class SimpleFactory2{ public static Car getCar(String type){ if("宝马".equals(type)){ return new BMW(); }else if("奔驰".equals(type)){ return new Benz(); } return null; } } }这个工厂模式不好的是:比如增加一个奔驰,就得改工厂类,改就违反了设计原则,对扩展开放,对修改关闭
2、工厂方法模式 特点:一个产品就对应一个工厂类
出发点: (1)为了生产对象与使用对象分开 (2)如果增加新产品,就不需要修改原来的工厂类
优点:遵循了增加新产品,不修改原来的类的原则, 缺点:类太多了
interface Che{ void run(); } class BaoMa implements Che{ @Override public void run() { System.out.println("宝马"); } } class BenChi implements Che{ @Override public void run() { System.out.println("奔驰"); } } interface GongChang{ Che getChe(); } class BaoMaFactory implements GongChang{ @Override public Che getChe() { return new BaoMa(); } } class BenChiFactory implements GongChang{ @Override public Che getChe() { return new BenChi(); } } public class TestFactory2 { public static void main(String[] args) { BaoMaFactory bf = new BaoMaFactory(); Che c = bf.getChe(); c.run(); } } //此时若是增加一个奥迪类,只需要增加一个工厂类,专门生产奥迪车,不需要动原来的代码总结:这时就要看个人出发点是什么,希望耦合度低一点,就用工厂模式,若是希望代码不要那么复杂,在前期运行的时候,短时间内,增加新产品可能性不高,用简单工厂就行。所以实际开发中,虽然简单工厂违背了原则,但简单工厂模式反而用的更多,因为代码更简洁,后面框架,JDBC连接池等都用的工厂模式
接口的实现类就叫产品,生产产品的类叫工厂 不管是简单工厂模式还是工厂模式,目的一样,实现形式不一样
有了反射后,简单工厂模式(或者工厂模式)与反射
interface Vehicle{ void run(); } class QQ implements Vehicle{ @Override public void run() { System.out.println("qq车"); } } class Aoto implements Vehicle{ @Override public void run() { System.out.println("奥拓"); } } class Atguigu implements Vehicle{ @Override public void run() { System.out.println("尚硅谷"); } } class SimpleFactory3{ public static Vehicle getVehicle(String className)throws Exception{ //className 传类名 Class clazz = Class.forName(className); return (Vehicle) clazz.newInstance(); } } public class TestFactory3 { public static void main(String[] args)throws Exception { //类名要写类的全名称 Vehicle c = SimpleFactory3.getVehicle("com.atguigu.test12.QQ"); c.run(); Vehicle c2 = SimpleFactory3.getVehicle("com.atguigu.test12.Aoto"); c2.run(); Vehicle c3 = SimpleFactory3.getVehicle("com.atguigu.test12.Atguigu"); c3.run(); } }有了反射后,解决了简单工厂模式的问题
注意:此案例所有类在一个java文件中