JAVA之工厂方法模式个人见解

//记录学习 

工厂模式一般分三种:

简单工厂模式

工厂方法模式

抽象工厂模式

这里主要介绍第二种了.

先讨论工厂模式有啥作用?

首先工厂模式是一种实例化对象的模式. 也就是说是用来 实例化对象的!

工厂模式实例化对象的优点主要在于: 带来更大的可扩展性,减少修改量.  关键在于 解耦

还是从下网上说,越往上,解耦越明显.

前面的说明代码参考了这里的博客  (作者 jason0539 ) 

后面附上自己见解与分析,这是关键和我的精华.

后面附上自己见解与分析,这是关键和我的精华.

对于简单工厂模式,

以博客中的宝马车(具体的产品为例子, 宝马又衍生出两个系列  经过简单工厂模式得代码如下)

//显然分两个模块, 产品类+工厂类, 产品有一个 抽象类 和实现接口的类, 就是说分了两个层次,但是工厂没有

产品类:

    abstract class BMW {  
        public BMW(){  
              
        }  
    }  
    public class BMW320 extends BMW {  
        public BMW320() {  
            System.out.println("制造-->BMW320");  
        }  
    }  
    public class BMW523 extends BMW{  
        public BMW523(){  
            System.out.println("制造-->BMW523");  
        }  
    }  
工厂类(管理生产产品):

    public class Customer {  
        public static void main(String[] args) {  
            Factory factory = new Factory();  
            BMW bmw320 = factory.createBMW(320);  
            BMW bmw523 = factory.createBMW(523);  
        }  
    }  


那么客户的使用就有:

    public class Customer {  
        public static void main(String[] args) {  
            Factory factory = new Factory();  
            BMW bmw320 = factory.createBMW(320);  
            BMW bmw523 = factory.createBMW(523);  
        }  
    }  


思考: 在这一层利用的我认为,有点像是用到了 JAVABEAN 的设计概念,还不至于说到有多解耦.

这里有封装的作用,比如客户需要一个 BMW320 的实例,那么利用的是 factory的 子类的一个createBMW函数,我完全不需要关心 BMW320的构造函数是如何的.这样

的好处在于,我以后想改变BMW320的构造函数时候,只需要修改,然后重新编译这一个构造函数就够了,不会影响其他地方,反正我的对外接口而言,就是通过工厂的这

样一个createBMW函数而已.

这里弱弱简单解释一下javabean概念: 假设某个类里有两个数据域 int A 和 int B 我类里所有的方法都是直接操作A和B的,有一天,我觉得A,B的值的算法量不够,

应该变成原本的两倍,咋办?我是去每个方法里把A变成2A吗?其实根本没这个必要. 我们只需要对存取数据的方式变成 getA() 和 setA() ,getB()和setB(),那么以后我

想对这些数据的量进行某些操作,直接在这个函数内搞定,所有外部的人调用也是通过这get,set函数进行的,就会方便很多. get set还有向后兼容性质.可以再去看看.

但我认为这里的javabean概念只是简单工厂模式的一个特性.其他还在于他起到一个封装作用.把具体产品的构建和new出这样一个对象分开了.这样我以后再新

增加产品的时候,增加的只不过是工厂管理的多一个项目而已.用户接触的是工厂,相当于往上再抽一层象,

用别人的话说,就是我买车我只需要去工厂提车,不管这车咋弄出来的.


工厂方法模式:

简单工厂模式如果新增宝马产品,则需要改动 Factory 类的源码

如果是工厂模式,则在工厂模式下,再多抽出一层象,

总的一个概念 Factory 作为一个接口,从而减轻了 Factory的负担

产品类:

    abstract class BMW {  
        public BMW(){  
              
        }  
    }  
    public class BMW320 extends BMW {  
        public BMW320() {  
            System.out.println("制造-->BMW320");  
        }  
    }  
    public class BMW523 extends BMW{  
        public BMW523(){  
            System.out.println("制造-->BMW523");  
        }  
    }  


创建工厂类:

    interface FactoryBMW {  
        BMW createBMW();  
    }  
      
    public class FactoryBMW320 implements FactoryBMW{  
      
        @Override  
        public BMW320 createBMW() {  
      
            return new BMW320();  
        }  
      
    }  
    public class FactoryBMW523 implements FactoryBMW {  
        @Override  
        public BMW523 createBMW() {  
      
            return new BMW523();  
        }  
    }  


客户类:

    public class Customer {  
        public static void main(String[] args) {  
            FactoryBMW320 factoryBMW320 = new FactoryBMW320();  
            BMW320 bmw320 = factoryBMW320.createBMW();  
      
            FactoryBMW523 factoryBMW523 = new FactoryBMW523();  
            BMW523 bmw523 = factoryBMW523.createBMW();  
        }  
    }  


