经典设计模式是前辈们在实际应用中总结出来的经验,之所以被设定为标准并推广,肯定有其道理。其中很多开发人员只注重于业务的实现,开发中并不注重代码设计。
我见过开发3年左右的程序员,代码中全都是if else,在特定的场景下使用设计模式会使我们的代码更有利于维护和扩展,同时也不容易出错,在一定程度上也能更加理解面向对象的概念。
工厂模式在开发中是比较常用的设计模式,我们一般创建对象用 new 关键字,工厂模式就是替我们创建了对象。
像一些常见的工具类Calendar.getInstance() , LoggerFactory.getLogger(this.getClass()) 查看其源码都用到了工厂方法。
工厂模式分为简单工厂模式、工厂方法模式和抽象工厂模式,都属于创建型模式。
简单工厂模式
简单工厂模式(Simple Factory Pattern):是指由一个工厂对象决定创建出哪一种产品类的实例。
适用场景:
工厂类负责创建的对象较少。
客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心。
优点:
只需传入一个正确的参数,就可以获取你所需要的对象无须知道其创建的细节。
缺点 :
工厂类的职责相对过重,增加新的产品时需要修改工厂类的判断逻辑,违背开闭原则。
不易于扩展过于复杂的产品结构。
例:现在有几款电脑,联想、苹果、华硕等。
1、先定义一个电脑标准
public interface IComputer {
/**
* 价格
*/
void getPrice();
}
2、创建实现类,苹果电脑和联想电脑
public class IphoneComputer implements IComputer {
@Override
public void getPrice() {
System.out.println("苹果电脑");
}
}
public class LenovoComputer implements IComputer{
@Override
public void getPrice() {
System.out.println("联想电脑");
}
}
3、不用工厂实现
@org.junit.Test
public void test1(){
IComputer lenovoComputer = new LenovoComputer();
lenovoComputer.getPrice();
IComputer iphoneComputer = new IphoneComputer();
iphoneComputer.getPrice();
}
可见这种方式如果实现类越来越多,代码就会越来越臃肿。
但是如果我们可以把创建对象的细节隐藏起来,也就是交给工厂去实现,代码就会非常清爽了。
4、简单工厂模式实现,传入对应参数生成对象。
工厂类
public class SimpleComputerFactory {
public static IComputer createComputer(String type){
if ("Lenovo".equals(type)){
return new LenovoComputer();
}
if ("Iphone".equals(type)){
return new IphoneComputer();
}
return null;
}
}
看下类图
调用
//使用工厂
@org.junit.Test
public void test2(){
IComputer iComputer = SimpleComputerFactory.createComputer("Lenovo");
iComputer.getPrice();
}
这种工厂实现方式有个问题,就是产品越来越多的时候,需要频繁的修改工厂方法,不符合开闭原则,我们可以利用反射技术进行优化。
public static IComputer createComputer(Class<? extends IComputer> clazz){
try{
if (null!=clazz){
return clazz.newInstance();
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
看下类图
再次调用
//优化后的工厂
@org.junit.Test
public void test3(){
IComputer iComputer = SimpleComputerFactory.createComputer(IphoneComputer.class);
iComputer.getPrice();
}
工厂方法模式
在简单工厂中,随着产品链的丰富,如果每个产品创建的逻辑又有所不同,那么工厂的职责会变得越来越多,有点像万能工厂,不利于维护。
这种情况下,将职责拆分,专人干专事,也符合单一职责原则。分为联想工厂和苹果工厂。
工厂方法模式(Fatory Method Pattern)是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。主要解决产品扩展的问题。
使用场景:
创建类需要大量重复代码
1、定义抽象工厂
public interface IComputerFactory {
/**
* 生产电脑
* @return
*/
IComputer create();
}
2、实现联想工厂
public class LenovoComputerFactory implements IComputerFactory{
@Override
public IComputer create() {
return new LenovoComputer();
}
}
3、实现苹果工厂
public class IphoneComputerFactory implements IComputerFactory{
@Override
public IComputer create() {
return new IphoneComputer();
}
}
4、测试
//工厂方法
@org.junit.Test
public void test4(){
IComputerFactory lenovoComputerFactory = new LenovoComputerFactory();
lenovoComputerFactory.create().getPrice();
IComputerFactory iphoneComputerFactory = new IphoneComputerFactory();
iphoneComputerFactory.create().getPrice();
}
抽象工厂模式
抽象工厂模式(Abastract Factory Pattern)是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们具体的类。
客户端(应用层)不依赖于产品类实例如何被创建、实现等细节,强调的是一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。需要提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。
首先能称为组证明不是一个单独的个体。举网上一个例子来说明产品组的概念。美的电器和格力电器,我们都知道这两个品牌都不是只生产单一的产品。美的电器生产洗衣机、空调、电风扇,那么同样格力也生产洗衣机、空调、电风扇。这里洗衣机、空调、电风扇就可以成为一个产品组。
本篇中的例子,具体结构如下:
1、价格和质量接口
public interface IPrice {
/**
* 价格
*/
void getPrice();
}
public interface IQuality {
/**
* 质量
*/
void getQuality();
}
2、联想产品组
public class LenovoPrice implements IPrice{
@Override
public void getPrice() {
System.out.println("联想价格");
}
}
public class LenovoQuality implements IQuality{
@Override
public void getQuality() {
System.out.println("联想质量");
}
}
3、苹果产品组
public class IphonePrice implements IPrice{
@Override
public void getPrice() {
System.out.println("苹果价格");
}
}
public class IphoneQuality implements IQuality{
@Override
public void getQuality() {
System.out.println("苹果质量");
}
}
4、抽象工厂
public interface IComputerFactoryNew {
/**
* 价格
* @return com.zhkj.publicservice.utils.factorytest.IPrice
*/
IPrice createPrice();
/**
* 质量
* @return com.zhkj.publicservice.utils.factorytest.IQuality
*/
IQuality createQuality();
}
5、联想工厂实现
public class LenovoComputerFactoryNew implements IComputerFactoryNew {
@Override
public IPrice createPrice() {
return new LenovoPrice();
}
@Override
public IQuality createQuality() {
return new IphoneQuality();
}
}
6、苹果工厂实现
public class IphoneComputerFactoryNew implements IComputerFactoryNew{
@Override
public IPrice createPrice() {
return new IphonePrice();
}
@Override
public IQuality createQuality() {
return new IphoneQuality();
}
}
7、测试
//抽象工厂方法
@org.junit.Test
public void test5(){
IphoneComputerFactoryNew iphoneComputerFactoryNew = new IphoneComputerFactoryNew();
iphoneComputerFactoryNew.createPrice().getPrice();
iphoneComputerFactoryNew.createQuality().getQuality();
}