zoukankan      html  css  js  c++  java
  • 设计模式——工厂模式

    1.静态工厂方法

    只给司机一辆车

    package com.bjsxt.dp.factory;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Car {
        private static Car car = new Car();// 单例
        private static List<Car> cars = new ArrayList<Car>();// 多例。连接池就是
    
        private Car() {
    
        }
    
        /**
         * 静态工厂方法,在一个方法里面控制了产生对象的逻辑,都可以把该方法称为工厂相关的方法,又因为该方法是静态的,所以叫静态工厂方法
         * 
         * @return
         */
        public static Car getInstance() {
    
            return car;
        }
    
        public void run() {
            System.out.println("冒着烟奔跑中car...");
        };
    }
    package com.bjsxt.dp.factory;
    
    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Car car = Car.getInstance();
            Car car2 = Car.getInstance();
            if(car==car2)
                System.out.println("same car");
            car.run();
    
        }
    
    }

    2.简单工厂模式

    1.目标:要控制任意定制交通工具的类型和生产过程

    目标有两层意思(1)任意类型 (2)生产模式,所以对应的,要这两个层面上抽象(Movable,VehicleFactory),利用接口,实现多态

    2.类结构

    1.Interface Movable.java

    2.Car.java

    3.Plane.java

    4.Interface VehicleFactory.java

    5.CarFactory.java

    6.PlaneFactory.java

    3.代码

    1.Movable.java

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

    2.Car.java

    package com.bjsxt.dp.factory;
    
    public class Car implements Moveable {
    
        @Override
        public void run() {
            System.out.println("冒着烟奔跑中car...");
        };
    }

    3.Plane.java

    package com.bjsxt.dp.factory;
    
    public class Plane implements Moveable {
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            System.out.println("扇着翅膀前进中...");
        }
    
    }

    4.VehicleFactory.java

    package com.bjsxt.dp.factory;
    
    public abstract class VehicleFactory {
        abstract Moveable create();
    }

    5.CarFactory.java

    package com.bjsxt.dp.factory;
    
    public class CarFactory extends VehicleFactory{
    
        @Override
        public Moveable create() {
            // TODO Auto-generated method stub
            return  new Car();
        }
    
    }

    6.PlaneFactory.java

    package com.bjsxt.dp.factory;
    
    public class PlaneFactory extends VehicleFactory {
    
        @Override
        Moveable create() {
            // TODO Auto-generated method stub
            return new Plane();
        }
    
    }

    7.Test.java

    package com.bjsxt.dp.factory;
    
    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            VehicleFactory factory = new CarFactory();
            Moveable m = factory.create();
            m.run();
        }
    }

     

    这样系统就可以产生扩展,既可以扩展交通工具,又可以控制生产过程。

    public class Broom implements Moveable {
        @Override
        public void run() {
            System.out.println("一路沙尘暴飞奔而来broom...");
        }
    }
    public class BroomFactory extends VehicleFactory {
        @Override
        Moveable create() {
            return new Broom();
        }
    }
    public class Test {
    
        public static void main(String[] args) {
            VehicleFactory factory = new BroomFactory();
            Moveable m = factory.create();
            m.run();
        }
    
    }

    3.抽象工厂模式

    系列产品(车、武器、食物) 

    首先,我们新建了一个Car类,一个AK47类,还有一个Apple类。

    package com.bjsxt.dp.abstractFactory;
    
    
    public class Car {
        public void run() {
            System.out.println("冒着烟奔跑中car...");
        }
    }
    package com.bjsxt.dp.abstractFactory;
    
    public class AK47 {
        public void shoot(){
            System.out.println("哒哒哒...");
        }
    }
    package com.bjsxt.dp.abstractFactory;
    
    public class Apple {
        public void printName() {
            System.out.println("apple");
        }
    }

    然后我们新建一个用户测试类,他有一辆车,一把AK47,一个苹果。

    package com.bjsxt.dp.abstractFactory;
    
    
    public class Test {
    
        public static void main(String[] args) {
            Car car = new Car();
            car.run();
            AK47 ak47 = new AK47();
            ak47.shoot();
            Apple apple = new Apple();
            apple.printName();
        }
    
    }

    这里的车,AK47,苹果都是分别new出来的,如果我们想要一次性的定制这些东西就需要用到抽象工厂模式。

    首先,我们想到要新建一个工厂,取名为DefaultFactory.

    package com.bjsxt.dp.abstractFactory;
    
    public class DefaultFactory {
    
        public Car createCar(){
            return new Car();
        }
    
        public AK47 createAK47(){
            return new AK47();
        }
    
        public Apple createApple(){
            return new Apple();
        }
    }

    这样的话我们的用户测试类就可以改成这样:

    package com.bjsxt.dp.abstractFactory;
    
    
    public class Test {
    
        public static void main(String[] args) {
            DefaultFactory factory = new DefaultFactory();
            Car car = factory.createCar();
            car.run();
            AK47 ak47 = factory.createAK47();
            ak47.shoot();
            Apple apple = factory.createApple();
            apple.printName();
        }
    }

    如果我想把上面的一系列产品都替换掉,只要来一个新的工厂就可以了,如 MagicFactory:

    package com.bjsxt.dp.abstractFactory;
    
    public class MagicFactory {
        public Broom createBroom(){
            return new Broom();
        }
    
        public MagicStick createMagicStrick(){
            return new MagicStick();
        }
    
        public MushRoom createMushRoom(){
            return new MushRoom();
        }
    }

    那么现在问题来了,如果我想把测试类中的DefaultFactory换成MagicFactory,那么下面的这些方法也要全部都改,太麻烦了,不想改下面的这些方法怎么办呢?

    解决方法,产生一个工厂的父类,abstractFactory

    package com.bjsxt.dp.abstractFactory;
    
    public abstract class AbstractFactory {
        public abstract Vehicle createVehicle();
        public abstract Weapon createWeapon();
        public abstract Food createFood();
    }
    package com.bjsxt.dp.abstractFactory;
    
    public abstract  class Vehicle {
        public abstract void  run();
    }
    package com.bjsxt.dp.abstractFactory;
    
    public abstract class Weapon {
       public abstract void shoot();
    }
    package com.bjsxt.dp.abstractFactory;
    
    public abstract class Food {
        public abstract void printName();
    }

    有了上面的这些抽象类,就可以继承上面的这些类。

    package com.bjsxt.dp.abstractFactory;
    
    public class DefaultFactory extends AbstractFactory{
    
    
        @Override
        public Vehicle createVehicle() {
            return new Car();
        }
    
        @Override
        public Weapon createWeapon() {
            return new AK47();
        }
    
        @Override
        public Food createFood() {
            return new Apple();
        }
    }
    package com.bjsxt.dp.abstractFactory;
    
    public class MagicFactory extends AbstractFactory {
        @Override
        public Vehicle createVehicle() {
            return new Broom();
        }
    
        @Override
        public Weapon createWeapon() {
            return new MagicStick();
        }
    
        @Override
        public Food createFood() {
            return new MushRoom();
        }
    }
    package com.bjsxt.dp.abstractFactory;
    
    public class AK47 extends Weapon{
        public void shoot(){
            System.out.println("哒哒哒...");
        }
    }
    package com.bjsxt.dp.abstractFactory;
    
    public class Apple extends Food{
        public void printName() {
            System.out.println("apple");
        }
    }
    package com.bjsxt.dp.abstractFactory;
    
    
    public class Car extends Vehicle {
        @Override
        public void run() {
            System.out.println("冒着烟奔跑中car...");
        }
    }
    package com.bjsxt.dp.abstractFactory;
    
    
    public class Broom extends Vehicle {
        @Override
        public void run() {
            System.out.println("一路沙尘暴飞奔而来broom...");
        }
    }
    package com.bjsxt.dp.abstractFactory;
    
    public class MushRoom extends Food{
        @Override
        public void printName() {
            System.out.println("mushroom...");
        }
    }
    package com.bjsxt.dp.abstractFactory;
    
    public class MagicStick extends Weapon {
        @Override
        public void shoot() {
            System.out.println("fire hu hu");
        }
    }

    test类

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

    整个体系结构如下图:

    如游戏里面的换皮肤功能,如果换个皮肤,界面上的很多功能及按钮都变了。

    总结:抽象工厂是生产了一系列产品,如果想换掉这一系列产品的时候,或者是想在这一些列产品的功能上进行扩展,想产生新的系列产品以及想对这一系列产品的生产过程进行控制,用抽象工厂。 

    简单工厂的问题在于产生产品系列的时候会造成工厂泛滥,而抽象工厂的问题在于在产生新的产品品种的时候,改动的地方会很多。

    4.Spring中的工厂

    现在又一个moveable接口,有两个实现类。

    package com.bjsxt.dp.springfactory;
    
    public interface Moveable {
        void run();
    }
    package com.bjsxt.dp.springfactory;
    
    
    public class Car implements Moveable {
        public void run() {
            System.out.println("冒着烟奔跑中car...");
        }
    }
    public class Train implements Moveable {
        @Override
        public void run() {
            System.out.println("小火车呜呜呜");
        }
    }

    此时,可以在测试类中,new car()或者new train().

    public class Test {
        public static void main(String[] args) throws Exception {
    
    //        Moveable m = new Train();
            Moveable m = new Car();
            m.run();
        }
    }

    现在的问题是能不能不要new,因为new源代码还是要更改,能不能改到配置文件里。

    1.利用properties文件配置

    VehicleType=factory.Train
    package factory;
    
    import factory.Car;
    import factory.Moveable;
    
    import java.util.Properties;
    
    public class Test {
        public static void main(String[] args) throws Exception {
            Properties pros = new Properties();
            pros.load(Test.class.getClassLoader().getResourceAsStream("spring.properties"));
            String vehicleTypeName = pros.getProperty("VehicleType");
            System.out.println(vehicleTypeName);
            Object o = Class.forName(vehicleTypeName).newInstance();
            Moveable m = (Moveable)o;
            m.run();
        }
    }

    此时,要是想改成car,则只要改配置文件就可以了。VehicleType=factory.Car

    2.spring中的Bean工厂

    1.先导入spring的jar包及spring框架需要的logging jar包

     

     

    2.spring中的配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
      <bean id="v" class="com.bjsxt.dp.springfactory.Car">
      </bean>
      <!-- 相当于 //v=com.bjsxt.spring.factory.factory.Car  -->
    
    </beans>

    3.测试类

    package com.bjsxt.dp.springfactory;
    
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Test {
        public static void main(String[] args) {
            BeanFactory f = new ClassPathXmlApplicationContext("applicationContext.xml");
            Object o = f.getBean("v");
            Moveable m = (Moveable) o;
            m.run();
        }
    }

  • 相关阅读:
    Palindrome Linked List 解答
    Word Break II 解答
    Array vs Linked List
    Reverse Linked List II 解答
    Calculate Number Of Islands And Lakes 解答
    Sqrt(x) 解答
    Find Median from Data Stream 解答
    Majority Element II 解答
    Binary Search Tree DFS Template
    188. Best Time to Buy and Sell Stock IV
  • 原文地址:https://www.cnblogs.com/xinmomoyan/p/11996590.html
Copyright © 2011-2022 走看看