//记录学习
工厂模式一般分三种:
简单工厂模式
工厂方法模式
抽象工厂模式
这里主要介绍第二种了.
先讨论工厂模式有啥作用?
首先工厂模式是一种实例化对象的模式. 也就是说是用来 实例化对象的!
工厂模式实例化对象的优点主要在于: 带来更大的可扩展性,减少修改量. 关键在于 解耦
还是从下网上说,越往上,解耦越明显.
前面的说明代码参考了这里的博客 (作者 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);
}
}
运行结果: