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

      概述

      工厂模式提供了创建对象的最佳模式,它使用统一的接口来指向新建的对象,屏蔽了创建对象的逻辑。

      工厂模式主要分为三种:(1)简单工厂 (2)工厂方法 (3)抽象工厂

      简单工厂

      简单工厂的实现比较简单,即工厂类中主要有个静态方法,用来接收传进来的参数,并根据参数的不同返回不同类的实例对象。

      假设有一个工厂,存放着牛奶,面包,手机等产品,首先为所有产品定义一个统一的接口。

    package com.jyk.factory.test;
     
    public interface Product {
        
    }

      接着让所有产品实现这个统一的接口,方便工厂类进行对象的创建。

      

    package com.jyk.factory.test;
    
    public class Milk implements Product {
    
        public void beDrink(){
            System.out.println("milk has been drinked");
        }
    }
    package com.jyk.factory.test;
    
    public class Bread implements Product {
    
        public void beEat(){
            System.out.println("bread has been eat");
        }
    }
    package com.jyk.factory.test;
    
    public class Mobile implements Product{
    
        public void beUsed(){
            System.out.println("mobile has been used");
        }
    }

      接着书写简单工厂的核心类,负责根据传入的产品名称进行对象的创建。

     

    package com.jyk.factory.test;
    
    public class SimpleFactory {
    
        public static Product getProduct(String productName) throws Exception{
            if(productName.equals("milk")){
                return new Milk();
            }else if(productName.equals("bread")){
                return new Bread();
            }else if(productName.equals("mobile")){
                return new Mobile();
            }else{
                throw new Exception("this type of product is not exist");
            }
        }
    }

      如此一来简单工厂的实现就完成了,该模式下存在一个致命的缺点,即违反了Java编码规范中的"开闭原则",当有其他产品的新增时,必须往SimpleFactory中不断的修改代码

    而且一旦SimpleFactory出现问题,所有对象的创建都会跟着歇菜。简单工厂模式还存在优化的空间。

      工厂方法

      为了降低风险,提高灵活性,使程序扩展性增强,需要对简单工厂进行重构,为此引入了工厂方法,旨在利用Java的多态提高工厂类的扩展性和耐风险性。

      定义工厂方法接口,接口只负责产品的存放,不再负责产品对象的创建,避免了工厂类出现问题导致的大面积瘫痪。

      

    package com.jyk.factory.test;
    
    public interface MethodFactory {
    
        public Product save();
    }

      再定义统一实现的产品的接口

      

    package com.jyk.factory.test;
    
    public interface Product {
        
    }

      所有具体的产品都必须实现该统一的接口

     

    package com.jyk.factory.test;
    
    public class Milk implements Product {
    
        public void beDrink(){
            System.out.println("milk has been drinked");
        }
    }
    package com.jyk.factory.test;
    
    public class Mobile implements Product{
    
        public void beUsed(){
            System.out.println("mobile has been used");
        }
    }
    package com.jyk.factory.test;
    
    public class Bread implements Product {
    
        public void beEat(){
            System.out.println("bread has been eat");
        }
    }

      接着编写实现工厂接口的,创建对象的具体实现。

      

    package com.jyk.factory.test;
    
    public class BreadSave implements MethodFactory{
    
        @Override
        public Product save() {
            return new Bread();
        }
    
    }
    package com.jyk.factory.test;
    
    public class MilkSave implements MethodFactory{
    
        @Override
        public Product save() {
            return new Milk();
        }
    
    }
    package com.jyk.factory.test;
    
    public class MobileSave implements MethodFactory{
    
        @Override
        public Product save() {
            return new Mobile();
        }
    
    }

      通过以上工厂方法的实现可看出,与简单工厂不同,工厂方法把不同产品对象的创建放在了实现工厂类接口的不同实现中,就算其中一个工厂类的实现出现问题,其他工厂仍旧可以正常的生产,每新增产品,也仅需新增一个工厂的实现类,无需修改代码,符合Java编码规范中的"开闭原则"

      抽象工厂

      如上介绍的方法工厂模式,当遭遇到复杂产品种类的场景时,将变得十分冗杂。如工厂中新增了很多新产品,如此一来,每个产品都需要有一个自己的创建对象的工厂实现类,当工厂中存在数量较多的产品时,方法工厂便出现了瓶颈。

      为此,我们引入了抽象工厂的实现,基于个人的理解认为,抽象工厂名字高大上有逼格,实则只是对方法工厂中的产品进行分类创建,看如下案例。

      比如工厂中存在着多种多样的产品,按产品的所属生产厂商进行分类。

    package com.jyk.factory.test;
    
    public interface huawei {
    
    }
    package com.jyk.factory.test;
    
    public interface alibaba {
    
    }
    package com.jyk.factory.test;
    
    public interface TypeFactory {
    
        public huawei huaweiCreate();
        
        public alibaba alibabaCreate();
    }

       接着对所属厂商的产品的价钱高低进行分类,如阿里巴巴和华为的低价产品,归类到一起。

    package com.jyk.factory.test;
    
    public class alibabaLowProduct implements alibaba {
    
    }
    package com.jyk.factory.test;
    
    public class huaweiLowProduct implements huawei {
    
    }

      如阿里巴巴和华为的高价产品,归类到一起。

    package com.jyk.factory.test;
    
    public class huaweiHighProduct implements huawei {
    
    }
    package com.jyk.factory.test;
    
    public class alibabaHighProduct implements alibaba {
    
    }

      接着将工厂隔离为两处,一处生产华为以及阿里巴巴的低价产品,一处生产华为以及阿里巴巴的高价产品。

    package com.jyk.factory.test;
    
    public class HighCreate implements TypeFactory{
    
        @Override
        public huawei huaweiCreate() {
            return new huaweiHighProduct();
        }
    
        @Override
        public alibaba alibabaCreate() {
            return new alibabaHighProduct();
        }
    }
    package com.jyk.factory.test;
    
    public class LowCreate implements TypeFactory {
    
        @Override
        public huawei huaweiCreate() {
            return new huaweiLowProduct();
        }
    
        @Override
        public alibaba alibabaCreate() {
            return new alibabaLowProduct();
        }
    
    }

      如此一来,我们有序的对商品进行了归类,以后每新增新的产品,根据所属厂商以及价格高低进行归类,并分配到不同的工厂去创建,通过分类,有效防止了类的无限增长,有效益的减少了代码维护的难度,在产品数量较多的场景下,更适合选用抽象工厂方法。

      

  • 相关阅读:
    Linux-netstat
    API接口防止参数篡改和重放攻击
    Java中遍历Map的几种方式
    Java泛型中的标记符含义
    Iterator 和 for...of 循环
    Promise 对象
    Reflect
    正则要求密码长度最少12位,包含至少1个特殊字符,2个数字,2个大写字母和一些小写字母。
    一个JS正则表达式,一个正实数,整数部分最多11位 小数部分最多 8位
    java阿里云短信发送配置
  • 原文地址:https://www.cnblogs.com/jiyukai/p/6691644.html
Copyright © 2011-2022 走看看