显而易见,这个时候,不仅产品类分了两个层次, 工厂也分两个层次.这个抽象层次又高了一些.以后我们需要增加产品的时候,

只需要继承车类,得到新产品车类,再继承工厂类,得到新的工厂类. 这不需要改变其他源码,但是抽象等级还在.

缺点在于 一个工厂对应一个产品,当产品一多的时候,工作量会比较大. 

其实对于我这种学得浅,应用得不多的人而言,还是比较难理解这种好处的,尤其是上面这个工厂方法模式.我就会想问:你新建一个产品要新建一个产品+新建一个工厂,

而且我要得到一个对象的时候,得先得到一个"和产品对应"的工厂对象,之后再得到我的对象,哪里体现出了抽象的好处了?你直接new BMW320 和通过工厂弄,反正你函数名没变,你修改宝马320内部东西不也不影响用户吗?我增加产品直接新建一个车类再new不就得了??

看了资料仔细想想, 并不是这样的.并不是这样的.并不是这样的.假设有一个A包和B包,A要用B中的interfaceC衍生出来的某个类D,new D这个类,类的构造函数有一些基本的状态信息比如需要

new D(int a,int b,int c),其中a,b,c决定了,比如说汽车吧,a b c=3 2 0的时候表示是一部宝马320, 我现在需要一辆宝马320, 我如果直接去new,我还得去查类D的细节!这是多么烦的事情阿 ,真想有个人帮我把这些事儿都给办了. 这时候就有工厂了, 你想要得到一辆宝马320是吧? 

那么!!!!!!!

你只需要给我这两句话

            FactoryBMW320 factoryBMW320 = new FactoryBMW320();  
            BMW320 bmw320 = factoryBMW320.createBMW(); 
我的BMW320工厂会帮你把那些乱七八糟的参数阿 ,或者什么的都给办好!!  现在你理解到了这种区别了吧.

别人老师说什么工厂能隐藏细节,能起到模块化,抽象化,封装的作用. 光看上面我引用的这种博客还是会有很多疑惑的.

//抽象工厂模式我觉得那篇博文还可以..贼晚了.留个坑


下面是我利用工厂模式解决判断数字奇偶的程序...比价简单..我主要说一下结构..

数字判断者 Numjudger.java // 抽象类 理解为产品

--奇数判断者 OddNumJudger.java // 实现类

--偶数判断者 EvenNumJudger.java // 实现类


判断者工厂 AbstractFactory.java // 抽象类 理解为总工厂

--奇数判断者工厂 FactoryOddJudger.java // 实现类

--偶数判断者工厂 FactoryEvenJudger.java // 实现类


用户类+Main User.java // 负责使用的大佬


数字判断者

public abstract class NumJudger{
    public NumJudger(){
    }
}

奇数判断者

public class OddNumJudger extends NumJudger{
    public OddNumJudger(){
    }
    public void Judging(int num){
        if(num%2!=0){
            System.out.println("num is odd");
        }
    }
}
偶数判断者

public class EvenNumJudger extends NumJudger{
    public EvenNumJudger(){
    }
    public void Judging(int num){
        if(num%2==0){
            System.out.println("num is even");
        }
    }
}

总工厂抽象类

public class EvenNumJudger extends NumJudger{
    public EvenNumJudger(){
    }
    public void Judging(int num){
        if(num%2==0){
            System.out.println("num is even");
        }
    }
}
mistake@mistake-pc:~/Documents/myProject/Java_prac/AbstractFactory$ cat AbstractFactory.java 
interface FactoryJudge{
    JudgeNum createJudger();
}

奇数判断者工厂

public class FactoryOddJudger implements FactoryJudger{
    public OddNumJudger createJudger(){
        return new OddNumJudger();
    }
}

偶数判断者工厂

public class FactoryEvenJudger implements FactoryJudger{
    public EvenNumJudger createJudger(){
        return new EvenNumJudger();
    }
}

用户者大佬

import java.util.Scanner;
public class User{
    public static void main(String args[]){
        FactoryOddJudger foj=new FactoryOddJudger();
        OddNumJudger onj=foj.createJudger();

        FactoryEvenJudger fej=new FactoryEvenJudger();
        EvenNumJudger enj=fej.createJudger();

        int num;
        Scanner sc=new Scanner(System.in);
        num=sc.nextInt();
        while(num!=0){
            onj.Judging(num);
            enj.Judging(num);
            num=sc.nextInt();
        }
        onj.Judging(num);
        enj.Judging(num);
    }
}

运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值