说明一下设计模式:设计模式有适用的时候也有不适用的时候.并且不少存在过度设计的问题,这同时也是设计模式本人的意思.
1.最重要的一点:不要有大段重复代码,如果有就封装起来调用,这样需要改的时候改一个地方就行.
2.逻辑清晰:一个类的功能单一,这样那个功能需要变动,只需要改一个类
3.类和类之间,用接口关联.说白了,在我们实际编码的时候,要做到,除了一开始得到一个类,其余的时候都是接口,这样自己改代码的时候,只要保证初始的类和接口不变,就不会影响到其他人了.
如果文雅的来说,就是几个法则了,必须说明一点,其中开闭法则必须改为:尽量只修改一处,不修改明显是不可能的,而且意义不大,往往会增加能多的代码量,更多的系统复杂度.
再来说说工厂模式解决的问题(常见误区:工厂方法用于批量生产对象):
1.让别人用自己代码的时候好用;让自己修改的时候好改
2.类的创建复杂(参数多,过程复杂)
3.类的选择复杂(类似的类太多)
a.jar其中有 a interface 这个接口
a interface 有 xxx()方法 有 a1 -- a5 这5这具体实现的类
这个时候,我们有用到xxx()方法的时候,就要很小心的根据自己的情况来new 这几个class了,而且a.jar的开发人员要升级或者修改的时候也要保证这5个class的意义和构造方法不变,这样双方都很被动.
而如果用到了工厂方法,a.jar的开发者很高兴, 直接对外屏蔽了 a1--a5这5个类,改从工厂类里得到.
这个时候再使用a.jar的时候情况就不一样了
使用者 需要使用 xxx() 方法的时候,只需要按照 工厂类的指引创建对应的对象,而a.jar开发者更新修改代码的时候,只需要保证 工厂类的 方法意义不变,接口不变就行了 里面随便折腾, 把 a1-a5,改成a6-a10 都行.
这是一种是非常契合面向对象编程的设计模式,如果没有弄明白工厂模式的作用,那么很可能是,大多数时候,你即是类的创建者,也是类的使用者,换个角度思考就清楚了.
工厂分为简单工厂,工厂方法(普通工厂)和抽象工厂,但其实都是工厂,都是为了实现上面的目标而开发的.其中普通工厂和抽象工厂分别是一种设计模式,简单工厂不在设计模式之列.
简单工厂:
一个工厂类,一个产品接口,多个不同的产品.
评价:简单工厂很好的解决了上面三个问题,简单好用,修改并不复杂.缺点:要特别说明传什么值.所以适合自己写自己用,不太适合给别人用.
工厂方法:
工厂接口:与产品接口一一对应;
具体工厂:一个具体工厂对应一个具体产品;
产品接口:
具体产品:
抽象工厂:
抽象工厂与普通工厂的区别在于:普通工厂面向具体产品,抽象工厂面向具体的系列.代码上的差别在于,抽象工厂接口存在多个方法,多个产品接口融合在一个工厂(普通工厂一个工厂接口对应一个)
一个工厂接口或抽象类:多个产品接口返回
多个具体的工厂类实现:
多个产品接口:
多个产品实现:
关闭Apple窗口
打开windows窗口
关闭windows窗口
评价:为用户分开了错综复杂的产品类,避免用错,减少了类的创建.同样将选择抛给用户,但选择的余地减少了(普通工厂)有多少个产品就有多少个工厂,而这个是有多少个系列就有多少个工厂),逻辑清晰.编码的时候有明显分成系列的时候,建议使用,比如:用不同的数据库实现dao层...
结论:
工厂模式便于他人使用代码,便于修改代码.不是为了批量生成对象,根据自己的业务选取合适的工厂.
在说工厂模式前,首先说明下设计模式是为了解决什么问题:
简单的来说就是:
在出了问题的时候,有什么新需求的时候,更新换代的时候...好改代码.
要怎么做到好改代码呢?
通俗的来讲:1.最重要的一点:不要有大段重复代码,如果有就封装起来调用,这样需要改的时候改一个地方就行.
2.逻辑清晰:一个类的功能单一,这样那个功能需要变动,只需要改一个类
3.类和类之间,用接口关联.说白了,在我们实际编码的时候,要做到,除了一开始得到一个类,其余的时候都是接口,这样自己改代码的时候,只要保证初始的类和接口不变,就不会影响到其他人了.
如果文雅的来说,就是几个法则了,必须说明一点,其中开闭法则必须改为:尽量只修改一处,不修改明显是不可能的,而且意义不大,往往会增加能多的代码量,更多的系统复杂度.
再来说说工厂模式解决的问题(常见误区:工厂方法用于批量生产对象):
1.让别人用自己代码的时候好用;让自己修改的时候好改
2.类的创建复杂(参数多,过程复杂)
3.类的选择复杂(类似的类太多)
先设想一个情况:
假设我们要用到 a.jar 这个包a.jar其中有 a interface 这个接口
a interface 有 xxx()方法 有 a1 -- a5 这5这具体实现的类
这个时候,我们有用到xxx()方法的时候,就要很小心的根据自己的情况来new 这几个class了,而且a.jar的开发人员要升级或者修改的时候也要保证这5个class的意义和构造方法不变,这样双方都很被动.
而如果用到了工厂方法,a.jar的开发者很高兴, 直接对外屏蔽了 a1--a5这5个类,改从工厂类里得到.
这个时候再使用a.jar的时候情况就不一样了
使用者 需要使用 xxx() 方法的时候,只需要按照 工厂类的指引创建对应的对象,而a.jar开发者更新修改代码的时候,只需要保证 工厂类的 方法意义不变,接口不变就行了 里面随便折腾, 把 a1-a5,改成a6-a10 都行.
这是一种是非常契合面向对象编程的设计模式,如果没有弄明白工厂模式的作用,那么很可能是,大多数时候,你即是类的创建者,也是类的使用者,换个角度思考就清楚了.
工厂分为简单工厂,工厂方法(普通工厂)和抽象工厂,但其实都是工厂,都是为了实现上面的目标而开发的.其中普通工厂和抽象工厂分别是一种设计模式,简单工厂不在设计模式之列.
简单工厂:
一个工厂类,一个产品接口,多个不同的产品.
public static class SimpleFactory {
public static Product getProduct(String type) {
switch (type) {
case "A":
return new ProductA();
case "B":
return new ProductB();
case "C":
return new ProductC();
}
return null;
}
}
interface Product{
void method();
}
class ProductA implements Product{
@Override
public void method() {
System.out.println("ProductA");
}
}
class ProductB implements Product{
@Override
public void method() {
System.out.println("ProductB");
}
}
class ProductC implements Product{
@Override
public void method() {
System.out.println("ProductC");
}
}这样在需要获取ABC的时候,传入对应的值就行,而且直接造型为接口:
Product a=SimpleFactory.getProduct("A")
评价:简单工厂很好的解决了上面三个问题,简单好用,修改并不复杂.缺点:要特别说明传什么值.所以适合自己写自己用,不太适合给别人用.
工厂方法:
工厂接口:与产品接口一一对应;
具体工厂:一个具体工厂对应一个具体产品;
产品接口:
具体产品:
interface IFactory{
Product getProduct();
}
class FactoryA implements IFactory {
@Override
public Product getProduct() {
return new ProductA();
}
}
class FactoryB implements IFactory {
@Override
public Product getProduct() {
return new ProductB();
}
}
class FactoryC implements IFactory {
@Override
public Product getProduct() {
return new ProductC();
}
}
interface Product{
void method();
}
class ProductA implements Product{
@Override
public void method() {
System.out.println("ProductA");
}
}
class ProductB implements Product{
@Override
public void method() {
System.out.println("ProductB");
}
}
class ProductC implements Product{
@Override
public void method() {
System.out.println("ProductC");
}
}使用的时候:
IFactory f=new FactoryA();f.getProduct();
评价:工厂方法,每一个具体产品,对应一个工厂.然后把工厂的选择抛给了用户.这种设计模式仅仅相当于一个中介,用于创建对象,当对象创建简单的时候毫无作用,并且凭空的增加了系统的复杂度.除非创建对象的过程真的非常复杂,不然不建议使用.
抽象工厂:
抽象工厂与普通工厂的区别在于:普通工厂面向具体产品,抽象工厂面向具体的系列.代码上的差别在于,抽象工厂接口存在多个方法,多个产品接口融合在一个工厂(普通工厂一个工厂接口对应一个)
一个工厂接口或抽象类:多个产品接口返回
多个具体的工厂类实现:
多个产品接口:
多个产品实现:
public class AbstractFactory {
public static void main(String[] args) {
AFactory apple=new FactoryAppleSerise();
apple.getOpenWin().win();
apple.getCloseWin().closeWin();
AFactory windows=new FactoryWindowsSerise();
windows.getOpenWin().win();
windows.getCloseWin().closeWin();
}
}
interface AFactory{
OpenWinow getOpenWin();
CloseWindow getCloseWin();
}
class FactoryAppleSerise implements AFactory{
@Override
public OpenWinow getOpenWin() {
return new WinInApple();
}
@Override
public CloseWindow getCloseWin() {
return new CloseWinInApple();
}
}
class FactoryWindowsSerise implements AFactory{
@Override
public OpenWinow getOpenWin() {
return new WinInWindows();
}
@Override
public CloseWindow getCloseWin() {
return new CloseWinInWindows();
}
}
interface OpenWinow{
void win();
}
class WinInWindows implements OpenWinow{
@Override
public void win() {
System.out.println("打开windows窗口");
}
}
class WinInApple implements OpenWinow{
@Override
public void win() {
System.out.println("打开Apple窗口");
}
}
interface CloseWindow{
void closeWin();
}
class CloseWinInWindows implements CloseWindow{
@Override
public void closeWin() {
System.out.println("关闭windows窗口");
}
}
class CloseWinInApple implements CloseWindow{
@Override
public void closeWin() {
System.out.println("关闭Apple窗口");
}
}输出结果:
打开Apple窗口关闭Apple窗口
打开windows窗口
关闭windows窗口
评价:为用户分开了错综复杂的产品类,避免用错,减少了类的创建.同样将选择抛给用户,但选择的余地减少了(普通工厂)有多少个产品就有多少个工厂,而这个是有多少个系列就有多少个工厂),逻辑清晰.编码的时候有明显分成系列的时候,建议使用,比如:用不同的数据库实现dao层...
结论:
工厂模式便于他人使用代码,便于修改代码.不是为了批量生成对象,根据自己的业务选取合适的工厂.
版权声明:本文为zzwwcat原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。