zoukankan      html  css  js  c++  java
  • 简单工厂,工厂方法,抽象工厂,三种工厂模式

    简单工厂

    简单工厂是真的简单,如果我们有N个类需要被工厂管理,那我们给N个类分配一个唯一标识,调用工厂方法需要传递标识,工厂根据传入的标识创建对象。这种做法的缺点很明显,扩展性太差!严重违反开闭原则。如果要是又新增M个类需要被工厂管理,那么还要去改工厂类代码。

    package simplefactory_k;/*
    * @auther 顶风少年 
    * @mail dfsn19970313@foxmail.com
    * @date 2020-01-15 10:45
    * @notify 
    * @version 1.0
    */
    public class Airplane {
    
    }
    View Code
    package simplefactory_k;/*
    * @auther 顶风少年 
    * @mail dfsn19970313@foxmail.com
    * @date 2020-01-15 10:46
    * @notify 
    * @version 1.0
    */
    public class Rocket {
    }
    View Code
    package simplefactory_k;/*
    * @auther 顶风少年 
    * @mail dfsn19970313@foxmail.com
    * @date 2020-01-15 10:46
    * @notify 
    * @version 1.0
    */
    public class Screw {
    }
    View Code
    package simplefactory_k;
    /*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2020-01-15 10:46
     * @notify
     * @version 1.0
     */
    
    public class SimpleFactoryK {
        public static Object getObject(String obj) {
            if (obj.equals("飞机")) {
                return new Airplane();
            } else if (obj.equals("火箭")) {
                return new Rocket();
            } else if (obj.equals("螺丝")) {
                return new Screw();
            } else {
                return null;
            }
        }
    }
    View Code
    package simplefactory_k;
    /*
    * @auther 顶风少年 
    * @mail dfsn19970313@foxmail.com
    * @date 2020-01-15 10:53
    * @notify 
    * @version 1.0
    */
    public class Main {
        public static void main(String[] args) {
            Object airplane = SimpleFactoryK.getObject("飞机");
            System.out.println(airplane instanceof Airplane);
    
            Object rocket = SimpleFactoryK.getObject("火箭");
            System.out.println(rocket instanceof Rocket);
    
            Object screw = SimpleFactoryK.getObject("螺丝");
            System.out.println(screw instanceof Screw);
        }
    }
    View Code

    工厂方法

    工厂方法弥补了简单工厂不易于扩展的缺点,给一个产品族定义一个接口,产品族下边定义具体的产品实现。(产品族的纵向的,接口和实现类,或者抽象类和子类)创建产品族工厂接口,不同的产品工厂创建不同的产品。苹果和香蕉都是都是水果族,苹果工厂生产苹果,香蕉工厂生产香蕉,而他们属于水果工厂。当我们需要增加另外一种水果,例如橘子,需要我们创建一个橘子类,和一个橘子类的工厂,这听起来好像又麻烦了许多。但是我们假设,创建一个类需要很多的参数,整体的创建需要写很多的代码。那创建一个工厂类是完全有必要的。

    package factorymethod_k;/*
    * @auther 顶风少年 
    * @mail dfsn19970313@foxmail.com
    * @date 2020-01-15 14:22
    * @notify 
    * @version 1.0
    */
    public interface Fruiter {
        void product();
    }
    View Code
    package factorymethod_k;/*
    * @auther 顶风少年 
    * @mail dfsn19970313@foxmail.com
    * @date 2020-01-15 14:24
    * @notify 
    * @version 1.0
    */
    public class Apple implements Fruiter {
        @Override
        public void product() {
            System.out.println("种出苹果");
        }
    }
    View Code
    package factorymethod_k;/*
    * @auther 顶风少年 
    * @mail dfsn19970313@foxmail.com
    * @date 2020-01-15 14:24
    * @notify 
    * @version 1.0
    */
    public class Banana implements Fruiter {
        @Override
        public void product() {
            System.out.println("种出香蕉");
        }
    }
    View Code
    package factorymethod_k;/*
    * @auther 顶风少年 
    * @mail dfsn19970313@foxmail.com
    * @date 2020-01-15 14:25
    * @notify 
    * @version 1.0
    */
    public interface Farm {
        Fruiter getBean();
    }
    View Code
    package factorymethod_k;/*
    * @auther 顶风少年 
    * @mail dfsn19970313@foxmail.com
    * @date 2020-01-15 14:26
    * @notify 
    * @version 1.0
    */
    
    import factoryMethod.Fruit;
    
    public class AppleFarm  implements Farm{
        @Override
        public Fruiter getBean() {
            return new Apple();
        }
    }
    View Code
    package factorymethod_k;/*
    * @auther 顶风少年 
    * @mail dfsn19970313@foxmail.com
    * @date 2020-01-15 14:26
    * @notify 
    * @version 1.0
    */
    public class BananaFarm implements Farm{
        @Override
        public Fruiter getBean() {
            return new Banana();
        }
    }
    View Code
    package factorymethod_k;/*
    * @auther 顶风少年 
    * @mail dfsn19970313@foxmail.com
    * @date 2020-01-15 14:29
    * @notify 
    * @version 1.0
    */
    
    
    public class Client {
        public static void main(String[] args) {
    
            Farm farm = new AppleFarm();
            Fruiter fruiter = farm.getBean();
    
            Farm farm2 = new BananaFarm();
            Fruiter fruiter2 = farm2.getBean();
    
            System.out.println(fruiter instanceof Apple);
            System.out.println(fruiter2 instanceof Banana);
        }
    }
    View Code

    抽象工厂

    工厂方法对于单一产品族是够用了,但是如果是多产品族就不行了。思考一个场景,有一个水果族,和一个蔬菜族。水果和蔬菜都分热带种植环境,和常温种植环境。如果使用工厂方法,我们要怎么做呢?创建一个水果族接口,创建一个水果族工厂接口,创建一个蔬菜族的接口,一个蔬菜族工厂接口。但这显然是不符合实际逻辑的,热带水果和常温水果肯定不能在一个工厂被创建出来。热带蔬菜和常温蔬菜也是。于是我们需要横向抽取。热带水果,常温水果都是水果,热带蔬菜,常温蔬菜都是蔬菜。我们在园丁接口做抽取,有管理常温农作物的园丁和管理热带农作物的园丁。现在一个农场就可以创建两个族群的产品了。

    package abstractFactory;
    /*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2019-07-24 10:55
     * @notify 蔬菜接口
     * @version 1.0
     */
    
    public interface Veggie {
    }
    View Code
    package abstractFactory;
    /*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2019-07-24 10:58
     * @notify 热带的蔬菜
     * @version 1.0
     */
    
    import com.sun.org.apache.regexp.internal.RE;
    
    public class TropicalVeggie implements Veggie {
        private String name;
    
        public TropicalVeggie(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    View Code
    package abstractFactory;
    /*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2019-07-24 10:56
     * @notify 北方的蔬菜
     * @version 1.0
     */
    
    public class NorthernVeggie implements Veggie {
        private String name;
    
        public NorthernVeggie(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    View Code
    package abstractFactory;
    /*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2019-07-24 11:00
     * @notify 水果接口
     * @version 1.0
     */
    
    public interface Fruit {
    }
    View Code
    package abstractFactory;
    /*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2019-07-24 11:00
     * @notify 北方的水果
     * @version 1.0
     */
    
    public class NorthernFruit implements Fruit {
        private String name;
    
        public NorthernFruit(String name) {
            this.name = name;
        }
    
        public String getName(){
            return name;
        }
    
        public void setName(String name){
            this.name = name;
        }
    
    }
    View Code
    package abstractFactory;
    /*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2019-07-24 11:02
     * @notify 热带的水果
     * @version 1.0
     */
    
    public class TropicalFruit implements Fruit {
        private String name;
    
        public TropicalFruit(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    View Code
    package abstractFactory;
    /*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2019-07-24 10:50
     * @notify 园丁抽象类
     * @version 1.0
     */
    
    public interface Gardener {
    }
    View Code
    package abstractFactory;/*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2019-07-24 10:50
     * @notify 管理北方农场的园丁
     * @version 1.0
     */
    
    public class NorthernGardener implements Gardener {
    
        //    北方的水果
        public Fruit createFruit(String name) {
            return new NorthernFruit(name);
        }
    
        //北方的蔬菜
        public Veggie createVeggie(String name) {
            return new NorthernVeggie(name);
        }
    }
    View Code
    package abstractFactory;
    /*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2019-07-24 10:53
     * @notify 管理热带农场的园丁
     * @version 1.0
     */
    
    
    public class TropicalGardener implements Gardener{
    
        //热带水果
        public Fruit createFruit(String name){
            return new TropicalFruit(name);
        }
    
        //热带蔬菜
        public Veggie createVeggie(String name){
            return new TropicalVeggie(name);
        }
    }
    View Code
    package abstractFactory;/*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2019-07-24 12:28
     * @notify
     * @version 1.0
     */
    
    import junit.framework.TestCase;
    
    public class AbstractFactoryTest extends TestCase {
        public void testCreate(){
            TropicalGardener tropicalGardener = new TropicalGardener();
            Fruit fruit1 = tropicalGardener.createFruit("热带水果");
            Veggie veggie1 = tropicalGardener.createVeggie("热带蔬菜");
            assertTrue(fruit1 instanceof TropicalFruit);
            assertTrue(veggie1 instanceof  TropicalVeggie);
    
            NorthernGardener northernGardener = new NorthernGardener();
            Fruit fruit2 = northernGardener.createFruit("北方水果");
            Veggie veggie2 = northernGardener.createVeggie("北方蔬菜");
            assertTrue(fruit2 instanceof NorthernFruit);
            assertTrue(veggie2 instanceof  NorthernVeggie);
    
        }
    }
    View Code
  • 相关阅读:
    vim lua对齐indent无效
    C中的私有成员
    Lua 设置table为只读属性
    c语言结构体可以直接赋值
    Lua5.3 注册表 _G _ENV
    火狐浏览器调试ajax异步页面时报错NS_ERROR_UNEXPECTER
    ajax向后台请求数据,后台接收到数据并进行了处理,但前台就是调用error方法
    maven安装之后,或者升级之后遇到的问题:could not find or load main class org.codehaus.plexus.class.....
    jenkins执行shell命令,有时会提示“Command not found”
    shell 脚本替换文件中某个字符串
  • 原文地址:https://www.cnblogs.com/zumengjie/p/12195598.html
Copyright © 2011-2022 走看看