zoukankan      html  css  js  c++  java
  • 简单工厂,工厂模式,反射工厂,抽象工厂

    在软件设计中,我们通常是追求封装,降低耦合。开放封闭原则是符合这一设计目标的。

    开放封闭原则主要体现在:

    1.对扩展开放 

    2.对修改封闭  

    我们通常使用OOP中的多态和继承来实现这个目的。

    场景:一个大富翁出行,他拥有很多交通工具,汽车,轮船,飞机。

    简单工厂:

    将交通工具抽象为一个接口或者抽象类,使实际的交通工具继承或实现它。创造一个简单工厂(我们通常称此工厂为“上帝类”,意味着任何事都需要它负责,它可能除了负责交通工具,还要负责选择着装,负责出行时间,所以这种模式破坏了开放封闭原则中的对扩展开放)

    代码如下:

    package SimpleFactory;
    
    public class Car implements Vehicle{
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            System.out.println("汽车在地上开");
        }
    
    }
    
    public class Plane implements Vehicle{
    
        public void run() {
            System.out.println("飞机在天上飞");
        }
    
    }
    
    
    public interface Vehicle {
    public  void run();
    }
    
    public  class VehicleFactory {
    public static Vehicle createVehicle(VehicleType t)
    {
        switch (t) {
        case Car:
            return new Car();
        case Plane:
            return new Plane();
        default:
            return null;
        }
    }
    }
    
    public enum VehicleType {
    Car,
    Plane
    }

    测试程序:

    using System;
    using ParkFactorys;
    namespace Test
    {
        class Program
        {
            static void Main(string[] args)
            {
                IFactory factory = new ParkFactoryA();
                IPark park=factory.CreatePark();
                park.GetParkInfo();
                ICar car = factory.CreateCar();
                car.Run();
                Console.ReadLine();
            }
        }
    }

    当我们有更多同一需求时,(这里指拥有更多交通工具),必须修改上帝类Vehicle.


    工厂模式

    对这种情况进行了改良,我们是否可以创建一个工厂接口,当我们需要添加更多的交通工具时,可以添加不同交通工具工厂来实现此接口?

    代码如下:

    package FactoryMethod;
    
    public class Car implements Vehicle{
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            System.out.println("汽车在地上开");
        }
    
    }
    
    public class Plane implements Vehicle{
    
        public void run() {
            System.out.println("飞机在天上飞");
        }
    
    }
    
    public class CarFactory implements IVehicleFactory{
    
        @Override
        public Vehicle CreateVehicle() {
            // TODO Auto-generated method stub
            return new Car();
        }
    
    }
    
    public class PlaneFactory implements IVehicleFactory{
    
        @Override
        public Vehicle CreateVehicle() {
            // TODO Auto-generated method stub
            return new Plane();
        }
    
    }
    
    
    public interface IVehicleFactory {
        Vehicle CreateVehicle();
    }
    
    
    public interface Vehicle {
    public void run();
    }

    测试程序如下:

    package FactoryMethod;
    
    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            IVehicleFactory iv=new CarFactory();
            Vehicle v=iv.CreateVehicle();
            v.run();
    }
    }

    反射工厂:

    反射工厂同样是针对简单工厂破坏开封原则的一种改进,使用Java的反射特性

    代码如下:(Car,Plane,Vehicle类同上,这里暂不列举)

    package ReflectionFactory;
    
    import java.lang.reflect.*;
    
    public class VehicleFactory {
    public static Vehicle CreateVehicle(String typeName) 
    {
        try {
            Class clazz=Class.forName(typeName);
            try {
                return(Vehicle)clazz.newInstance();
            } catch (InstantiationException e) {
                // TODO: handle exception
                throw new RuntimeException("实例化异常",e);
            }catch (IllegalAccessException e) {
                // TODO: handle exception
                throw new RuntimeException(e);
            }
        } catch (ClassNotFoundException e) {
            // TODO: handle exception
            throw new RuntimeException("这个实体类不存在",e);
        }
    }
    }

    测试程序:

    package ReflectionFactory;
    
    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Vehicle v=VehicleFactory.CreateVehicle("ReflectionFactory.Car");
            v.run();
        }
    
    }

    抽象工厂:

    场景:当这个富翁选完了交通工具,还要考虑目的地的时候,或者考虑使用什么手机,穿什么衣服的时候,换句话说,涉及多重产品时,我们必须将工厂模式进行扩展,将大富翁今天的单一工厂(选择汽车类)扩展为多重工厂(既能选择汽车,也能选择着装,手机)

    代码如下:

    package AbstractFactory;
    
    public interface Ball {
    public void play();
    }
    
    public class BasketBall implements Ball{
    
        @Override
        public void play() {
            // TODO Auto-generated method stub
            System.out.println("在篮球场上打篮球");
        }
    
    }
    
    package AbstractFactory;
    
    public class FootBall implements Ball{
    
        @Override
        public void play() {
            // TODO Auto-generated method stub
            System.out.println("在足球场上踢足球");
        }
    
    }
    
    public interface Vehicle {
    public  void run();
    }
    
    public class Car implements Vehicle{
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            System.out.println("汽车在地上开");
        }
    
    }
    
    public class Plane implements Vehicle{
    
        public void run() {
            System.out.println("飞机在天上飞");
        }
    
    }
    
    public interface IFactory {
      Vehicle createVehicle();
      Ball createBall();
    }
    
    public class DefaultFactory implements IFactory{
    
        @Override
        public Ball createBall() {
            // TODO Auto-generated method stub
            return new FootBall();
        }
    
        @Override
        public Vehicle createVehicle() {
            // TODO Auto-generated method stub
            return new Car();
        }
    
    }

    测试程序如下:

    package AbstractFactory;
    
    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            IFactory ivFactory=new DefaultFactory();
            Vehicle v=ivFactory.createVehicle();
            Ball b=ivFactory.createBall();
            v.run();
            b.play();
        }
    
    }

    当我们既定了富翁今天必须选择交通工具,衣着,目的地三个产品线之后,多重选择工厂IFactory就不用变化,符合开封原则,不过当你需要决定另外的事务时,就必须修改Ifactory类和默认选择类,重新新建一个产品线。


    个人认为没有完美匹配任何需求的设计模式,我们必须灵活运用抽象来降低耦合性和封装,尽量使程序的扩展性和封闭性更好。

    以上代码经测试无误。

  • 相关阅读:
    set 用法、小结
    AC 自动机优化
    HDU 2222 Keywords Search 【ac自动机】
    组合数学 隔板法
    BZOJ1303_中位数图_KEY
    初识Trie_对Trie的一些认识
    网络流Edmonds-Karp算法入门
    Codevs1332_上白泽慧音_KEY
    Fliptil_KEY
    2017Noip普及组游记
  • 原文地址:https://www.cnblogs.com/Maskisland/p/6047763.html
Copyright © 2011-2022 走看看