精华内容
下载资源
问答
  • 工厂模式-从jdk与spring解读三种工厂模式简单工厂模式简单工厂模式的代码实现简单工厂JDK中的例子CalendarLoggerFactory工厂方法模式简单工厂模式的不足JDK中的例子ILoggerFactory抽象工厂模式抽象工厂是什么JDK中...

    简单工厂模式、工厂方法模式、抽象工厂模式,是一个由简到繁,根据需求的不断复杂化多样化而诞生的过程,工厂模式其实就是根据工厂创建对象,只不过有的是小作坊,有的是大车间

    简单工厂模式

    简单工厂模式就相当于一个小作坊,客户端给工厂传一个参数(可以是类名,或者类的字节码对象等)

    简单工厂模式的代码实现

    /**
    * 造车的接口
    */
    public interface ICar{
    	// 造轮胎
    	void createWheel();
    	// 造发动机
    	void createEngine();
    }
    
    /**
    * 造公交车的类
    */
    public class Bus implements ICar{
    	// 造轮胎
    	public void createWheel(){
    		System.out.println("造出一个大巴轮胎");
    	};
    	// 造发动机
    	public void createEngine(){
    		System.out.println("造出一个大巴发动机");
    	};
    }
    
    /**
    * 造卡车的类
    */
    public class Truck implements ICar{
    	// 造轮胎
    	public void createWheel(){
    		System.out.println("造出一个卡车轮胎");
    	};
    	// 造发动机
    	public void createEngine(){
    		System.out.println("造出一个卡车发动机");
    	};
    }
    
    /**
    * 造车工厂
    */
    public class CarFactory{
    	// 造车方法
    	public ICar createCar(Class<? extends ICar> clazz){
    		try {
    			if (null != clazz)
    				return clazz.newInstance();
    			}
    		}catch (Exception e){
    			e.printStackTrace();
    		}
    		return null;
    	}
    }
    
    /**
    * 客户端
    */
    public static void main(String[] args){
    	// 创建一个简单工厂,并传入Bus的字节码对象,来获得一个Bus的对象
    	CarFactory factory = new CarFactory();
    	ICar bus = factory.createCar(Bus.class);
    }
    

    这里假设我们创建对象的过程比较复杂,这样的话就相当于把创建对象的过程封装到了工厂中,调用者只需要传入需要的参数即可获得对应的对象实例,不需要关心具体是怎么创建出来的。

    简单工厂在JDK中的例子

    Calendar

    在这里插入图片描述
    在这里插入图片描述
    createCalendar这个方法,和我们的createCar其实是一样的,他这个里面的逻辑就是为了得到一个Calendar对象。
    这里先不讨论具体的创建过程,只关注它的简单工厂思想的部分。
    里面还涉及到了其他设计模式,可见我们的设计模式一般是混合使用的。

    LoggerFactory

    比如我们常用的门面,org.slf4j.LoggerFactory

    public static Logger getLogger(String name) {
            ILoggerFactory iLoggerFactory = getILoggerFactory();
            return iLoggerFactory.getLogger(name);
        }
    
        public static Logger getLogger(Class<?> clazz) {
            Logger logger = getLogger(clazz.getName());
            if (DETECT_LOGGER_NAME_MISMATCH) {
                Class<?> autoComputedCallingClass = Util.getCallingClass();
                if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {
                    Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(), autoComputedCallingClass.getName()));
                    Util.report("See http://www.slf4j.org/codes.html#loggerNameMismatch for an explanation");
                }
            }
    
            return logger;
        }
    

    这里的两个getLogger方法也都类似于createCar,只不过是传参的不同而已,方法内不管多复杂,最终都是为了得到一个Logger实例来进行日志的输出,我们的调用是简单的。

    // 从工厂获取实例,调用
    private final Logger logger = LoggerFactory.getLogger(Test.class);
    logger.info("输出了一行日志,行号为{}:",lineNumber);
    

    工厂方法模式

    简单工厂模式的不足

    简单工厂模式封装了生成bean的过程,但是工厂的职责太重,不利于产品的拓展,只适用单一简单的情况。
    比如上面造车的例子,如果我们的产品结构再复杂一点,巴士和卡车的造车组装过程肯定是有所差别的。
    这样的话,我们就需要对工厂做如下改造

    /**
    * 造车工厂
    */
    public class CarFactory{
    	// 造车方法
    	public ICar createCar(Class<? extends ICar> clazz){
    		try {
    			if (null != clazz)
    				if(Bus.class.equals(clazz)){
    					//要获取的是巴士,找些巴士司机来进行模拟测评
    				}
    				if(Truck.class.equals(clazz)){
    					//要获取的是卡车,找些卡车司机来进行模拟测评
    				}
    				// 对应车的组装前置过程完成后,再返回实例
    				return clazz.newInstance();
    			}
    		}catch (Exception e){
    			e.printStackTrace();
    		}
    		return null;
    	}
    }
    

    这样当然是没有问题的,但是如果我们再增加一种产品-吉普车(Jeep),那么就又需要改造工厂类了。如果这个时候,对巴士的改造过程也要做改变,把司机车龄限制成10年以上…
    反正都要改这个CarFactory,容易引起代码冲突不说,还很混乱,容易对之前的功能也造成影响。
    这很显然不符合我们的开闭原则。
    所以这个时候就需要把能抽象的抽象一下,能解耦的解耦,能分离的分离

    /**
    * 造车工厂接口
    */
    public interface ICarFactory{
    	// 造车方法
    	public ICar createCar(){}
    }
    
    /**
    * 巴士工厂接口
    */
    public class BusFactory implements ICarFactory{
    	// 造车方法
    	public ICar createCar(){
    		//找些巴士司机来进行模拟测评
    	}
    }
    
    /**
    * 卡车工厂接口
    */
    public class TruckFactory implements ICarFactory{
    	// 造车方法
    	public ICar createCar(){
    		//找些卡车司机来进行模拟测评
    	}
    }
    
    /**
    * 客户端
    */
    public static void main(String[] args){
        // 由客户端来决定实例化哪个工厂
    	CarFactory factory = new BusFactory();
    	ICar bus = factory.createCar(Bus.class);
    }
    

    这样如果我们要再增加一个吉普,只需要再增加一个类就行,不需要改其他代码,不用担心对Bus或者Truck的已有逻辑造成影响

    JDK中的例子

    ILoggerFactory

    在这里插入图片描述
    还是我们的日志,其实日志系统是一个很好的学习设计模式的例子。
    具体的实现不用管,通过类图,我们能清楚的看到,SubstituteLoggerFactory和NOPLoggerFactory都实现了ILoggerFactory这个工厂接口。正是我们上面说的工厂方法模式。

    抽象工厂模式

    抽象工厂是什么

    其实,个人感觉无需太过纠结具体定义。抽象工厂顾名思义就是在工厂方法模式的基础上,更加抽象了一步,业务场景更复杂一些。
    从简单工厂到工厂方法模式,我们把一个大而全的工厂抽象成了具体的功能的工厂。那么工厂抽象出来了,再抽象还能抽象什么呢?
    没错,就是每个具体的产品中的方法

    /**
    * 造公交车的类
    */
    public class Bus implements ICar{
    	// 造轮胎
    	public void createWheel(){
    		System.out.println("造出一个大巴轮胎");
    	};
    	// 造发动机
    	public void createEngine(){
    		System.out.println("造出一个大巴发动机");
    	};
    }
    
    /**
    * 造卡车的类
    */
    public class Truck implements ICar{
    	// 造轮胎
    	public void createWheel(){
    		System.out.println("造出一个卡车轮胎");
    	};
    	// 造发动机
    	public void createEngine(){
    		System.out.println("造出一个卡车发动机");
    	};
    }
    

    只要有相似重复可拓展的东西,都可以抽象。我们可以吧轮胎、卡车等具体方法抽象出来
    我们先把公交车和卡车的类稍作改造,让它变得贴近一些实际场景。

    /**
    * 大巴轮胎
    */
    public class BusWheel{
    	// 设置形状
    	void setShape(...);
    	// 设置尺寸
    	void setSize(...);
    	// 进行公交车特有质量检测
    	void excuteCheckForBus(...);
    }
    
    /**
    * 卡车轮胎
    */
    public class TruckWheel{
    	// 设置形状
    	void setShape(...);
    	// 设置尺寸
    	void setSize(...);
    }
    

    BusWheel

    /**
    * 造公交车的类
    */
    public class Bus implements ICar{
    	// 造轮胎
    	public void createWheel(){
    		return new BusWheel();
    	};
    	// 造发动机
    	public void createEngine(){
    		return new BusEngine();
    }
    
    /**
    * 造卡车的类
    */
    public class Truck implements ICar{
    	// 造轮胎
    	public void createWheel(){
    		return new TruckWheel();
    	};
    	// 造发动机
    	public void createEngine(){
    		return new TruckEngine();
    	};
    }
    

    我们这里以轮胎为例,BusEngine和TruckEngine暂时省略。
    这里的Bus就是一个产品族,BusWheel是一个产品
    同样Truck也是一个产品族,TruckWheel也是一个产品
    这个时候我们改造完成了,怎么抽象呢?
    我们发现,大巴和卡车的轮胎制造流程很相似,所有设置尺寸和设置形状的方法,那完全可以抽象一个接口出来。

    /**
    * 汽车轮胎标准接口
    */
    public interface Wheel{
    	// 设置形状
    	void setShape();
    	// 设置尺寸
    	void setSize();
    }
    
    /**
    * 大巴轮胎
    */
    public class BusWheel implements Wheel{
    	// 设置形状
    	void setShape(...);
    	// 设置尺寸
    	void setSize(...);
    	// 进行公交车特有质量检测
    	void excuteCheckForBus(...);
    }
    
    /**
    * 卡车轮胎
    */
    public class TruckWheel implements Wheel{
    	// 设置形状
    	void setShape(...);
    	// 设置尺寸
    	void setSize(...);
    }
    

    这样,就把具体产品抽象出来了,也符合我们的现实场景,比如轮胎是有一个统一生产标准的。
    提到统一,我们又想到,如果所有轮胎的形状是一样的,那么是不是可以把这部分实现放在接口中,把他变成一个抽象类?
    当然是可以的。
    综上,其实就已经是个抽象工厂模式了
    抽象工厂比抽象方法模式的便捷处在于,它更贴合现在现实的场景,适应更复杂的业务场景。比如我们如果要把轮胎改成球形而不是圆形,如果不适用抽象工厂模式,则需要修改每一个工厂的createWheel方法,现在只需要修改上层接口就好。

    JDK中的应用

    Collection

    在这里插入图片描述
    Collection对应Wheel,下面三个可以对应BusWheel、TruckWheel、JeepWheel等。
    如果再有个获取List的工厂(源码我找了半天没找到类似的),比如ListFactory、QueueFactory、SetFactory,这就是一个完整的抽象工厂了

    小结

    其实通过分析以及阅读源码,我们发现了几点

    • 设计模式一般都是混合使用的
    • 三种工厂模式的区别其实没那么重要,重要的是我们实际场景中,需要抽象到哪一步,三者只是抽象程度不同而已
    • 没有哪种比哪种好,甚至有时候用设计模式不一定就便捷,杀鸡焉用宰牛刀,适合最重要
    • 设计模式提供的更多是贴合几大原则的设计思路,而不是死搬硬套的去套,这点从源码的实现上也可以看出来。
    展开全文
  • 抽象工厂模式(Abstract Factory) 工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就...

    http://ichennan.com/2016/08/09/DesignPattern.html    http://blog.csdn.net/liruikqn/article/details/12888511


    抽象工厂模式(Abstract Factory)

    工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。

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

    类型:创建类模式


    抽象工厂模式与工厂方法模式的区别

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




    可以看到产品族包括ProductA和ProductB两种产品,每个具体工厂都能生产这两种产品,只是ConcreteFactory1生产的等级为1的族产品;ConcreteFactory2生产的是等级为2的族产品。下面以上图为模型,写一个demo,测试抽象工厂模式。

    抽象工厂:AbstractFactory接口

    [html]  view plain  copy
    1. //抽象工厂,定义了生产族产品的方法;  
    2. public interface AbstractFactory {  
    3.     public ProductA factoryA();  
    4.     public ProductB factoryB();  
    5. }  


    抽象产品:ProductA接口

    [html]  view plain  copy
    1. //抽象产品A定义了产品的公共方法,产品A和B属于一个产品族  
    2. public interface ProductA {  
    3.     public void method1();  
    4.     public void method2();  
    5. }  


    抽象产品:ProductB接口

    [html]  view plain  copy
    1. //抽象产品B定义了产品的公共方法,产品A和B属于一个产品族  
    2. public interface ProductB {  
    3.     public void method1();  
    4.     public void method2();  
    5. }  


    具体工厂(生产等级为2的族产品):ConcreteFactory1类

    [html]  view plain  copy
    1. //ConcreateFactory1是用来生产等级为1的产品A,B的具体工厂;  
    2. public class ConcreateFactory1 implements AbstractFactory {  
    3.   
    4.     //生产等级为1的产品A  
    5.     @Override  
    6.     public ProductA factoryA() {  
    7.         // TODO Auto-generated method stub  
    8.         return new ConcreateProductA1();  
    9.     }  
    10.   
    11.       
    12.     //生产等级为1的产品B  
    13.     @Override  
    14.     public ProductB factoryB() {  
    15.         // TODO Auto-generated method stub  
    16.         return new ConcreateProductB1();  
    17.     }  
    18.   
    19. }  


    具体工厂(生产等级为1的族产品):ConcreteFactory2类
    [html]  view plain  copy
    1. public class ConcreateFactory2 implements AbstractFactory {  
    2.   
    3.     //生产等级为2的产品A  
    4.     @Override  
    5.     public ProductA factoryA() {  
    6.         // TODO Auto-generated method stub  
    7.         return new ConcreateProductA2();  
    8.     }  
    9.   
    10.     //生产等级为2的产品B  
    11.     @Override  
    12.     public ProductB factoryB() {  
    13.         // TODO Auto-generated method stub  
    14.         return new ConcreateProductB2();  
    15.     }  
    16. }  


    具体产品(等级为1的A产品):ConcreteProductA1类

    [html]  view plain  copy
    1. //等级为1的具体产品A  
    2. public class ConcreateProductA1 implements ProductA {  
    3.   
    4.     @Override  
    5.     public void method1() {  
    6.         // TODO Auto-generated method stub  
    7.         System.out.println("等级为1的产品A的method1()");  
    8.     }  
    9.   
    10.     @Override  
    11.     public void method2() {  
    12.         // TODO Auto-generated method stub  
    13.         System.out.println("等级为1的产品A的method2()");  
    14.     }  
    15. }  


    具体产品(等级为2的A产品):ConcreteProductA2类

    [html]  view plain  copy
    1. //等级为2的具体产品A  
    2. public class ConcreateProductA2 implements ProductA {  
    3.   
    4.     @Override  
    5.     public void method1() {  
    6.         // TODO Auto-generated method stub  
    7.         System.out.println("等级为2的产品A的method1()");  
    8.     }  
    9.   
    10.     @Override  
    11.     public void method2() {  
    12.         // TODO Auto-generated method stub  
    13.         System.out.println("等级为2的产品A的method2()");  
    14.     }  
    15. }  


    具体产品(等级为1的B产品):ConcreteProductB1类

    [html]  view plain  copy
    1. //等级为1的产品B  
    2. public class ConcreateProductB1 implements ProductB{  
    3.   
    4.     @Override  
    5.     public void method1() {  
    6.         // TODO Auto-generated method stub  
    7.         System.out.println("等级为1的产品B的method1()");  
    8.     }  
    9.   
    10.     @Override  
    11.     public void method2() {  
    12.         // TODO Auto-generated method stub  
    13.         System.out.println("等级为1的产品B的method2()");  
    14.     }  
    15. }  


    具体产品(等级为2的B产品):ConcreteProductB2类

    [html]  view plain  copy
    1. //等级为2的产品B  
    2. public class ConcreateProductB2 implements ProductB {  
    3.   
    4.     @Override  
    5.     public void method1() {  
    6.         // TODO Auto-generated method stub  
    7.         System.out.println("等级为2的产品B的method1()");  
    8.     }  
    9.   
    10.     @Override  
    11.     public void method2() {  
    12.         // TODO Auto-generated method stub  
    13.         System.out.println("等级为2的产品B的method2()");  
    14.     }  
    15. }  


    使用场景:

    • JDK中体现:
      (1)Java.sql包
      (2)UIManager(swing外观)
    类图:



    ===================================


    简单工厂模式

    简单工厂模式不是23种里的一种,简而言之,就是有一个专门生产某个产品的类。
    比如下图中的鼠标工厂,专业生产鼠标,给参数0,生产戴尔鼠标,给参数1,生产惠普鼠标。

    1

    工厂模式

    工厂模式也就是鼠标工厂是个父类,有生产鼠标这个接口。
    戴尔鼠标工厂,惠普鼠标工厂继承它,可以分别生产戴尔鼠标,惠普鼠标。
    生产哪种鼠标不再由参数决定,而是创建鼠标工厂时,由戴尔鼠标工厂创建。
    后续直接调用鼠标工厂.生产鼠标()即可

    1

    抽象工厂模式

    抽象工厂模式也就是不仅生产鼠标,同时生产键盘。
    也就是PC厂商是个父类,有生产鼠标,生产键盘两个接口。
    戴尔工厂,惠普工厂继承它,可以分别生产戴尔鼠标+戴尔键盘,和惠普鼠标+惠普键盘。
    创建工厂时,由戴尔工厂创建。
    后续工厂.生产鼠标()则生产戴尔鼠标,工厂.生产键盘()则生产戴尔键盘。

    1

    在抽象工厂模式中,假设我们需要增加一个工厂

    假设我们增加华硕工厂,则我们需要增加华硕工厂,和戴尔工厂一样,继承PC厂商。
    之后创建华硕鼠标,继承鼠标类。创建华硕键盘,继承键盘类。
    即可。

    1

    在抽象工厂模式中,假设我们需要增加一个产品

    假设我们增加耳麦这个产品,则首先我们需要增加耳麦这个父类,再加上戴尔耳麦,惠普耳麦这两个子类。
    之后在PC厂商这个父类中,增加生产耳麦的接口。最后在戴尔工厂,惠普工厂这两个类中,分别实现生产戴尔耳麦,惠普耳麦的功能。
    以上。

    1




    展开全文
  • 建造模式(Builder模式) 假如有一个需求:盖房子,盖房子过程是一致的:打桩、砌墙、封顶。但是房子是各式各样的,最后盖出来的房子可能是高楼或别墅。 根据直接的思路,不用设计模式思想,我们也许会: 写一个 ...

    0、背景

    建造模式(Builder模式)

    假如有一个需求:盖房子,盖房子过程是一致的:打桩、砌墙、封顶。但是房子是各式各样的,最后盖出来的房子可能是高楼或别墅。

    根据直接的思路,不用设计模式思想,我们也许会:

    1. 写一个 CommonHouse 抽象类,然后里面规定了打桩、砌墙、封顶三个方法;
    2. 让不同房子继承这个类;
    3. 最后调用的时候调用分别的方法即可。

    在继承抽象类、子类区分这一块,思想没有问题,问题出现这些类本身。

    缺点:

    过于简单,将产品(房子)和创建产品(房子建造流程)封装在了一起,耦合性增强了。(可以理解为,面向对象的思想里,房子虽然是一个类,拥有自己的方法,但是房子不应该拥有建造自己的方法)

    解决方法:

    解耦 - > 建造者模式。

    一、建造者模式

    建造者模式(Builder Pattern)又叫生成器模式,是一种对象构建模式(创建型),可以将复杂对象的建造过程抽象出来(抽象类),使这个抽象过程的不同实现方法能构造出不同表现(属性)的对象。

    建造模式允许用户只通过指定复杂对象的类型和内容就可以构建他们,用户不需要知道内部的具体构建细节。

    建造者模式的四个角色:

    1. Product产品:一个具体产品对象;
    2. Builder(抽象建造者):创建Product对象指定的 接口或者抽象类;
    3. ConcreteBuilder具体建造者:实现接口,构建和装配各个部件;
    4. Director指挥者:构建一个使用Builder接口的对象,主要用于创建一个复杂度对象,有两个作用:一是隔离客户与对象的生产过程,二是负责控制产品对象的生产过程。

    他们之间的关系,我们用类图来解释:

    在这里插入图片描述

    • Directer里面聚合一个Builder实际上使用的是他的实现类ConcreteBuilder;
    • ConcreteBuilder可以有很多,就是所谓的不同的房子的建造者。

    因为getRusult是一样的,所以暂时不用接口,用抽象类实现Builder,代码如下:

    /*
        产品,对应product
    */
    public class House {
        private String base;
        private String wall;
        private String roof;
        //对应getset方法
    }
    
    /*
        抽象的建造者,对应Builder
    */
    public abstract class HouseBuilder {
        protected House house = new House();
        //写好流程的各个方法,但不约束具体执行
        public abstract void buildBasic();
        public abstract void buildWalls();
        public abstract void buildRoof();
        //建造方法,返回建造结果
        public House buildHouse(){
            return house;
        }
    }
    
    /*
        普通房子制造流程,继承抽象类
        可以看到,制造流程在这里,而House类拥有房子的属性,他们是分开的
        应是对House的操作,这里省略
    */
    public class CommonHouse extends HouseBuilder{
        @Override
        public void buildBasic() {
            System.out.println("普通房子:建造地基。。。");
        }
        @Override
        public void buildWalls() {
            System.out.println("普通房子:砌墙。。。");
        }
        @Override
        public void buildRoof() {
            System.out.println("普通房子:盖屋顶。。。");
        }
    }
    
    /*
        另一个实现类,本来应是对House的操作,这里省略
    */
    public class HighHouse extends HouseBuilder {
        @Override
        public void buildBasic() {
            System.out.println("高楼:建造地基。。。");
        }
        @Override
        public void buildWalls() {
            System.out.println("高楼:砌墙。。。");
        }
        @Override
        public void buildRoof() {
            System.out.println("高楼:盖屋顶。。。");
        }
    }
    
    /*
        Director,聚合建造者HouseBuilder
        同时决定制作流程,最后调用建造者的buildHouse方法返回
    */
    public class Director {
        HouseBuilder houseBuilder = null;
        //通过构造器聚合
        public Director(HouseBuilder houseBuilder) {
            this.houseBuilder = houseBuilder;
        }
        //通过setter方法聚合
        public void setHouseBuilder(HouseBuilder houseBuilder) {
            this.houseBuilder = houseBuilder;
        }
        //指挥具体建造流程,先后顺序不由Builder决定
        public House constructHouse(){
            houseBuilder.buildBasic();
            houseBuilder.buildWalls();
            houseBuilder.buildRoof();
            return houseBuilder.buildHouse();
        }
    }
    
    /*
        客户端
    */
    public class Client {
        public static void main(String[] args) {
            //new房子
            CommonHouse commonHouse = new CommonHouse();
            //new指挥者
            Director director = new Director(commonHouse);
            //完成盖房
            House house = director.constructHouse();
    
            //重置建造者
            HighHouse highHouse = new HighHouse();
            director.setHouseBuilder(highHouse);
            House house1 = director.constructHouse();
        }
    }
    

    上面代码总结起来:一是要把房子归为房子,有属性就够了,建造归建造,相当于是建筑工人,和房子两个对象分开,那么Director相当于包工头,对于不同的House要指挥不一样的Builder群体。

    二、建造者模式在JDK中的应用

    java.lang.StringBuilder类,也就是常用的可变字符串类,用到的就是建造者模式。以其中的常用方法 append 方法为例看源码。

    2.1 Appendable 接口

    定义了多个 append 方法(抽象方法),即 Appendable 就是我们的抽象建造者Builder 。

    在这里插入图片描述

    2.2 具体的实现类 AbstractStringBuilder

    虽然也是一个抽象类,但是也已经实现了 Append able 接口的方法,所以其实相当于是具体的建造者ConcreteBuilder了;

    在这里插入图片描述

    2.3 StringBuilder,继承了AbstractStringBuilder

    但是他重写 append 方法的方式只是调用了父类方法,所以应该说,StringBuilder既充当了Director,又是一个ConcreteBuilder.

    在这里插入图片描述
    在这里插入图片描述

    三、注意事项

    1. 客户端不必知道产品呢内部组成的细节,将产品本身和产品的创建过程解耦,使得相同的创建过程可以创建不同的产品;
    2. 每一个具体的建造者都是相对独立的,和其他的建造者无关,因此可以方便替换具体建造者或者增加新的具体建造者,用户使用不同的具体建造者就能得到不同产品;
    3. 可以更加精细的控制创建过程;
    4. 增加新的具体建造者无需修改原有代码,指挥者针对抽象建造者编程;
    5. 建造者模式创建的产品,一定是共同点比较多,组成部分相似,如果产品之间的差异性很大,那么就不适合使用建造者模式,因此其适用范围受到一定的限制。

    建造者模式 VS 抽象工厂模式:

    抽象工厂模式实现对产品家族的创建,一个产品家族:具有不同分类维度的产品组合,采用抽象工厂模式不需要关心构建过程,只关心什么产品由什么工厂生产。

    建造者模式是按照指定的要求创造产品,主要目的是通过组装零件产生一个新产品。

    (可能有点模糊,但是个人认为本来就是模糊的。。只是一种设计思想,没有严格的边界。。。)

    展开全文
  • jdk中的设计模式 Zen的JCG合作伙伴Brian Du Preez 是IT领域的合作伙伴, 在收集JDK中最常见的设计模式方面做得非常出色。 模式列表的确令人印象深刻且很长,因此让我们不再ba不休,然后将其呈现给您。 前几天,我在...

    jdk中的设计模式

    ZenJCG合作伙伴Brian Du Preez 是IT领域的合作伙伴, 收集JDK中最常见的设计模式方面做得非常出色。 模式列表的确令人印象深刻且很长,因此让我们不再ba不休,然后将其呈现给您。

    前几天,我在Enterprise Dev上看到了Rob Williams Brain Drain的文章(更多是之作)。 我必须说,我同意他所说的一些话。 从我的亲身经历中我知道,我花了大约2年左右的时间才沉迷于企业开发领域,没有学习任何东西,实际上却失去了之前开发的技能。 公司面临的领域不利于急切的技术人员。

    他在这篇文章中还指出:

    “十分之一的测试甚至无法通过简单的测试,例如'在流库中使用哪种设计模式可以使BufferedReaderFileReader互换?'”

    我也在工作中进行了测试,在8个人中只有1个人要求正确

    在没有太大信心的情况下,我猜想Decorator是基于“可互换的”。 然后,我认为这实际上是值得在将来的采访中偷偷摸摸的,并且可能是修改一下的好时机。

    因此,我去互联网上寻找有关该主题的所有信息,但实际上却没有找到我想的那么多。 它大部分来自Stackoverflow的 BalusC,其余的则非常分散在博客文章,java牧场,一些旧的pdf以及我的文章之间。 我没有采用发现的每个模式的每个示例,而是使用了常见的模式。

    这可能是人们学习模式的好方法,很多时候他们每天都在不知不觉中使用它们。

    结构性

    适配器
    这用于将编程接口/类转换为另一个。

    • java.util.Arrays#asList()
    • javax.swing.JTable(TableModel)
    • java.io.InputStreamReader(InputStream)
    • java.io.OutputStreamWriter(OutputStream)
    • javax.xml.bind.annotation.adapters.XmlAdapter#marshal()
    • javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal()


    这将抽象与抽象操作的实现分离开来,因此抽象及其实现可以独立变化。

    • AWT(它提供了抽象层,该抽象层将窗口支持映射到本机OS。)
    • JDBC

    复合材料
    让客户统一对待单个对象和对象组成。 因此换句话说,类型上的方法接受相同的类型。

    • javax.swing.JComponent#add(Component)
    • java.awt.Container#add(Component)
    • java.util.Map#putAll(Map)
    • java.util.List#addAll(Collection)
    • java.util.Set#addAll(Collection)

    装饰器
    动态地将附加职责附加到对象,因此它也是子类化的替代方法。 在创建类型传递相同类型时可以看到。 实际上,这在整个JDK中都使用了,您看的越多,发现的越多,因此下面的列表绝对不完整。

    • java.io.BufferedInputStream(InputStream)
    • java.io.DataInputStream(InputStream)
    • java.io.BufferedOutputStream(OutputStream)
    • java.util.zip.ZipOutputStream(OutputStream)
    • java.util.Collections#checked [List | Map | Set | SortedSet | SortedMap]()

    外墙
    为一组组件,接口,抽象或子系统提供简化的接口。

    • java.lang.Class
    • javax.faces.webapp.FacesServlet

    飞行重量
    缓存以有效地支持大量较小的对象。 几个月前,我偶然发现了Apon。

    • java.lang.Integer#valueOf(int)
    • java.lang.Boolean#valueOf(boolean)
    • java.lang.Byte#valueOf(byte)
    • java.lang.Character#valueOf(char)

    代理人
    代理模式用于用较简单的对象表示创建复杂或耗时的对象。

    • java.lang.reflect.Proxy
    • RMI

    创造力的

    抽象工厂
    提供创建相关或从属对象族的合同,而不必指定其具体类。 它使人们能够将应用程序与正在使用的整个框架的具体实现脱钩。 在整个JDK和许多类似Spring的框架中也可以找到它。 它们很容易发现,可以用于创建对象但仍返回接口或抽象类的任何方法。

    • java.util.Calendar#getInstance()
    • java.util.Arrays#asList()
    • java.util.ResourceBundle#getBundle()
    • java.sql.DriverManager#getConnection()
    • java.sql.Connection#createStatement()
    • java.sql.Statement#executeQuery()
    • java.text.NumberFormat#getInstance()
    • javax.xml.transform.TransformerFactory#newInstance()

    建造者
    通过定义一个目的是构建另一个类的实例的类,可以简化复杂对象的创建过程。 构建器模式还允许实现Fluent接口。

    • java.lang.StringBuilder#append()
    • java.lang.StringBuffer#append()
    • java.sql.PreparedStatement
    • javax.swing.GroupLayout.Group#addComponent()

    工厂方法
    只是一个返回实际类型的方法。

    • java.lang.Proxy#newProxyInstance()
    • java.lang.Object#toString()
    • java.lang.Class#newInstance()
    • java.lang.reflect.Array#newInstance()
    • java.lang.reflect.Constructor#newInstance()
    • java.lang.Boolean#valueOf(String)
    • java.lang.Class#forName()

    原型
    允许其实例可以创建其自身副本的类。 当创建类的实例以某种方式非常耗时或复杂时,可以使用此方法,而不必创建新的实例,而是可以复制原始实例并对其进行修改。

    • java.lang.Object#clone()
    • java.lang.Cloneable

    单身人士
    这试图确保只有一个类的实例。 我没有找到示例,但是另一个解决方案是使用Joshua Bloch在Effective Java中建议的Enum。

    • java.lang.Runtime#getRuntime()
    • java.awt.Toolkit#getDefaultToolkit()
    • java.awt.GraphicsEnvironment#getLocalGraphicsEnvironment()
    • java.awt.Desktop#getDesktop()

    行为的

    责任链
    通过将请求从链中的一个对象传递到下一个对象,直到对象被识别为止,从而允许对象之间的解耦。 链中的对象是同一接口或抽象类的不同实现。

    • java.util.logging.Logger#log()
    • javax.servlet.Filter#doFilter()

    命令
    将命令包装在对象中,以便可以像存储其他任何对象一样将其存储,传递到方法中并返回。

    • java.lang.Runnable
    • javax.swing.Action

    口译员
    此模式通常描述为该语言定义语法并使用该语法解释该格式的语句。

    • java.util.Pattern
    • java.text.Normalizer
    • java.text.Format

    迭代器
    提供一致的方式来顺序访问独立于基础集合且与基础集合分离的集合中的项目。

    • java.util.Iterator
    • java.util.Enumeration

    调解员
    通过引入管理消息分发的单个对象,用于减少类之间的直接依赖关系的数量。

    • java.util.Timer
    • java.util.concurrent.Executor#execute()
    • java.util.concurrent.ExecutorService#submit()
    • java.lang.reflect.Method#invoke()

    纪念品
    这是对象状态的快照,因此该对象可以返回其原始状态,而不必透露其内容。 Date通过内部实际上具有长值来实现此目的。

    • java.util.Date
    • java.io.Serializable

    空对象
    通过提供替代的“不执行任何操作”行为,可以将其用于封装不存在的对象。 它允许您抽象空对象的处理。

    • java.util.Collections#emptyList()
    • java.util.Collections#emptyMap()
    • java.util.Collections#emptySet()

    观察员
    用于为组件提供一种向感兴趣的接收者灵活广播消息的方法。

    • java.util.EventListener
    • javax.servlet.http.HttpSessionBindingListener
    • javax.servlet.http.HttpSessionAttributeListener
    • javax.faces.event.PhaseListener

    状态
    这使您可以在运行时根据内部状态轻松更改对象的行为。

    • java.util.Iterator
    • javax.faces.lifecycle.LifeCycle#execute()

    策略
    旨在提供一种定义一系列算法的方法,将每个算法封装为一个对象。 然后可以灵活地传递它们以更改功能。

    • java.util.Comparator#compare()
    • javax.servlet.http.HttpServlet
    • javax.servlet.Filter#doFilter()

    模板方法
    允许子类重写方法的某些部分而不重写它,还允许您控制需要重写哪些操作的子类。

    • java.util.Collections#sort()
    • java.io.InputStream#skip()
    • java.io.InputStream#read()
    • java.util.AbstractList#indexOf()

    访客
    提供一种易于维护的简便方法来执行一系列课程的操作。 访客集中了行为,并允许在不更改其操作的类的情况下对其进行修改或扩展。

    • javax.lang.model.element.Element和javax.lang.model.element.ElementVisitor
    • javax.lang.model.type.TypeMirror和javax.lang.model.type.TypeVisitor

    好是好人的敌人!

    拜伦

    相关文章:


    翻译自: https://www.javacodegeeks.com/2011/03/design-patterns-in-jdk.html

    jdk中的设计模式

    展开全文
  • JDK设计模式/Spring设计模式示例

    千次阅读 2021-01-14 11:23:09
    目录 1、JDK设计模式 2、Spring设计模式示例 1、JDK设计模式 2、Spring设计模式示例
  • JDK动态代理模式详解

    2019-11-12 09:06:21
    常用的代理模式有,jdk动态代理s和CGLIB动态代理模式,JDK动态代理是java.lang.reflect.*包提供的方式,它必须提供一个接口才能产生代理对象。 下面讲解jdk动态代理,如下图: 假设有这样一个场景,你的公司是一个...
  • jdk中的设计模式

    2014-09-13 18:15:51
    我们可以在不修改JDK源码的前提下开发出自己的应用软件,本文列出了部分JDK中的模式应用实例,有兴趣的童鞋可以深入研究,看看前Sun公司的开发人员是如何在实际框架开发中运用设计模式的,,Sunny认为,研究JDK类库...
  • JDK中的设计模式工厂方法

    千次阅读 2011-10-25 00:29:18
    一、工厂方法模式简介:  工厂方法模式的意图是定义一个创建产品对象的工厂接口,让子类决定实例化哪一个类,工厂方法模式使一个类的实例化延迟到其子类。  工厂方法模式的类图如下:  ...
  • 深入分析JDK代理和CGLIB代理模式前言 前言
  • 【设计模式JDK源码中用到的设计模式

    千次阅读 多人点赞 2017-07-31 13:34:11
    引入我是从Stack Overflow上看到的问题,感觉这个答案真心...问题我正在学习GoF Java设计模式,我想看看他们的一些现实生活中的例子。Java核心库中的这些设计模式的一些很好的例子是什么?答案我选择了一个投票数最高
  • 本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 ...本文主要是归纳了JDK中所包含的设计模式,包括作用和其设计类图。 首先来个总结,具体的某个模式可...
  • 工厂模式 工厂类都是以 Factory 作为后缀来命名。 工厂类的功能主要就是创建对象。 是不是所有的工厂模式中都以Factory作为后缀来命名呢? 不是的,我们以 java.util.Calendar 为例。 public abstract ...
  • 代理模式 文章目录代理模式一、概述二、结构三、静态代理1. 案例说明2. 代码实现四、JDK动态代理1. 代码实现2. 底层原理五、CGLIB动态代理1. 代码实现2. 底层原理六、三种代理模式的对比1. JDK代理和CGLIB代理2. ...
  • 设计模式jdk中的应用

    千次阅读 2016-08-15 20:31:16
    JDK(Java Development Kit)类库中,开发人员使用了大量设计模式。   创建型模式: (1) 抽象工厂模式(Abstract Factory) • java.util.Calendar#getInstance() • java.util.Arrays#asList() ...
  • JDK

    千次阅读 2019-09-17 16:51:38
    JDK5 JDK6 JDK7 JDK8 JDK9 JDK10 JDK11 JDK12 文件对比 public static void main(String[] args) throws IOException { Path dir = Paths.get("d:/"); Path path1 = dir.resolve("javastack1.txt"); Pat...
  • 我们可以在不修改JDK源码的前提下开发出自己的应用软件,本文列出了部分JDK中的模式应用实例,有兴趣的同学可以深入研究,看看前Sun公司的开发人员是如何在实际框架开发中运用设计模式的,Sunny认为,研究JDK类库中...
  • 我们可以在不修改JDK源码的前提下开发出自己的应用软件,本文列出了部分JDK中的模式应用实例,有兴趣的童鞋可以深入研究,看看前Sun公司的开发人员是如何在实际框架开发中运用设计模式的,,Sunny认为,研究JDK类库...
  • JDK(Java Development Kit)类库中,开发人员使用了大量设计模式,正因为如此,我们可以在不修改 JDK 源码的前提下开发出自己的应用软件。研究 JDK 类库中的模式实例...(1) 抽象工厂模式(Abstract Factory) • java.
  • jdk中设计模式的实现

    千次阅读 2016-04-22 21:30:50
    抽象工厂模式 特点:创建方法返回一个可以用来创建抽象类或接口的工厂类。 javax.xml.parsers.DocumentBuilderFactory#newInstance() javax.xml.transform.TransformerFactory#newInstance() javax.xml....
  • JDK(JavaDevelopment Kit)类库中,开发人员使用了大量设计模式。 创建型模式: (1)抽象工厂模式(Abstract Factory) •java.util.Calendar#getInstance() •java.util.Arrays#asList() •java.util....
  • JDK里的设计模式

    千次阅读 2012-07-22 14:56:44
    下面是JDK中有关23个经典设计模式的示例,在stakeoverflow也有相应的讨论: http://stackoverflow.com/questions/1673841/examples-of-gof-design-patterns Structural(结构模式) Adapter: 把一个接口或是...
  • 解释器模式原理及其在JDK源码中的体现设计模式系列汇总前言什么是解释器模式终结符表达式和非终结符表达式解释器模式示例解释器模式角色解释器模式JDK和Spring源码中应用解释器模式应用场景解释器模式优缺点总结 ...
  • 感谢慕课geely老师的设计模式课程,本套设计模式的所有内容均以课程为参考。  前面的软件设计七大原则,目前只有理论这块,因为最近参与项目重构,暂时没有时间把Coding的代码按照设计思路一点点写出来。本周周末...
  • 在多线程编程中,我们经常使用线程池来管理线程,以减缓线程频繁的创建和销毁带来的资源的浪费,在创建线程池的时候,经常使用一个工厂类来创建线程池Executors,实际上Executors的内部使用的是类ThreadPoolExecutor....
  • 工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例; 单例模式:Bean默认为单例模式。 代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术; 模板方法:用来解决代码重复的问题。...
  • jdk中使用的设计模式

    2019-04-25 15:02:00
    JDK(Java Development Kit)类库中,开发人员使用了大量设计模式,正因为如此,我们可以在不修改JDK源码的前提下开发出自己的应用软件,研究JDK类库中的模式实例也不失为学习如何使用设计模式的一个好方式。...
  • 下面是JDK中有关23个经典设计模式的示例,在stakeoverflow也有相应的讨论: http://stackoverflow.com/questions/1673841/examples-of-gof-design-patterns Structural(结构模式) Adapter: 把一个接口或是类变成...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 53,989
精华内容 21,595
关键字:

工厂模式jdk实际