使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式使代码编制真正工程化,是软件工程的基石脉络,如同大厦的结构一样。

文章结构:

1.单一职责原则(SRP);
2.里氏替换原则(LSP);
3.依赖倒置原则(DIP);
4.接口隔离原则(ISP);
5.迪米特原则(LoD);
6.开闭原则(OCP)。
7.以计算器设计为例子综合展示各大原则以及相关设计模式。


一、单一职责原则(Single Responsibility Principle,SRP原则):

定义:

应该有且仅有一个原因引起类的变更。也就是一个接口或类只负责一件事。

使用原因:

假设一个类负责两大职责,那么当业务变化,一个职责需要变化时就要修改这个类,所以就可能导致另一个职责会发生变化。

优点:

1.类的复杂度降低,实现什么职责都又清晰明确的定义;
2.可读性高,复杂性降低;
3.可维护性高,易维护;
4.变更引起的风险降低。(一个接口修改只对应的实现类有影响,对其他的接口无影响,对系统扩展性、维护性有多大帮助)。

例子:

//这样设计的话,有个后果可以看见:如果我要让帅哥类拥有一个跳舞的技能,那么我要修改哪里呢??修改People类?那就全崩了。所以我们应该把帅哥类拆分出来成为另一个类来继承People。
public class People{public void say(String name){System.out.println("我是"+name);}
}
//场景类
public class Client{public static void main(String []args){People people=new People();people.say("帅哥");people.say("美女");people.say("大叔");}
}

单一职责原则使用建议

接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化。

但是呢,类的设计也要结合实际,很多时候非单一职责的情况的,我们就要去妥协一下子:
1.只有逻辑足够简单,才可以在代码级别上违背SRP;
2.只有类中方法数量足够少,才可以在方法级别上违背SRP;
3.实际应用中的类都要复杂的多,一旦发生职责扩散而需要修改类时,除非这个类本身非常简单,否则还是要遵循SRP。


二、里氏变换原则(Liskov Substitution Principle,LSP原则):

定义:

所有引用基类的地方必须能透明地使用其子类对象。即:只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或寻常。(子类可完整实现父类的业务)。

设计原因:

有一功能P1,由类A完成。现需要将功能P1进行扩展,扩展后的功能为P,其中P由原有功能P1与新功能P2组成。新功能P由类A的子类B来完成,则子类B在完成新功能P2的同时,有可能会导致原有功能P1发生故障。

这个定义有四层含义:

### (一)、子类必须完全实现父类的方法:
也就是在类中调用其他类时务必要使用父类或接口,如果不能使用父类或接口,则说明违背LSP原则。(在编写类的实现时用父类对象,调用时传入其子类实现向上转型即可完成设计。是传入子类对象,在方法实现向上转型成父类)。

针对这一含义,实际的开发有些注意点:

1.业务增多时,类的设计思路:

(1)(不推荐)在moudle类中增加instanceof的判断(即每增加所有与这个类的父类有关系的类都要修改)。
(2)(推荐,维护人员经常干)新增类脱离继承,简历一个独立的父类,可与原来的那个父类建立关联委托关系。

2.具体应用场景类的设计关键:

子类是否能完整地实现父类的业务。(如果子类不能完整实现父类的方法,或者父类的某些方法在子类中已经发生变化,则应该简历断开父子继承关系,采用依赖、聚集、组合等关系。)

(二)子类可以有自己的个性:

也就是子类可以有自己的方法和属性。

注意:在调用那个类时,不要使用父类对象传递。因为向下转型是不安全的。

(三)覆盖或实现父类的方法时输入参数可以被放大。

相关概念:

(1)方法重载(Overload)子类拥有父类的所有属性和方法,方法名相同,但输入参数又不相同。要求方法的输入参数类或数量不相同,在LSP原则下,就是子类的输入参数宽于或等于父类的输入参数。
(2)方法覆写:父类和子类的同名方法的输入参数是相同的,而且两个方法的范围值为子类的小于父类的。

注意

1.子类中方法的前置条件(传递的参数)必须与父类中被覆写的方法的前置条件相同或者更宽松。

