• 设计模式——工厂模式


    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();
        }
    }

  • 相关阅读:
    使用 PyCharm 远程调试 Django 项目
    (坑集)Python环境配置
    字典的使用
    列表的使用
    字符串的魔法
    php 文件函数
    php 时间函数
    php xajax库基本知识
    php header函数
    c++注释
  • 原文地址:https://www.cnblogs.com/xinmomoyan/p/11996590.html
Copyright © 2020-2023  润新知