使用构建器模式的一些常见的、真实的例子是什么?它能给你买什么?为什么不直接使用工厂模式?
当前回答
在浏览微软MVC框架时,我对构建器模式有了一些想法。我在ControllerBuilder类中遇到了这种模式。这个类返回控制器工厂类,然后用它来构建具体的控制器。
我认为使用构建器模式的优点是,您可以创建自己的工厂并将其插入到框架中。
@Tetha,可以有一家意大利人开的餐厅(框架),供应披萨。为了准备披萨,Italian guy (Object Builder)使用Owen (Factory)和一个披萨基(基类)。
现在印度人从意大利人手里接管了餐厅。印度餐厅(框架)提供dosa而不是披萨。为了准备dosa, Indian guy(对象构建器)使用fried Pan(工厂)和Maida(基类)
如果你看场景,食物是不同的,食物的制作方式是不同的,但在同一家餐厅(在同一框架下)。餐馆应该以这样一种方式建造,它可以支持中国菜、墨西哥菜或任何菜。框架内的对象构建器有助于你想要的插件料理。例如
class RestaurantObjectBuilder
{
IFactory _factory = new DefaultFoodFactory();
//This can be used when you want to plugin the
public void SetFoodFactory(IFactory customFactory)
{
_factory = customFactory;
}
public IFactory GetFoodFactory()
{
return _factory;
}
}
其他回答
. net StringBuilder类是构建器模式的一个很好的例子。它主要用于在一系列步骤中创建字符串。执行ToString()的最终结果始终是一个字符串,但该字符串的创建取决于使用StringBuilder类中的哪些函数。总而言之,基本思想是构建复杂的对象,并隐藏如何构建对象的实现细节。
对于多线程问题,我们需要为每个线程构建一个复杂的对象。对象表示正在处理的数据,并且可以根据用户输入进行更改。
我们能用工厂代替吗?是的
为什么我们没有呢?我想建造者更有意义。
工厂用于创建具有相同基本类型的不同类型的对象(实现相同的接口或基类)。
构建器一遍又一遍地构建同一类型的对象,但是构造是动态的,因此可以在运行时更改它。
/// <summary>
/// Builder
/// </summary>
public interface IWebRequestBuilder
{
IWebRequestBuilder BuildHost(string host);
IWebRequestBuilder BuildPort(int port);
IWebRequestBuilder BuildPath(string path);
IWebRequestBuilder BuildQuery(string query);
IWebRequestBuilder BuildScheme(string scheme);
IWebRequestBuilder BuildTimeout(int timeout);
WebRequest Build();
}
/// <summary>
/// ConcreteBuilder #1
/// </summary>
public class HttpWebRequestBuilder : IWebRequestBuilder
{
private string _host;
private string _path = string.Empty;
private string _query = string.Empty;
private string _scheme = "http";
private int _port = 80;
private int _timeout = -1;
public IWebRequestBuilder BuildHost(string host)
{
_host = host;
return this;
}
public IWebRequestBuilder BuildPort(int port)
{
_port = port;
return this;
}
public IWebRequestBuilder BuildPath(string path)
{
_path = path;
return this;
}
public IWebRequestBuilder BuildQuery(string query)
{
_query = query;
return this;
}
public IWebRequestBuilder BuildScheme(string scheme)
{
_scheme = scheme;
return this;
}
public IWebRequestBuilder BuildTimeout(int timeout)
{
_timeout = timeout;
return this;
}
protected virtual void BeforeBuild(HttpWebRequest httpWebRequest) {
}
public WebRequest Build()
{
var uri = _scheme + "://" + _host + ":" + _port + "/" + _path + "?" + _query;
var httpWebRequest = WebRequest.CreateHttp(uri);
httpWebRequest.Timeout = _timeout;
BeforeBuild(httpWebRequest);
return httpWebRequest;
}
}
/// <summary>
/// ConcreteBuilder #2
/// </summary>
public class ProxyHttpWebRequestBuilder : HttpWebRequestBuilder
{
private string _proxy = null;
public ProxyHttpWebRequestBuilder(string proxy)
{
_proxy = proxy;
}
protected override void BeforeBuild(HttpWebRequest httpWebRequest)
{
httpWebRequest.Proxy = new WebProxy(_proxy);
}
}
/// <summary>
/// Director
/// </summary>
public class SearchRequest
{
private IWebRequestBuilder _requestBuilder;
public SearchRequest(IWebRequestBuilder requestBuilder)
{
_requestBuilder = requestBuilder;
}
public WebRequest Construct(string searchQuery)
{
return _requestBuilder
.BuildHost("ajax.googleapis.com")
.BuildPort(80)
.BuildPath("ajax/services/search/web")
.BuildQuery("v=1.0&q=" + HttpUtility.UrlEncode(searchQuery))
.BuildScheme("http")
.BuildTimeout(-1)
.Build();
}
public string GetResults(string searchQuery) {
var request = Construct(searchQuery);
var resp = request.GetResponse();
using (StreamReader stream = new StreamReader(resp.GetResponseStream()))
{
return stream.ReadToEnd();
}
}
}
class Program
{
/// <summary>
/// Inside both requests the same SearchRequest.Construct(string) method is used.
/// But finally different HttpWebRequest objects are built.
/// </summary>
static void Main(string[] args)
{
var request1 = new SearchRequest(new HttpWebRequestBuilder());
var results1 = request1.GetResults("IBM");
Console.WriteLine(results1);
var request2 = new SearchRequest(new ProxyHttpWebRequestBuilder("localhost:80"));
var results2 = request2.GetResults("IBM");
Console.WriteLine(results2);
}
}
我在自制消息库中使用了builder。库核心从线路接收数据,用Builder实例收集数据,然后,一旦Builder确定它已经获得了创建Message实例所需的一切,Builder. getmessage()就使用从线路收集的数据构造消息实例。
构建器的另一个优点是,如果您有一个Factory,那么代码中仍然存在一些耦合,因为要让Factory工作,它必须知道它可能创建的所有对象。如果您添加了另一个可以创建的对象,则必须修改工厂类以包括他。这在抽象工厂中也会发生。
另一方面,对于构建器,您只需要为这个新类创建一个新的具体构建器。director类将保持不变,因为它在构造函数中接收构造器。
此外,构建器也有很多种。神风特攻队雇佣兵又给了一个。
推荐文章
- codestyle;把javadoc放在注释之前还是之后?
- 如何在Spring中定义List bean ?
- 将Set<T>转换为List<T>的最简洁的方法
- 在JavaScript中,什么相当于Java的Thread.sleep() ?
- 使用Java重命名文件
- URL从Java中的类路径加载资源
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
- Hibernate中不同的保存方法之间有什么区别?
- Java 8流和数组操作
- Java Regex捕获组
- Openssl不被视为内部或外部命令
- 如何添加自定义方法到Spring Data JPA
- 如何在Ubuntu中设置Java环境路径
- 无法执行dex:在Eclipse中超过GC开销限制
- 有人能解释一下JPA和Hibernate中的mappedBy吗?