2.如果父类的输入参数类型宽于子类的输入参数类型,那么会出现父类存在的地方,子类就未必可存在。因为一旦把子类作为参数传入,调用者可能进入子类的方法。

(四)、覆写或实现父类的方法时输出结果可以被缩小:

含义:

父类的一方法的返回值是一个类型T,子类的相同方法(重载或覆写)的返回值为S,那么LSP原则要求S必须小于或等于T。也就是说S和T是同一类型或者S是T的子类。

LSP原则的目的:

增强程序的健壮性,使版本升级时,即使增加子类,原有的子类还可以继续运行。

实际项目做法:项目中,每个子类对应不同的业务含义,使用父类作为参数,传递不同的子类完成不同的业务逻辑。可是!!使用LSP原则的时候要尽量避免子类的“个性”,因为LSP原则只可以正着用不能反着用。

例子:

public class Father {public Collection doSomeing(HashMap map){System.out.println("父类被执行。。。");return map.values();  }
}
public class Son extends Father{public Collection doSomeing(Map map){System.out.println("到子类啦");return map.values();}
}
//场景类一。
public class Client{public static void invoker(){Father f=new Father();     //这里就是直接使用父类的对象HashMap map=new HashMap();f.doSomeing(map);}public static void main(String []args){invoker();}
}
//跟场景类一结果一样的场景二:
//分析:为啥会一样结果呢??因为我们设计子类的时候,输入的参数的范围相对于父类扩大了,子类就可以代替父类传递到父类的调用者中,子类的方法就不会被执行啦。但是呢,如果想让子类的方法被执行,就必须覆写父类的方法了。
public class Client{public static void invoker(){Son son=new Son();HashMap map=new HashMap();son.doSomeing(map);}public static void main(String []args){invoker();}
}

三、依赖倒置原则(Dependence Inversion Principle,DIP原则):

定义:简而言之,就是面向接口编程。

(1)模块间的依赖通过抽象发生,实现类之间不发生之间的依赖关系,其依赖关系是通过接口或抽象类产生的;
(2)接口或抽象类不依赖于实现类;
(3)实现类依赖接口或抽象类。

设计原因:

类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险。

DIP原则优点:

减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性。

相关概念:

java中一个变量有两种类型:表面类型和实际类型。表面类型是定义的时候赋予的类型,实际类型是对象的类型。

使用:

分析!!分析两个类是否有依赖关系,有则制定出两者之间的接口(或抽象类)即可独立开发。

依赖的三种写法 :

(一)、在类中通过构造函数声明依赖对象。(按照依赖注入的说法,叫做构造函数注入)。

public interface IDriver{public void drive();       //是司机就会开车.这是个司机接口
}
public class Driver implements IDriver{private ICar car;public Driver (ICar _car){    //构造函数注入依赖this.car=_car;}//司机主要职责就是开车public void drive(){this.car.run();  //对象事务一级级地传递,传递到车对象}
}

(二)在抽象中设置Setter方法声明依赖关系(依照依赖注入的说法,这叫Setter依赖注入)。

public interface IDriver{public interface IDriver{public void setCar(ICar car); //车辆型号public void drive();}public class Driver implements IDriver{private ICar car;public void setCar(ICar car){   //setter函数注入依赖this.car=car;  }public void driver(){this.car.run();}}
}

(三)接口声明依赖对象

//分析:在IDriver中,通过传入ICar接口实现**抽象之间**的依赖关系。Driver实现类也传入了ICar接口,而是什么类型Car就需要在高层声明了。
public interface ICar {//是汽车就会跑public void run();
}
public interface IDriver{//是司机就会开车public void drive(ICar car);   //在接口就注入依赖,注入的是接口之间的依赖
}
publi class Driver implements IDriver{//司机主要职责就是开车public void drive(ICar car){car.run();}
}

使用DIP原则的规则以及注意点

(一)、每个类尽量都又接口或抽象类,或者两者都具备。

(依赖倒置的基本要求,有了抽象才可能依赖倒置)

(二)变量的表面类型尽量是接口或者抽象类。

(但不是所有类型都要抽象,比如一个工具类一般不需接口或抽象类)

(三)任何类都不应该从具体类派生。

(比如:项目处于开发状态,不应从具体类派生出子类。但有维护的口占情况,这时则可以不考虑,但要求不超过两层继承)。

(四)尽量不要覆写基类的方法

(如果基类是一个抽象类,而且方法已经实现,子类应尽量不要覆写。类间依赖的是抽象,覆写抽象方法对依赖的稳定性有影响。)

(五)结合里氏替换原则使用

(原则:接口负责定义public属性和方法,并且声明与其他对象的的依赖关系,抽象类负责公共构造部分的实现,是实现类准确地实现业务逻辑,同时在适当的时候对父类进行细化)。

DIP原则是6个设计原则中最难实现的原则,是实现开闭原则的重要途径。


四、接口隔离原则(Interface Segregation Principle,ISP原则):

定义:

客户端不应该依赖它不需要的接口,类间的依赖关系应该建立在最小的接口上。(一句话:接口尽量细化,同时接口中的方法尽量少。)

相关定义:接口分类:

(一)实例接口。在Java中声明一个类,然后new产生一个实例,它是对一个类型的事物的描述(一个角度:Java中的类也是一种接口)。
(二)类接口。Java中经常使用的interface关键字定义的接口。

做法:

把大接口分解为几个小接口。(例子:美女的接口分解为外貌美女、气质型美女)

注意:

单一职责要求的是类和接口职责单一,注重的是职责!!!这属于业务逻辑的划分。

接口隔离原则是对接口进行规范约束:(四层含义)开发注意点

(1)接口要尽量小。

根据接口隔离原则拆分接口时,首先必须满足单一职责原则!

(2)接口要高内聚。

高内聚:提高接口、类、模块的处理能力,减少对外的交互。要求接口–尽量少公布public方法,接口是对外的承诺,承诺越少对系统的开发越有利。

(3)定制服务:

原因:模块之间必然会有耦合,有耦合就要有相互访问的接口(可能是Java中的interface,也可能为一个类或单纯数据交换)设计时需要为各个访问者(客户端)定制服务。

定义:就是单独为一个getItem提供优良的服务

要求做法:只提供访问者需要的方法。


项目开发时接口设计规则:

(一)一个接口只服务于一个子模块或业务逻辑
(二)通过业务逻辑压缩接口中的public方法,接口时常去回顾,尽量让接口达到“满身筋骨肉“,而不是肥嘟嘟的一堆方法。
(三)已经被污染了的接口,尽量去修改,若变更的风险较大,则采用适配器模式进行转化处理。
(四)了解环境,不要盲从。每个项目或产品都有特定的环境因素,别看到大师做接口就做接口。环境不同,接口拆分的标准不同,有一点点的妥协原则的。

例子:

//外貌型美女
public interface GoodBodyGirl{//美丽的外貌public void goodLooking{}//好身材public void niceFigure{}
}
//气质型美女
public interface GreatTemperametGirl{//气质public void greatTemperament();
}

(五)迪米特原则(Law Of Demeter,LOD原则):

定义:

一个对象应该只对其他对象有最少的了解。(也就是说你的类多复杂都不关我的事,我只关心你的public事物)

设计原因:

类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。

含义有四层:

(一)只和朋友交流:类与类的联系不要跨越。

(也就是我想叫我的朋友的朋友去干活,就必须通过我的朋友去告诉我的朋友的朋友)
类与类之间的关系是建立在类间的,而不是方法之间,因此一个方法尽量不引入一个类中不存在的对象。

(二)朋友之间也是有距离的:

一个雷公开的public属性或方法越多,修改时设计的面也就越大,变更引起的风险扩散也越大。

注意:尽量不公布太多public方法和非静态的public变量,多使用private–>类的高内聚。

技巧:一个类暴露过多方法,而发现这堆方法有关系时,可以设计一个public方法,把那堆方法统率在新的public方法,并设置为private。

(三)是自己的就是自己的:

方法设计原则:如果一个方法放在本类中,即不增加类间的关系,也对本类不产生负面影响,就可以放置在本类中。

(四)谨慎使用Serializable(序列化机制,具体看我另一篇博客输入输出机制)。

例子:一个项目使用RMI(远程方法调用)方式传递VO值对象,其实就是个网络请求过程,那么这个对象就必须实现Serializable接口。(也就是把需要网络传输的对象进行序列化,否则会出现Not Serializable Exception)。

核心观念:类间解耦,实现弱耦合。

可能导致的后果:然而其结果会产生大量中转类或跳转类,导致系统的复杂性提高,为维护带来难度。所以使用LOD原则时要反复权衡。跳转不超过两次。

例子:

//场景是:老师叫班长清点女生人数,班长就去清点了。
//分析:所以这个场景,根据LOD原则,老师是不能调用女生的类的。然后我们知道只能够让班长去调用女生。而老师去调用班长。
public class Teacher{public void commond(GroupLeader groupleader){groupleader.countGirls();}
}
public class Girl{}
public class GroupLeader{private List<Girl> listGirls;//传递全班的女生进来public GroupLeader(List<Girl> _listGirls){this.listGirls = _listGirls;}//清查女生数量public void countGirls(){System.out.println("女生数量是:"+this.listGirls.size());}
}

六、开闭原则:

定义:

一个软件实体应通过扩展来实现变化,而不是通过修改已有的代码来实现变化。

设计原因:

在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。

相关概念:

软件实体
(1)项目或软件产品中按照一定逻辑规则划分的模块。
(2)抽象和类。
(3)方法。

业务变化:(三种类型)

(1)逻辑变化。

只变化一个逻辑而不涉及其他模块,可通过修改原有类中的方法的方式来完成。但是有个前提条件:所有依赖或关联类都按照相同逻辑处理。

(2)子模块变化:

一个模块变化,必会对其他模块产生影响,特别是一个低层次的模块变化必然引起高层模块的变化。

(3)可见视图变化:

可见视图是提供给客户使用的界面,该部分的变化一般会引起连锁反应。因为多了一项显示数据,意味着你的其他部分代码也要增多一项这样的数据。

针对软件产品的需求业务变化:有三大扩展方案

(一)修改接口,增加方法:(否定)

后果:所有拥有该接口的实现类必须作修改,场景类也要修改。
否定这个方案的原因:接口应该是稳定且可靠的,不应经常发生变化,否则接口作为契约的作用就失去了。

(二)修改实现类:(不推荐)

做法:通过class文件替换的方式完成业务变化。
后果:修改了的信息可能会导致其他类获得的信息不对称。

(三)通过扩展实现变化:(推荐)

做法:增加子类,覆写方法,高层次的模块(static静态模块区)通过新增子类产生新的对象。
代码例子:

public interface Book{//书籍有名称public String getName();//书籍有售价public int getPrice();//书籍有作者public String getAuthor();
}
public class NovelBook implements Book{//书籍名称private String name;//书籍的价格private int price;//书籍的作者private String author;//通过构造函数传递书籍数据public NovelBook(String _name,int _price,String _author){this.name = _name;this.price = _price;this.author = author;}public String getAuthor(){return this.author;}public String getName(){return this.name;}public int getPrice(){return this.price;}
}
//然后到了阅读月啦,我们书店就要打折啦!!怎么办??正如我们刚刚提到的三种方案。
//分析:如果选择第一种方案,在接口里面新增方法,那么我们的小说类NovelBook也要修改,而且违背接口的稳定性原则。如果选择第二种方案,直接修改实现类,也就是修改NovelBook的类啦,是的,我们可以做一个打折的方法,然后完成打折的业务扩展,但是!!其他业务就有可能有影响,比如设计模式里面说的采购人员也看价格,而当这个方法实现了,采购人员只会看到打折后的价格。
//所以我们采用第三种方案。来完成业务扩展。
public class OffNovelBook extends NovelBook{public offNovelBook(String _name,int _price,String _author){super(_name,_price,_author);}@Overridepublic int getPrice(){//原价int selfPrice = super.getPrice();int offPrice = 0;if(selfPrice>4000){offPrice = selfPrice * 9/10;}else{offPrice = self * 8/10;}return offPrice;}
}

开闭原则是最基础的一个原则,也就是说前五个原则是指导设计的工具和方法,而开闭原则才是精神领袖。可以说,只要遵守前五大原则,设计出来的软件就会符合开闭原则。

思想核心:用抽象构建框架,用实现扩展细节。

联系其他原则:单一职责原则告诉我们实现类要职责单一;里氏替换原则告诉我们不要破坏继承体系;依赖倒置原则告诉我们要面向接口编程;接口隔离原则告诉我们在设计接口的时候要精简单一;迪米特法则告诉我们要降低耦合。而开闭原则是总纲,他告诉我们要对扩展开放,对修改关闭。


七、计算器(结合了六大设计原则与工厂模式)

//这个就是运算类的工厂模式。因为运算太多了,如果每个都在运算类里面再写个几行,那样会导致运算类的繁重累赘而且不清晰。以多态特性来设计。
public class OperationFactory{public static Operation createOperate(String operate){Operation oper = null;swich(operate){case "+":oper = new OperationAdd();break;case "-":oper = new OperationSub();break;case "*":oper = new OperationMul();break;case "/":oper = new OperationDiv();break;}return oper;}
}
//而这个运算类,把他给抽象处理就体现出 用抽象构建架构,用实现扩展细节了。
//分析:我们把运算类的核心抽取出来:两个数,一个结果,还需一个运算规则。这几个就是本质!而运算规则有很多种,我们需要交给子类去实现
//根据 单一职责原则--我们把每个运算规则的类分开成了单独的类。加减乘除均为一个类。
//根据 里氏替换原则--加减乘除的四个类均继承一个抽象出来的运算父类,获得一样的特性。两个数,一个结果。
//根据 依赖导致原则--面向接口编程,也就是面对抽象的结果编程。而我们抽象出的运算父类,拥有各个运算规则子类的共同特征。
//根据 接口隔离原则--呃,,这里只作出了一步抽象,没有多余的接口。
//根据 迪米特原则--松耦合。当然啦,都把加减乘除分离开来成一个类了,以后你想要修改加法,比如根据职位不同去加不同的薪水,这样更改,你只需改加法这个类。
//根据 开闭原则。核心--用抽象构建框架,用实现扩展细节。以上原则都实现了,这不就好了咩。
public abstract class Operation{private double numberA = 0;private double numberB = 0;private double result = 0;public void setNumberA(Double _numberA){this.numberA = _numberA;}public double getNumberA(){return numberA;}public void setNumberB(Double _numberB){this.numberB = _numberB;}public double getNumberB(){return numberB;}public abstract double getResult();
}
//加法类
class OperationAdd extends Operation {public double getResult(){result = numberA + numberB;return result;}
}
//减法类
class OperationSub extends Operation {public double getResult(){result = numberA - numberB;return result;}
}
//乘法类
class OperationMul extends Operation {public double getResult(){result = numberA - numberB;return result;}
}
//除法类
class OperationDiv extends Operation {public double getResult(){try{result = numberA / numberB;}catch(Exception e){System.out.println("除数不能为0");e.printStackTrace();}return result;}
}
//场景类代码:
Operation oper;oper = OperationFactory.createOperate(“+”);oper.setNumberA(1.0);oper.SetNumberB(2.0);double result = oper.GetResult();

好了,设计模式-六大设计原则(附加实际开发建议以及计算器例子)讲完了。本博客借鉴了一部分设计模式之禅,这是一本很好的书,只是我在这里总结以及写出自己的理解。欢迎在下面指出错误,共同学习!

转载请注明:【JackFrost的博客】
更多内容,可以访问JackFrost的博客

设计模式-六大设计原则(附加实际开发建议以及计算器例子)相关推荐

