提到设计模式,很多人都觉得老生常谈,这是一个非常有趣的领域,设计模式并不是属于多么高深的一种算法,而是属于一种代码结构,而设计模式中创建型的设计模式——工厂模式,是非常常见的一种。以下分别写出工厂模式中简单工厂模式、工厂方法模式、抽象工厂模式。
简单工厂模式
概念:对于简单工厂模式而言,大致概念就是说将所有的需要创建的对象放置到一个工厂中进行创建,比如对于Car 车这个类别来说,在进行获取对象的时候,根据传入的参数进行对象的创建。
基本代码如下:首先需要一个接口,Car,所有的车的实体类需要实现这个接口。
车接口
public interface Car {
void name();
}
然后在这个接口下面有两个实现类,比如分别是宝马车和奔驰车
宝马车:
public class BMW implements Car{
@Override
public void name() {
System.out.println("宝马车!");
}
}
奔驰车
public class benchi implements Car{
@Override
public void name() {
System.out.println("奔驰车!");
}
}
生产车的工厂
在这个工厂里面有非常多的车可以生产,当我们需要买车的时候,我们可以直接从这个工厂中进行getCar,而不用关心车如何生产的。
public class CarFactory {
public static Car getCar(String name){
if(name.equals("宝马")){
return new BMW();
}
else if(name.equals("奔驰")){
return new benchi();
}
else return null;
}
}
客户端测试
public class Consumer {
public static void main(String[] args) {
Car car1 = CarFactory.getCar("奔驰");
Car car2 = CarFactory.getCar("宝马");
car1.name();
car2.name();
}
}
简单工厂模式总结:
对于一种实体类的父类而言,比如车有很多种车,鸟有很多种鸟,首先需要定义一个这个父类的接口,在这个接口中定义所有实现类必须有的行为和属性。然后写出对应的实现这个接口的实体类。在这个父类的工厂中,有一个get父类的方法,根据需要传入的参数,new 出不同的对象返回到用户中即可。
优点:代码量少、易于管理、理解简单。
缺点:想要增加新的产品,需要在原本代码上进行修改。
工厂方法模式
概念工厂方法模式就是解决简单工厂模式如果想要增加新的产品需要在原本代码上进行修改的缺点,同样都有Car接口、以及对应的实现类,但是我们现在获取对象的话不是从一个CarFactory中进行获取,而是从每个实体类的工厂中进行获取。比如宝马有宝马的工厂,宝马这个工厂只专注于生产宝马车,而奔驰这个工厂只专注于生产奔驰车。再想增加产品的话不用再原来的代码上进行修改。
代码如下:
同样有上述的Car benchi 、bmw。这里不再进行编写。
工厂的接口
public interface CarFactory {
Car getCar();
}
实现工厂接口的宝马工厂
public class BmwFactory implements CarFactory{
@Override
public Car getCar() {
return new BMW();
}
}
实现工厂接口的奔驰工厂
public class BenchiFactory implements CarFactory{
@Override
public Car getCar() {
return new benchi();
}
}
客户端测试
public class Consumer {
public static void main(String[] args) {
new BenchiFactory().getCar().name();
new BmwFactory().getCar().name();
}
}
**工厂方法模式总结:**相对于简单工厂模式的话,工厂方法模式的优化就在于我们对于每一种品牌都有自己单独的一个工厂进行 产品的生产,而不是所有的产品都在一个工厂中进行生产,这个也符合我们生活中的常识。最大的提升就是如果我们想在增加一个车,比如再想增加一个保时捷车的话,我们只需要在定义一个类实现Car这个接口,然后在定义一个保时捷的工厂即可,而不用修改原来的代码。
优点:每个产品都有属于自己的一个工厂,不用再获取产品的时候添加参数。增加产品的时候不用在原来的代码上进行修改。
缺点:代码量增加、不方便统一管理、理解稍微困难。
抽象工厂模式
概念: 抽象工厂模式的概念就相当于是在原来的基础上增加了一个抽象工厂,而这个抽象工厂定义了一些方法,比如说这个抽象工厂定义了一些方法,继承这个抽象工厂的则为对应的实体厂商。既可以认为是这个抽象工厂则为其它工厂的工厂。
手机接口:
public interface phoneProduct {
void start();
void shutdown();
void callUp();
void sendMs();
}
实现手机接口的实体类。比如小米手机
public class xiaomiPhone implements phoneProduct{
@Override
public void start() {
System.out.println("小米手机开机");
}
@Override
public void shutdown() {
System.out.println("小米手机关机");
}
@Override
public void callUp() {
System.out.println("小米手机打电话");
}
@Override
public void sendMs() {
System.out.println("小米手机发短信");
}
}
实现手机接口的另一个实体类,比如华为手机
public class huaweiPhone implements phoneProduct{
@Override
public void start() {
System.out.println("华为手机开机");
}
@Override
public void shutdown() {
System.out.println("华为手机关机");
}
@Override
public void callUp() {
System.out.println("华为手机打电话");
}
@Override
public void sendMs() {
System.out.println("华为手机发短信");
}
}
路由器接口
public interface routeProduct {
void start();
void shutdown();
void setting();
}
实现路由器接口的实现类,小米路由器。
public class xiaomiRoute implements routeProduct{
@Override
public void start() {
System.out.println("小米路由器开机");
}
@Override
public void shutdown() {
System.out.println("小米路由器关机");
}
@Override
public void setting() {
System.out.println("设置小米路由器密码");
}
}
实现路由器接口的另一个实体类,华为路由器。
public class huaweiRoute implements routeProduct{
@Override
public void start() {
System.out.println("华为路由器开机");
}
@Override
public void shutdown() {
System.out.println("华为路由器关机");
}
@Override
public void setting() {
System.out.println("设置华为路由器密码");
}
}
然后再定义一个工厂的接口。其余的对应厂商实现这个接口。
//抽象产品工厂。
public interface productFactory {
//生产手机
phoneProduct phoneproduct();
//生产路由器
routeProduct routeproduct();
}
定义小米生产的工厂
public class xiaomiFactory implements productFactory{
@Override
public phoneProduct phoneproduct() {
return new xiaomiPhone();
}
@Override
public routeProduct routeproduct() {
return new xiaomiRoute();
}
}
定义华为生产的工厂
public class huaweiFactory implements productFactory{
@Override
public phoneProduct phoneproduct() {
return new huaweiPhone();
} @Override
public routeProduct routeproduct() {
return new huaweiRoute();
}
}
从这里我们可以看到,每个不同的品牌现在都有自己的一个工厂,这个工厂里可以生产属于自己的那些产品。在这个工厂中,直接提供了获取这个产品的方法,不需要我们去关心这个产品如何生产。实现了模块化。
客户端测试代码:
public class Client {
public static void main(String[] args) {
xiaomiFactory xiaomiFactory = new xiaomiFactory();
phoneProduct phone = xiaomiFactory.phoneproduct();
routeProduct route = xiaomiFactory.routeproduct();
System.out.println("==========小米产品================");
phone.start();
phone.shutdown();
phone.callUp();
route.start();
route.shutdown();
route.setting();
System.out.println("==========小米产品================");
huaweiFactory huaweiFactory = new huaweiFactory();
phoneProduct phone1 = huaweiFactory.phoneproduct();
routeProduct route1 = huaweiFactory.routeproduct();
System.out.println("==========华为产品================");
phone1.start();
phone1.shutdown();
phone1.callUp();
route1.start();
route1.shutdown();
route1.setting();
System.out.println("==========华为产品================");
}
}
优点:生产产品的详细情况在应用层被隔离,无需关心创建的细节。
将一个系列的产品归并到一起进行创建。
缺点:如果想在一个品牌中增加一个产品的话需要在原来的基础上进行修改。理解在三个中是最困难的。借助编写代码能够加深理解。
总结
简单工厂模式:简单易于管理,如果增加产品但是需要在原来代码上进行修改。
工厂方法模式:可以在不修改当前代码的基础下,通过实现对应的产品类以及工厂类实现扩展。
抽象工厂模式:增加新的产品需要修改代码,增加新的品牌不用修改代码。