zoukankan      html  css  js  c++  java
  • 2018.4.4 设计模式之简单工厂模式与抽象工厂模式详解(一)

    1设计模式之简单工厂模式与抽象工厂模式详解

    简介

    设计模式时一套被反复使用的多数人知晓的、经过分类编目的、代码设计经验的总结。设计模式使代码设计真正工程化,模式是软件工程的基石。
    

    2.什么是GOF(四人帮 。 Gang of Four)

    Design Patterns-Elementes of ReusableObject -Oriented Software

    (中文译名:设计模式-可复用的面向软件元素)

    四位作者合成GOF,他们所提出的设计模式主要是基于鱼虾的面向对象设计原则
    
    对接口编程儿不是对实现编程;
    优先使用对象组合而不是继承
    

    3.设计模式的类型

    3大类+1另外的:
    	创建型模式:这些模式提供了一种在创建对象同时隐藏创建逻辑方式,而不是使用new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。
    	结构型模式:这些模式关注类与对象的组合。继承概念被用来组合接口和定义组合对象获得新功能的方式。
    	行为型模式:这些设计模式特别关注对象之间的通信。
    	J2EE模式:这些设计模式特别关注表示层。这些模式时由Sun Java Center鉴定的
    

    创建型模式

    工厂模式
    1.概念:在工厂模式中,我们在创建对象时不会对客户暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
    
    2.介绍:
    	意图:定义一个创建对象的接口,让其子类自己去实例化那一个工厂,工厂模式使其创建过程延迟到子类进行;
    	何时会用:明确计划不同条件下创建不同实例时;
    	如何解决:让其子类实现工厂接口,返回的事一个抽象产品。
    	主要解决:接口选择问题;
    	关键代码:创建过程在子类中执行;
    
    应用实例:
    	1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。 2、Hibernate 换数据库只需换方言和驱动就可以。
    
    
    实现:创建一个Shape接口实现Shape接口的实体类。下一步时定义工厂类ShapeFactory。FactoryPatternDemo,是使用 ShapeFactory来获取Shape对象,它将向ShapeFactory传递信息,以便获取他所需要的对象类型
    

    代码实现:

    package com.glut.demo2;
    
    /**
     * 图形的工厂 负责加工成型
     * 写一个方法,返回的类型是接口的对象类型,实际上返回的对象
     * 就是创建具体实现类的过程,材料确定了,就知道是什么类型具体的产品了。
     * 
     * @author qichunlin
     *
     */
    public class ShapeFactory {
    	public Shape getShape(String type) {
    		if(type.equals("Circle")) {
    			return new Circle();
    		}else if(type.equals("Rectangle")) {
    			return new Rectangle();
    		}else if(type.equals("Square")){
    			return new Square();
    		}else {
    			System.out.println("你的输入有误");
    			return null;
    		}
    	}
    }
    
    
    //
    package com.glut.demo2;
    
    /**
     * 定义一个接口,里面写一个方法
     * 
     * @author qichunlin
     *
     */
    public interface Shape {
    	public void draw();
    }
    
    
    //
    package com.glut.demo2;
    
    public class Circle implements Shape{
    
    	@Override
    	public void draw() {
    		System.out.println("I am Circle Draw Method!");
    	}
    }
    
    
    //
    package com.glut.demo2;
    
    /**
     * Square实现图形的接口
     * 实现类
     * @author qichunlin
     *
     */
    public class Square implements Shape{
    
    	@Override
    	public void draw() {
    		System.out.println("I am Square Draw Method!");
    	}
    
    }
    
    //
    package com.glut.demo2;
    
    public class Rectangle implements Shape{
    
    	@Override
    	public void draw() {
    		System.out.println("I am Rectangle Draw Method");
    	}
    
    }
    
    //
    package com.glut.demo2;
    
    /**
     * “工厂模式”的举例
     * 
     * 这个相当于平时写的测试类
     * 总结:在测试类中实例化的是工厂(ShapeFactory)而不是具体产品的
     * 		实现类(Circle 、Rectangle、Square有这些),然后在调用
     * 		工厂里面的具体方法传入参数,来获取“材料”,然后根据主类中输
     * 		入的“材料”来制造出产品,先获取产品的对象,在调用里面的具体方法。
     * 
     * @author qichunlin
     *
     */
    public class FactoryPatternDemo {
    	public static void main(String[] args) {
    		//实例化工厂
    		ShapeFactory shapeFactory = new ShapeFactory();
    		
    		//获取 Circle 的对象,并调用它的 draw 方法
    		Shape shape1 = shapeFactory.getShape("Circle");
    		shape1.draw();
    		
    		
    		//获取 Rectangle 的对象,并调用它的 draw 方法
    	     Shape shape2 = shapeFactory.getShape("Rectangle");
    	     shape2.draw();
    	     
    	   //获取 Square 的对象,并调用它的 draw 方法
    	     Shape shape3 = shapeFactory.getShape("Square");
    	   //调用 Square 的 draw 方法
    	     shape3.draw();
    
    		//验证当输入的材料为空时显示的结果
    	     Shape shape4 = shapeFactory.getShape("");
    	     
    	}
    }	
    
    
    例子总结:
       在工厂模式中,就是先定一个接口,然后然后产品去实现这个接口类;实现的过程中会重写接口里面的所有方法(也就是具体的内容);接着再定义一个接口工厂专门用来加工创建刚才的实现类产品的,写一个方法里面穿入一个参数也就是所所得额材料来决定创建的事是什么产品通过if-else结构来选择;最后在测试类中,实例化这个工厂类,然后通过点里面的方法(getShape)来获取实际的对象,接着在接手用接口对象的类型(Shape),接着在点里面实现的具体方法(draw)
    

    抽象工厂模式

    1.概念:围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂,这种类型的设计模式属于创建型模式
    
    2.介绍:
    	意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们的类
    	主要解决:接口选择问题
    	何时使用:系统的产品有多余一个的产品组,而系统只消费其中某一族的产品。
    	如何解决:在一个产品族里面,定义多个产品。
    	关键代码:在一个工厂里聚合多个同类产品
    	
    
    应用实例:
    	工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产品)、时尚装(成套,一系列具体产品),甚至对于一个家庭来说,可能有商务女装、商务男装、时尚女装、时尚男装,这些也都是成套的,即一系列具体产品。假设一种情况,在家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然要从这个衣柜中取出了。用 OO 的思想去理解,所有的衣柜(具体工厂)都是衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。
    
    
    
    实现:我们将创建的Shape和color接口实现这些接口的实体类。下一步是创建抽象工厂类ShapeFactory和colorFactory,这两个工厂类都是扩展了AbstractFactory。然后创建一个工厂创造器/生成器类FactoryProducer。
    
    下面的类中使用FactoryProducer来获取AbstractFactoryAbstractFactory 对象。它将向 AbstractFactory 传递形状信息 Shape(CIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。同时它还向 AbstractFactory 传递颜色信息 Color(RED / GREEN / BLUE),以便获取它所需对象的类型。
    

    代码实现:

    package com.glut.demo4;
    
    /**
     * 定义一个形状的接口,让子类或者叫产品去实现
     * @author qichunlin
     *
     */
    public interface Shape {
    	public void draw();//写方法
    }
    
    
    
    package com.glut.demo4;
    
    /**
     * 先通过抽象工厂来指定是哪一种类型的工厂(颜色、形状)
     * 获取到了某一种类型的工厂之后就输入
     * 原材料根据原材料来决定生产什么样的产品
     * 
     * 抽象工厂里面没有if-else 判断而是直接把工厂方法写进去  在子类中实现
     * 
     * @author qichunlin
     *
     */
    public class Test {
    	public static void main(String[] args) {
    		// 获取形状工厂或者叫类型工厂
    		AbstractFactory shapeFactory = FactoryProducer.getFactory("Shape");
    		// 获取形状为Circle的对象
    		Shape shape1 = shapeFactory.getShape("Circle");
    		shape1.draw();// 调用circle的draw方法
    
    		// 获取Rectangle的对象
    		Shape shape2 = shapeFactory.getShape("Rectangle");
    		shape2.draw();// 调用Rectangle对象
    
    		// 获取Square对象
    		Shape shape3 = shapeFactory.getShape("Square");
    		shape3.draw();
    
    		// 获取颜色工厂的对象
    		AbstractFactory colorFactory = FactoryProducer.getFactory("Color");
    		//获取Red对象
    		Color c1 = colorFactory.getColor("Red");
    		c1.fill();//调用red的方法
    
    		Color c2 = colorFactory.getColor("Green");
    		c2.fill();
    
    		Color c3 = colorFactory.getColor("Blue");
    		c3.fill();
    
    	}
    }
    
    //
    package com.glut.demo4;
    
    public class Red implements Color{
    
    	@Override
    	public void fill() {
    		System.out.println("This is a Red !");
    	}
    
    }
    
    
    
    package com.glut.demo4;
    
    public class Rectangle implements Shape{
    
    	@Override
    	public void draw() {
    		System.out.println("I am Rectangle Draw Method");
    	}
    
    }
    
    
    
    package com.glut.demo4;
    
    /**
     * Square实现图形的接口
     * 实现类
     * @author qichunlin
     *
     */
    public class Square implements Shape{
    
    	@Override
    	public void draw() {
    		System.out.println("I am Square Draw Method!");
    	}
    
    }
    
    
    package com.glut.demo4;
    
    /**
     * 图形的工厂 负责加工成型
     * 写一个方法,返回的类型是接口的对象类型,实际上返回的对象
     * 就是创建具体实现类的过程,材料确定了,就知道是什么类型具体的产品了。
     * 
     * 抽象工厂里面的方法就都要重写但不一定要全部具体实现
     * 比如:在图形工厂里面不一定要实现颜色的方法只需要实现该工厂里面自己的方法
     * @author qichunlin
     *
     */
    public class ShapeFactory extends AbstractFactory{
    
    	@Override
    	public Color getColor(String color) {
    		return null;
    	}
    
    	@Override
    	public Shape getShape(String shape) {
    		if(shape==null) {
    			return null;
    		}
    		
    		if(shape.equals("Circle")) {
    			return new Circle();
    		}else if(shape.equals("Rectangle")) {
    			return new Rectangle();
    		}else if(shape.equals("Square")){
    			return new Square();
    		}
    		return null;
    	}
    }
    
    
    
    
    package com.glut.demo4;
    
    /**
     * 专门制造颜色的工厂
     * 
     * 所以它没有具体实现图形的工厂 不是自己的方法直接返回空,不能删除必须要重写
     * 当父类中的方法为抽象方法时要全部必须重写,普通方法时可以重写也可以不重写
     * @author qichunlin
     *
     */
    public class ColorFactory extends AbstractFactory{
    
    	@Override
    	public Shape getShape(String shape) {
    		return null;
    	}
    
    	@Override
    	public Color getColor(String color) {
    		if(color==null) {
    			return null;
    		}
    		
    		if(color.equals("Red")) {
    			return new Red();
    		}else if(color.equals("Green")){
    			return new Green();
    		}else if(color.equals("Blue")) {
    			return new Blue();
    		}
    		return null;
    		
    	}
    }
    
    
    
    package com.glut.demo4;
    
    /**
     * 创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂
     * 
     * @author qichunlin
     *
     */
    public class FactoryProducer {
    	//注意:这里用的是静态方法不然不可以访问
    	//写一个方法  判断指定的是哪个类型的工厂,图形还是颜色?
    	public static AbstractFactory getFactory(String choice) {
    		if(choice.equalsIgnoreCase("Shape")) {
    			return new ShapeFactory();
    		}else if(choice.equalsIgnoreCase("Color")) {
    			return new ColorFactory();
    		}
    		return null;
    		
    	}
    }
    
    
  • 相关阅读:
    矩阵解压,网络流UESTC-1962天才钱vs学霸周2
    最小生成树唯一性判断-UESTC1959天才钱vs学霸周
    度及拓扑图的使用-UESTC1958学霸周选课
    CodeForces1000A-Light It Up
    CodeForces1000A- Codehorses T-shirts
    CoderForces999F-Cards and Joy
    CoderForces999E-Reachability from the Capital
    CoderForces999D-Equalize the Remainders
    CoderForces999C-Alphabetic Removals
    CoderForces999B- Reversing Encryption
  • 原文地址:https://www.cnblogs.com/qichunlin/p/8717411.html
Copyright © 2011-2022 走看看