  1. 设计模式—六大设计原则

    本文开始对<设计模式之禅>进行学习总结,首先是六大设计原则. 单一职责原则 单一职责原则(Single Responsibility Principle)简称SRP,这个原则存在的争议之处 ...

  2. JAVA关于设计模式六大设计原则

    设计模式 前言 一.单一职责原则 1.定义 2. 问题由来 3.单一职责优点: 二.里式替换原则 1.定义: 2.含义: 3.优缺点: 4.注意事项 三.依赖倒置原则 1.定义 2.作用 3.实现方法 ...

  3. Java设计模式六大设计原则

    从今年的七月份开始学习设计模式到9月底,设计模式全部学完了,在学习期间,总共过了两篇:第一篇看完设计模式后,感觉只是脑子里面有印象但无法言语.于是决定在看一篇,到9月份第二篇设计模式总于看完了,这一篇 ...

  4. 设计模式六大设计原则 详细整理版

    一.单一职责原则 定义: 一个接口,类或者方法只有一个原因引起变化.即只有一个职责. 解读: 职能多样是一个诱惑,一个方法如果能根据入参(可变参数等)或其他判断条件实现不同或多种功能,看起来很强大而且 ...

  5. java设计模式-六大设计原则

     1. .单一职责            一个类只负责一项职责.      2. 里氏替换原则     子类可以扩展父类的功能,但不能改变父类原有的功能.它包含以下4层含义:     子类可以实现父类 ...

