zoukankan      html  css  js  c++  java
  • java设计模式-工厂系列

    一、简单工厂      

    1.背景:

    任意定制交通工具的类型和生产过程

    代码:

    Moveable.java 

    package com.cy.dp.factory;
    
    public interface Moveable {
        void run();
    }

    Car.java:

    package com.cy.dp.factory;
    
    public class Car implements Moveable{
        
        @Override
        public void run(){
            System.out.println("car running...");
        }
        
    }
    View Code

    Plane:

    package com.cy.dp.factory;
    
    public class Plane implements Moveable{
    
        @Override
        public void run() {
            System.out.println("plane running...");
        }
    
    }
    View Code

    VehicleFactory.java:

    package com.cy.dp.factory;
    
    /**
     * 交通工具工厂
     * @author CY
     *
     */
    public abstract class VehicleFactory {
        abstract Moveable create();
    }

    CarFactory:

    package com.cy.dp.factory;
    
    public class CarFactory extends VehicleFactory{
    
        @Override
        Moveable create() {
            return new Car();
        }
    }
    View Code

    PlaneFactory:

    package com.cy.dp.factory;
    
    public class PlaneFactory extends VehicleFactory{
    
        @Override
        Moveable create() {
            return new Plane();
        }
    }
    View Code

    Test测试类:

    package com.cy.dp.factory;
    
    public class Test {
        public static void main(String[] args) {
            VehicleFactory factory = new CarFactory();
            Moveable m = factory.create();
            m.run();
        }
    }
    View Code
    question:
    要不要把工厂VehicleFactory设计成接口?
    答:可以,接口和抽象类其实是一回事;什么时候用抽象类,什么时候用接口?基本上可以采用这样的方式:如果说这个概念在我们脑中确确实实存在的,那你就用抽象类;如果说这个概念仅仅是某些方面的一个特性,比如说会飞的,能跑的,像这一类的东西,我们就把它设计成接口;如果是比较模糊的概念,不知道设计成抽象类还是接口时,那么设计成接口,原因是我们实现了这个接口之后,还可以从其他的抽象类来继承,更灵活。
     

    二、抽象工厂          

    控制一系列产品(车、武器、食品...)的替换,举个例子,家里搞装修,现在海尔卖那种整体厨房,油烟机、地板、热水器、微波炉...等等,你能不能够做到我要把一系列产品替换掉的话,它就全替换掉了。这件事情该怎么做呢?
     
    代码:
    Vechile:
    package com.cy.dp.factory;
    
    //交通工具
    public abstract class Vehicle {
        abstract void run();
    }
    View Code

    Weapon:

    package com.cy.dp.factory;
    
    //武器
    public abstract class Weapon {
        abstract void shoot();
    }
    View Code

    Food:

    package com.cy.dp.factory;
    
    //食物
    public abstract class Food {
        abstract void printName();
    }
    View Code

    Car: 

    package com.cy.dp.factory;
    
    public class Car extends Vehicle{
        
        public void run(){
            System.out.println("car running...");
        }
        
    }
    View Code

    AK47:

    package com.cy.dp.factory;
    
    public class AK47 extends Weapon{
        public void shoot(){
            System.out.println("shooting...");
        }
    }
    View Code

    Apple:

    package com.cy.dp.factory;
    
    public class Apple extends Food{
        public void printName(){
            System.out.println("apple");
        }
    }
    View Code

    AbstractFactory:

    package com.cy.dp.factory;
    
    public abstract class AbstractFactory {
        abstract Vehicle createVehicle();
        abstract Weapon createWeapon();
        abstract Food createFood();
    }

    DefaultFactory:(默认工厂,生产汽车、AK47、苹果)

    package com.cy.dp.factory;
    
    public class DefaultFactory extends AbstractFactory{
    
        @Override
        Vehicle createVehicle() {
            return new Car();
        }
    
        @Override
        Weapon createWeapon() {
            return new AK47();
        }
    
        @Override
        Food createFood() {
            return new Apple();
        }
    }

    Test:

    package com.cy.dp.factory;
    
    public class Test {
        public static void main(String[] args) {
            AbstractFactory f = new DefaultFactory();
            Vehicle v = f.createVehicle();
            v.run();
            Weapon w = f.createWeapon();
            w.shoot();
            Food a = f.createFood();
            a.printName();
            
        }
    }
    View Code

    抽奖工厂好处:

     
    好处:如果自己对这一系列东西不满意了,添加自己的系列产品,交通工具从Vehicle继承,武器从Weapon继承... 然后再产生自己的工厂,不用再修改自己的代码,只需要改AbstractFactory f = new DefaultFactory()这一个地方;如果写在配置文件里,甚至源代码再也不用变了;只改配置文件就ok;
    抽象工厂:是它生产了一系列产品,如果你想换掉一系列产品的时候,或者在这一系列产品基础之上进行扩展,想产生新的系列产品以及想对这一系列产品的生产过程进行控制,用抽象工厂。
     
     
    比较上面两种简单工厂和抽象工厂:
     
    问:抽象工厂和普通的工厂比较,有哪些好的和不好的?
    对于普通的工厂来说,可以在产品这个维度进行扩展,可以扩展产品,扩展生产产品的工厂;如果在普通工厂里面产生产品系列,就会很麻烦,比如扩展apple,就要多一个appleFactory,最后就发现工厂泛滥;所以普通的工厂方法来说最后会产生工厂泛滥这种问题;
    但是对于抽象工厂来说,也有短处,不能扩展新的产品品种,比如上面有Food、Vehicle、Weapon,想要加一个盔甲,那么AbstractFactory就要加一个create盔甲的抽象方法,所有继承AbstractFactory的类也要加实现,就太麻烦了;
     
     
    三、spring的bean工厂  
    模拟spring的bean工厂:
     
    代码:
    BeanFactory:
    package com.bjsxt.spring.factory;
    
    public interface BeanFactory {
        Object getBean(String id);
    }

    ClassPathXmlApplicationContext:

    package com.bjsxt.spring.factory;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import org.jdom.Document;
    import org.jdom.Element;
    import org.jdom.input.SAXBuilder;
    import org.jdom.xpath.XPath;
    
    public class ClassPathXmlApplicationContext implements BeanFactory  {
        private Map<String, Object> container = new HashMap<String, Object>();
        
        public ClassPathXmlApplicationContext(String fileName) throws Exception{
            SAXBuilder sb = new SAXBuilder();
              Document doc = sb.build(this.getClass().getClassLoader()
                      .getResourceAsStream(fileName));
              Element root = doc.getRootElement();
              List list = XPath.selectNodes(root, "/beans/bean");
              System.out.println(list.size());
              
              for (int i = 0; i < list.size(); i++) { 
               Element bean = (Element) list.get(i);
               String id = bean.getAttributeValue("id");
               String clazz = bean.getAttributeValue("class");
               Object o = Class.forName(clazz).newInstance();
               container.put(id, o);
               System.out.println(id + " " + clazz);
              }
    
        }
        
        @Override
        public Object getBean(String id) {
            
            return container.get(id);
        }
    
    }

    applicationContext.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans>
    
      <bean id="v" class="com.bjsxt.spring.factory.Train">
      </bean>
      
      <!--  //v=com.bjsxt.spring.factory.Car  -->
    
    
    </beans>

    Car:

    package com.bjsxt.spring.factory;
    
    
    public class Car implements Moveable{
        
        
        
        public void run() {
            System.out.println("car running.......");
        }
    }
    View Code

    Test测试类:

    package com.bjsxt.spring.factory;
    
    import java.io.IOException;
    import java.util.Properties;
    
    public class Test {
    
        /**
         * @param args
         * @throws IOException 
         */
        public static void main(String[] args) throws Exception {
            BeanFactory f = new ClassPathXmlApplicationContext("com/bjsxt/spring/factory/applicationContext.xml");
            Object o = f.getBean("v");
            Moveable m = (Moveable)o;
            m.run();
        }
    
    }
     
     
     
     
     
  • 相关阅读:
    硬件IC汇总
    stm8s103调试注意点
    感悟短句
    USB接口
    液晶屏驱动注意
    四数之和
    所有奇数长度子数组的和
    秋叶收藏集
    删除中间节点
    组合总和
  • 原文地址:https://www.cnblogs.com/tenWood/p/9169324.html
Copyright © 2011-2022 走看看