Java

Posted 张玉宝

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java相关的知识,希望对你有一定的参考价值。

引言:

 工厂设计模式分为三种:

  1. 简单工厂

  2. 工厂方法

  3. 抽象工厂

 联想四种情况

  (1)、还没有工厂时代:假如还没有工业革命,如果一个客户要一件产品,一般的做法是客户去创建一件产品,然后拿来用。

  (2)、简单工厂模式:后来出现工业革命。用户不用去创建产品。因为客户有一个工厂来帮他创建产品.想要什么产品,这个工厂就可以创建这种产品。比如想要一台洗衣机。工厂就创建这台洗衣机。即工厂可以创建产品。

  (3)、工厂方法模式时代:为了满足客户,要求的产品越来越多,如洗衣机、电视机等系列,一个工厂无法创建所有的产品。于是由单独分出来多个具体的工厂。每个具体工厂创建一种产品。即具体工厂类只能创建一个具体产品。但是工厂还是个抽象。你需要指定某个具体的工厂才能生产产品出来。

  (4)、抽象工厂模式时代:随着客户的要求越来越高,由于不同工厂的产品品质和功能不一样,客户希望生产好的电视机的厂商可以生产洗衣机。于是这个工厂开始生产电视机车和需要的洗衣机。

 假设有三种产品:洗衣机、电视机和空调。

一、简单工厂模式(Simple Factory)

建立一个工厂(一个函数或一个类方法)来制造新的对象。
分布说明引子:从无到有。客户自己创建宝马车,然后拿来用。但是客户需要知道怎么去创建一款车,客户和车就紧密耦合在一起了。为了降低耦合,就出现了工厂类,把创建产品的操作细节都放到了工厂里面去,客户直接使用工厂的创建工厂方法,传入想要的产品的类型就行了,而不必去知道创建的细节.这就是工业革命了:简单工厂模式

  首先创建一个共同的产品接口

1
2
package com.gqx.Factory;
public interface Product {}

  然后将洗衣机、电视机和空调去实现该接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.gqx.SimpleFactory;
public class TV implements Product {
    public TV(){
        System.out.println("电视机被生产了!");
    }
}
package com.gqx.SimpleFactory;
public class Wash implements Product {
    public Wash(){
        System.out.println("洗衣机被生产了!");
    }
}
package com.gqx.SimpleFactory;
public class Aircondition implements Product {
    public Aircondition(){
        System.out.println("空调被生产了");
    }
}

  产品被实现后,我们需要创建一个工厂,直接让用户在工厂中取走产品,而不是让用户来创建,从而降低用户和产品的耦合度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.gqx.SimpleFactory;
public class SimpleFactory {
    public static Product getProduct(String name){
        if (name.equals("wash")) {
            return new Wash();
        }else if (name.equals("TV")) {
            return new TV();
        }else if (name.equals("Aircondition")) {
            return new Aircondition();
        }else {
            return null;
        }
    }
}

  客户端

1
2
3
4
5
6
7
8
9
10
11
package com.gqx.SimpleFactory;
public class Client {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Product product =SimpleFactory.getProduct("wash");
        Product product2 =SimpleFactory.getProduct("TV");
        Product product3=SimpleFactory.getProduct("Aircondition");
    }
}

   简单工厂模式的核心就是SimpleFactory类,他拥有常见产品的权限,我们只需要把订单给它,他就可以生产出相应的产品。但这样也有很多局限,每当我们增加一个产品的时候,都必须修改其源代码,其次,我们有很多产品的时候,里面的if和else关系太过复杂和冗长。

 

二、工厂方式(Factory Method)

   工厂方法模式使用实现抽象工厂角色的多个接口来代替简单工厂模式中的“上帝类”。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活 起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有 的代码。可以看出工厂角色的结构也是符合开闭原则的!

首先创建产品接口

package com.gqx.Factory;
public interface Product {
}

创建相对应的产品

复制代码
package com.gqx.Factory;
public class TV implements Product {
    public TV(){
        System.out.println("电视机被生产了!");
    }
}

package com.gqx.Factory;
public class Wash implements Product {
    public Wash(){
        System.out.println("洗衣机被生产了!");
    }
}

package com.gqx.Factory;
public class Aircondition implements Product {
    public Aircondition(){
        System.out.println("空调被生产了");
    }
}
复制代码