  6. 设计模式 - 六大设计原则之SRP(单一职责)

    文章目录 概述 Case Bad Impl Better Impl 1. 定义接口 2. 职责分离-多种实现类 3. 单元测试 小结 概述 单一职责原则(Single Responsibility P ...

  7. 设计模式 - 六大设计原则之OCP(开闭原则)

    文章目录 概述 Case 接口定义 接口实现 Bad Impl Better Impl 概述 Open-Close Principle 在面向对象编程领域中,开闭原则规定软件中的类.对象.模块和函数对 ...

  8. 设计模式 - 六大设计原则之LoD(迪米特法则原则)

    文章目录 概述 Case 学生类 老师类 Bad Impl Better Impl 老师类改造 调用方:校长类改造 概述 迪米特法(Law Of Demeter , LoD)则又叫最少知道原则(Lea ...

  9. 【设计模式】设计原则

    [设计模式]设计原则 在软件开发中,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,程序员要尽量根据6条原则来开发程序,从而提高软件开发效率.节约软件开发成本和维护成本. 1 开闭原 ...

最新文章

  1. 深入redis内部--字典实现
  2. DL:深度学习模型概览(包括DNN、CNN、RNN等)的简介、网络结构简介、使用场景对比之详细攻略
  3. 树状数组求逆序对_区间和的个数(树状数组)
  4. DTS开发记录(5)-- 挑战增量导出
  5. netmiko 记录日志_Pythonnetmiko模块的使用 | 学步园
  6. mac下virtualbox虚拟机centos联网问题
  7. css part 2
  8. turnserver开机启动配置
  9. HashMap底层原理面试题
  10. 交通规划软件功能分析
  11. python 删除pdf页面_使用PyPDF2库对pdf文件进行指定页面删除操作
  12. Oracle数据库管理维护
  13. 短信验证码通道相关误区
  14. 词霸天下---192 词根【-oxy- = -oxia- = -oxic- 尖锐,敏锐,氧 】
  15. 移动机器人传感器——GNSS
  16. 【H2】绘制三角警示牌,使用turtle绘制三角警示牌,陈斌老师北京大学暑期学校Python语言基础与应用
  17. 如何在VI中使用小键盘上的数字键
  18. 计算机桌面图标方向变了,Win7系统桌面图标变了怎么办?
  19. [Copy] Netlink Socket
  20. 全球及中国氮化铝(AlN)模板行业运行态势及投资战略分析报告2021-2028年

热门文章

  1. mysql事务处理银行转账模拟提交以及回滚
  2. Android开发之十四: camera(一):camera模组CMM介绍
  3. 2021年中国全国最新最全路网shp矢量数据含城市道路、高速、省道、县道、乡道+含各级道路网
  4. 记录一次补丁服务器异常处理的过程
  5. moment常用操作(获取当前年/季度/月/日、上一年/季度/月/日、下一年/季度/月/日、某年/月/季度的开始和结束时间)
  6. 宏观视角下的office漏洞(2010-2018)
  7. 简单快速地隐藏移动硬盘上的文件
  8. 中断及定时器实现时钟功能
  9. 加密与授权 Oauth2.0
  10. 对话快手 | 如何从0到1建立商业化品牌的海外影响力?