引言: 在我们开发过程中,前期可能为了赶进度,比较注重业务功能上的走通,没太留意代码的易读性,可维护性。因此呢,前人也是总结了23种设计模式,来帮助我们更优雅地进行代码重构、或者工具类编写、中间件设计等。笔者最近也是通过回顾和进一步深入学习,来总结常用的一些设计模式。有不足之处,欢迎留言共同讨论哦~。
1、工厂模式分类
《设计模式篇》第一篇,我们来聊聊工厂模式。
所谓工厂,就是用来生产东西的,那么对于java中的工厂模式,就是用来生产对象的。按对象和工厂的关系,我们可以分为三类模式:
简单工厂,所有对象都来源同一个工厂
工厂模式,每个对象都有自己的工厂
抽象工厂,每个对象需要在使用的时候才确认具体长啥样,可以产生一组相似对象。
下面我们通过代码来详细看看他们的区别和利弊。
2、优缺点分析
首先看下简单工厂 :
//简单工厂
public class SimpleFactory {
public Object create(String name){
if(name==null || name.replace(" ","").length()==0) return null;
if("nike".equals(name)){
return new Nike();
}else if("addidas".equals(name)){
return new Addidas();
}
return null;
}
/** 测试
* 依次打印 nike inited 、Addidas inited
* @param args
*/
public static void main(String[] args) {
SimpleFactory simpleFactory = new SimpleFactory();
Nike nike = (Nike)simpleFactory.create("nike");
nike.doSth();
Addidas addidas = (Addidas)simpleFactory.create("addidas");
addidas.doSth();
}
}
//待创建
class Nike{
void doSth(){
System.out.println("nike inited");
}
}
//待创建
class Addidas{
void doSth(){
System.out.println("Addidas inited");
}
}
简单工厂优缺点分析 :
很明显,简单工厂创建对象的方式就是根据一个字符串名字来创建的,我们需要什么对象就传进对应的字符串。这种方式也挺灵活适用很多场景,只需知道对象名称就能得到对应的对象; 但是这种工厂类写法有个前提,就是我们已经确定下来需要哪些对象, 那么一旦有新的变更,那就要修改工厂类,这样就不符合开闭原则(已封装好的东西尽量不修改)。那么当我们不知道到底需要多少对象,这时候咋办呢,工厂模式对此做了进一步深化:
来看下代码 :
//鞋类接口,定义鞋子
public interface IShoes {
//品牌
void logo();
//种类
void kind();
}
//Addidas 鞋子
class Addidas implements IShoes{
@Override
public void logo() {
System.out.println("logo - addidas");
}
@Override
public void kind() {
System.out.println("addidas - sport");
}
}
//Nike 鞋子
class Nike implements IShoes{
@Override
public void logo() {
System.out.println("logo - nike");
}
@Override
public void kind() {
System.out.println("nike - sport");
}
}
abstract class AbstractShoesFactory{
abstract IShoes create();
}
//Nike鞋子的独立工厂
class NikeFactory extends AbstractShoesFactory{
@Override
IShoes create() {
return new Nike();
}
}
// Addida 鞋子的独立工厂
class AddidasFactory extends AbstractShoesFactory{
@Override
IShoes create() {
return new Addidas();
}
}
//测试效果
class Test{
/** 依次输出:
* logo - nike
* nike - sport
* logo - addidas
* addidas - sport
*/
public static void main(String[] args) {
NikeFactory nikeFactory = new NikeFactory();
IShoes iShoes = nikeFactory.create();
iShoes.logo();
iShoes.kind();
AddidasFactory addidasFactory = new AddidasFactory();
IShoes iShoes1 = addidasFactory.create();
iShoes1.logo();
iShoes1.kind();
}
}
可以看出,工厂模式中,每个对象都有自己的工厂,当我们需要新的对象时,只需要新建一个对象的工厂就好。不需要修改主工厂类的代码,这样就更符合开闭原则。而且在设计比较复杂的逻辑时,每个对象有自己工厂类的划分,不用像简单工厂全部挤在一起,这样更方便维护。
但是也有个缺点,就是只能生产单一确定的对象,当我们想生产一组近似的对象,有时候只相差一个方法,如果这时候再特地创建工厂类,未免不太灵活,为此,我们有了抽象工厂模式:
//抽象工厂模式,可以生产一组对象
//制作鞋子Logo
interface ILogo {
void makeLogo();
}
//制作鞋子品类
interface IKind{
void makeKind();
}
//鞋子制作工厂
interface IShoesFactory{
ILogo madeLogo();
IKind madeKind();
}
//Addidas鞋Logo制作
class AddidasLogo implements ILogo{
@Override
public void makeLogo() {
System.out.println("制作阿迪达斯Logo");
}
}
//Addidas鞋类制作
class AddidasKind implements IKind{
@Override
public void makeKind() {
System.out.println("制作阿迪达斯运动鞋");
}
}
// Addidas鞋子制作工厂
class AddidasFactory implements IShoesFactory{
@Override
public ILogo madeLogo() {
return new AddidasLogo();
}
@Override
public IKind madeKind() {
return new AddidasKind();
}
}
//测试效果
class Test{
public static void main(String[] args) {
AddidasFactory addidasFactory = new AddidasFactory();
addidasFactory.madeLogo().makeLogo();
addidasFactory.madeKind().makeKind();
}
}
好了,以上就是工厂模式的三种简单介绍,最后再简单总结下使用上的选择:
3、使用选择
首先三种工厂模式使用的共有前提,就是需要大量创建使用某些对象的时候,为了提高代码的复用率和方便统一维护,我们可以使用该模式。
当我们已经确定下来需要哪些对象,优先使用简单工厂模式。
当我们不确定对象到底需要多少,则使用工厂模式。
当我们使用的对象,要在使用的时候才能确定到底长啥样,就使用抽象工厂。
以上就是个人在学习过程中对 工厂模式的总结,由于笔者能力有限,难免有疏漏的地方,有不足或者不太清楚的地方,欢迎留言讨论,共同进步-==