创建工厂接口、分担简单工厂中‘上帝’的责任

package com.gqx.Factory;

public interface Factory {

}

创建相对应的工厂

复制代码
package com.gqx.Factory;
public class WashFactory implements Factory {
    public Product create(){
        return new Wash();
    }
}

package com.gqx.Factory;
public class TVFactory implements Factory {
    public Product createTV(){
        return new TV();
    }
}

package com.gqx.Factory;
public class AirconditionFactory implements Factory {
    public Product createAircondition(){
        return new Aircondition();
    }
}
复制代码

客户通过指定的工厂拿到指定的产品

复制代码
package com.gqx.Factory;

public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        TVFactory tvFactory=new TVFactory();
        tvFactory.createTV();
        
        AirconditionFactory airconditionFactory=new AirconditionFactory();
        airconditionFactory.createAircondition();
        
        WashFactory washFactory=new WashFactory();
        washFactory.create();
    }

}
复制代码

  工厂方法虽然解决了上面的问题,但是产品对象增多的时候,会出现大量与之对应的工厂类,这就让我们更加不易理清其中的逻辑了。

 

三、抽象工厂(Factory Method)

   随着客户的要求越来越高,由于不同工厂的产品品质和功能不一样,客户希望生产好的电视机的厂商可以生产洗衣机。于是这个工厂开始生产电视机车和需要的洗衣机。

首先,我们就需要先创建洗衣机和电视机的接口

复制代码
package com.gqx.AbstractFactory;
public interface Wash {
}

package com.gqx.AbstractFactory;
public interface TV {
}
复制代码

 

然后两个不同的厂商分别实现其接口

复制代码
package com.gqx.AbstractFactory;
//厂商一
public class TV1 implements TV {
    public TV1 (){
        System.out.println("TV1被生产了。哈哈");
    }
}
package com.gqx.AbstractFactory;
//厂商一
public class Wash1 implements Wash {
    public Wash1(){
        System.out.println("Wash1被生产了!");
    }
}

package com.gqx.AbstractFactory;
//厂商二
public class TV2 implements TV {
    public TV2(){
        System.out.println("TV2被生产了,哈哈哈");
    }
}
package com.gqx.AbstractFactory;
//厂商二
public class Wash2 implements Wash {
    public  Wash2(){
        System.out.println("wash2被生产了,哈哈哈");
    }
}
复制代码

现在开始创建工厂接口

复制代码
package com.gqx.AbstractFactory;

public interface Factory {
    public Wash createWash();
    public TV createTv();
}
复制代码

让两家工厂去实现该接口

复制代码
package com.gqx.AbstractFactory;
public class Factory1 implements Factory {
    @Override
    public Wash createWash() {
        // TODO Auto-generated method stub
        return new Wash1();
    }

    @Override
    public TV createTv() {
        // TODO Auto-generated method stub
        return new TV1();
    }
}



package com.gqx.AbstractFactory;
public class Factory2 implements Factory {
    @Override
    public Wash createWash() {
        // TODO Auto-generated method stub
        return new Wash2();
    }

    @Override
    public TV createTv() {
        // TODO Auto-generated method stub
        return new TV2();
    }
}
复制代码

最后,则是客户端

复制代码
package com.gqx.AbstractFactory;

public class Client {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Factory1 factory1=new Factory1();
        factory1.createTv();
        
        Factory1 factory11=new Factory1();
        factory11.createWash();    
    }
}
复制代码

 

  抽象工厂模式的起源或者最早的应用,是用于创建分属于不同操作系统的视窗构建。比如:命令按键(Button)与文字框(Text)都是视窗构建,在UNIX操作系统的视窗环境和Windows操作系统的视窗环境中,这两个构建有不同的本地实现,它们的细节有所不同。
在每一个操作系统中,都有一个视窗构建组成的构建家族。在这里就是Button和Text组成的产品族。而每一个视窗构件都构成自己的等级结构,由一个抽象角色给出抽象的功能描述,而由具体子类给出不同操作系统下的具体实现。

以上是关于Java的主要内容,如果未能解决你的问题,请参考以下文章

# Java 常用代码片段

# Java 常用代码片段

创建片段而不从 java 代码实例化它

如何重构这个 Java 代码片段

java 反射代码片段

java 代码片段