标签:
标签: Java与设计模式
从C++转过来的同学要注意一下了, Java比C++多了包的概念, 因此在权限访问符中也多了一个包访问
级别(default
:不写访问控制符, 默认default).
* | private | default | protected | public |
---|---|---|---|---|
类内 | + | + | + | + |
包内 | + | + | + | |
子类 | + | + | ||
全局 | + |
注意:
public
与default
.protected
修饰这些方法.Java Bean规范:
如果一个Java类每个实例变量都被private
修饰, 并为每个实例变量都提供getter/setter
方法, 那么这个类就是一个符合JavaBean
规范的类.
建造者模式: 将一个复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示(将一个产品的内部表示与产品的生成过程分割开来);
建造者模式与抽象工厂的区别:
在建造者模式里,有个指导者(Director)
,由指导者来管理建造者(Builder)
,用户是与指导者联系的,指导者联系建造者最后得到产品。即建造模式可以强制实行一种分步骤进行的建造过程.
如果我们使用了建造者模式,那么用户只需指定需要建造的类型就可以得到他们, 而具体的建造过程和细节就不要关心了.
举个简单的例子,如宇宙飞船,有很多部件: 引擎, 轨道舱, 逃生塔,还有各种小零件等等,如何将这些部件装配成一艘宇宙飞船,这个装配过程非常复杂(需要很好的组装技术), Builder模式就是为了将部件和组装分开.
Product
产品类, 由多个部件组成(假设我们这艘宇宙飞船的建造过程非常复杂)
/**
* 目标对象 - 宇宙飞船
* (代表复杂对象, 拥有复杂的建造过程)
* Created by jifang on 15/12/8.
*/
public class AirShip {
private Engine engine;
private EscapeTower escapeTower;
private OrbitalModule orbitalModule;
public Engine getEngine() {
return engine;
}
public void setEngine(Engine engine) {
this.engine = engine;
}
public EscapeTower getEscapeTower() {
return escapeTower;
}
public void setEscapeTower(EscapeTower escapeTower) {
this.escapeTower = escapeTower;
}
public OrbitalModule getOrbitalModule() {
return orbitalModule;
}
public void setOrbitalModule(OrbitalModule orbitalModule) {
this.orbitalModule = orbitalModule;
}
}
class Engine {
private String description;
public Engine() {
}
public Engine(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
class EscapeTower {
private String description;
public EscapeTower() {
}
public EscapeTower(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
class OrbitalModule {
private String description;
public OrbitalModule() {
}
public OrbitalModule(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
public interface AirShipBuilder {
Engine builtEngine();
EscapeTower builtEscapeTower();
OrbitalModule builtOrbitalModule();
AirShip getProduct(AirShipDirector director);
}
然后我们需要创建一个低端的宇宙飞船, 让这个宇宙飞船的建造者实现这个接口
public class LowAirShipBuilder implements AirShipBuilder {
@Override
public Engine builtEngine() {
System.out.println("\t\t构造低端引擎...");
return new Engine("低端 - 引擎");
}
@Override
public EscapeTower builtEscapeTower() {
System.out.println("\t\t构造低端逃逸塔...");
return new EscapeTower("低端 - 逃逸塔");
}
@Override
public OrbitalModule builtOrbitalModule() {
System.out.println("\t\t构造低端轨道舱...");
return new OrbitalModule("低端 - 轨道舱");
}
@Override
public AirShip getProduct(AirShipDirector director) {
AirShip airShip = new AirShip();
director.directAirShip(airShip);
return airShip;
}
}
Director
来控制建造过程, 也用它来隔离用户与建造过程的关联public abstract class AirShipDirector {
protected AirShipBuilder builder;
public AirShipDirector(AirShipBuilder builder){
this.builder = builder;
}
public abstract void directAirShip(AirShip airShip);
}
此时, 这艘宇宙飞船的构造过程就完全由Director的子类来确定了(是先构造引擎还是先构造逃逸塔)
public class LowAirShipDirector extends AirShipDirector {
public LowAirShipDirector(AirShipBuilder builder) {
super(builder);
}
@Override
public void directAirShip(AirShip airShip) {
airShip.setEngine(builder.builtEngine());
airShip.setEscapeTower(builder.builtEscapeTower());
airShip.setOrbitalModule(builder.builtOrbitalModule());
}
}
/**
* Created by jifang on 15/12/8.
*/
public class Client {
@Test
public void client() {
AirShipBuilder builder = new LowAirShipBuilder();
// 由Director来指导AirShip的构造过程
AirShip airShip = builder.getProduct(new LowAirShipDirector(builder));
System.out.println(airShip.getEngine().getDescription());
System.out.println(airShip.getEscapeTower().getDescription());
System.out.println(airShip.getOrbitalModule().getDescription());
}
}
建造者模式的本质:
- 分离了对象子模块的单独构造
(由Builder负责)和装配
(有Director负责)过程. 从而可以构造出复杂的对象.
- 由于实现了构建和装配的解耦. 不同的构建器, 相同的装配, 可以做出不同的对象, 反之亦然. 也就是实现了构建算法
与装配算法
的解耦, 实现了更好的复用;
开发中应用场景:
建造者模式适用于建造的目标对象十分庞大, 比如像宇宙飞船
, iPhone手机
, 涉及的组件非常多, 建造过程复杂的情况.
SqlSessionFactoryBuilder
其实对建造者模式做了简化处理(因为其只有Builder而没有Director),这样就减少了我们的实际开发中的编程复杂度.
/**
* @author Clinton Begin
*/
public class SqlSessionFactoryBuilder {
public SqlSessionFactory build(Reader reader) {
return build(reader, null, null);
}
public SqlSessionFactory build(Reader reader, String environment) {
return build(reader, environment, null);
}
public SqlSessionFactory build(Reader reader, Properties properties) {
return build(reader, null, properties);
}
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
}
public SqlSessionFactory build(InputStream inputStream, String environment) {
return build(inputStream, environment, null);
}
public SqlSessionFactory build(InputStream inputStream, Properties properties) {
return build(inputStream, null, properties);
}
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
}
由于SqlSessionFactory
创建的SqlSession
需要支持的操作很多, 如selectOne
, selectList
, update
等, 可以想象,SqlSessionFactory
的构造是很复杂的(细节请参考下面的xml代码), 因此, MyBatis
为他做了一个Builder, 我们可以为该类传进一个配置文件来构造SqlSessionFactory
(其实, 这个配置文件我们可以认为是一个Director).
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mybatis/mapper/*DAO.xml"/>
<property name="typeAliases" value="com.feiqing.domain.User"/>
<property name="configLocation" value="classpath:mybatis/mybatis-configuration.xml"/>
</bean>
由此, 我们可以看到Builder模式是如何用到MyBatis中的.
参考:
标签:
原文地址:http://blog.csdn.net/zjf280441589/article/details/50364975