概要
Abstract Factory パターンは、複数のインスタンスをまとめて生成するインターフェースを抽象化する、デザインパターンの一つである。
ソースコード
+factory/Item.m
classdef (Abstract) Item < handle
properties (Access = protected)
caption {mustBeTextScalar} = ''
end
methods (Access = public)
function obj = Item(caption)
arguments (Input)
caption {mustBeTextScalar}
end
arguments (Output)
obj(1,1) factory.Item
end
obj.caption = caption;
end
end
end
+factory/Link.m
classdef (Abstract) Link < factory.Item
properties (Access = protected)
url {mustBeTextScalar} = ''
end
methods (Access = public)
function obj = Link(caption, url)
arguments (Input)
caption {mustBeTextScalar}
url {mustBeTextScalar}
end
arguments (Output)
obj(1,1) factory.Link
end
obj = obj@factory.Item(caption);
obj.url = url;
end
end
end
+factory/Tray.m
classdef (Abstract) Tray < factory.Item
properties (Access = protected)
tray(1,:) cell = {}
end
methods (Access = public)
function obj = Tray(caption)
arguments (Input)
caption {mustBeTextScalar}
end
arguments (Output)
obj(1,1) factory.Tray
end
obj = obj@factory.Item(caption);
end
function add(obj, item)
arguments (Input)
obj(1,1) factory.Tray
item(1,1) factory.Item
end
obj.tray{end + 1} = item;
end
end
end
+factory/Page.m
classdef (Abstract) Page < handle
properties (Access = protected)
title {mustBeTextScalar} = ''
author {mustBeTextScalar} = ''
content(1,:) cell = {}
end
methods (Access = public)
function obj = Page(title, author)
arguments (Input)
title {mustBeTextScalar}
author {mustBeTextScalar}
end
arguments (Output)
obj(1,1) factory.Page
end
obj.title = title;
obj.author = author;
end
function add(obj, item)
arguments (Input)
obj(1,1) factory.Page
item(1,1) factory.Item
end
obj.content{end + 1} = item;
end
function output(obj)
arguments (Input)
obj(1,1) factory.Page
end
try
filename = [obj.title, '.html'];
fileID = fopen(filename, 'w');
fprintf(fileID, obj.makeHTML());
fclose(fileID);
disp([filename, ' を作成しました。']);
catch e
disp(e);
end
end
end
methods (Abstract, Access = public)
out = makeHTML(obj)
end
end
+factory/Factory.m
classdef (Abstract) Factory
methods (Static)
function factory = getFactory(classname)
arguments (Input)
classname {mustBeTextScalar}
end
arguments (Output)
factory(1,1) factory.Factory
end
try
factory = feval(classname);
catch e
switch e.identifier
case 'MATLAB:UndefinedFunction'
fprintf(2, ['クラス ', classname, ' が見つかりません。']);
otherwise
disp(e);
end
end
end
end
methods (Abstract)
out = createLink(obj, caption, url)
out = createTray(obj, caption)
out = createPage(obj, title, author)
end
end
main.m
function main(concreteFactoryName)
if nargin ~= 1
disp('Usage: main class.name.of.ConcreteFactory');
disp('Example 1: main listfactory.ListFactory');
disp('Example 2: main tablefactory.TableFactory');
return;
end
import factory.Factory;
factory = Factory.getFactory(concreteFactoryName);
asahi = factory.createLink('朝日新聞', 'http://www.asahi.com/');
yomiuri = factory.createLink('読売新聞', 'http://www.yomiuri.co.jp/');
us_yahoo = factory.createLink('Yahoo!', 'http://www.yahoo.com/');
jp_yahoo = factory.createLink('Yahoo!Japan', 'http://www.yahoo.co.jp/');
excite = factory.createLink('Excite', 'http://www.excite.com/');
google = factory.createLink('Google', 'http://www.google.com/');
traynews = factory.createTray('新聞');
traynews.add(asahi);
traynews.add(yomiuri);
trayyahoo = factory.createTray('Yahoo!');
trayyahoo.add(us_yahoo);
trayyahoo.add(jp_yahoo);
traysearch = factory.createTray('サーチエンジン');
traysearch.add(trayyahoo);
traysearch.add(excite);
traysearch.add(google);
page = factory.createPage('LinkPage', '結城 浩');
page.add(traynews);
page.add(traysearch);
page.output();
end
+listfactory:ListFactory.m
classdef ListFactory < factory.Factory
methods (Access = public)
function out = createLink(~, caption, url)
arguments (Input)
~ % listfactory.ListFactory
caption {mustBeTextScalar}
url {mustBeTextScalar}
end
arguments (Output)
out(1,1) listfactory.ListLink
end
out = listfactory.ListLink(caption, url);
end
function out = createTray(~, caption)
arguments (Input)
~ % listfactory.ListFactory
caption {mustBeTextScalar}
end
arguments (Output)
out(1,1) listfactory.ListTray
end
out = listfactory.ListTray(caption);
end
function out = createPage(~, title, author)
arguments (Input)
~ % listfactory.ListFactory
title {mustBeTextScalar}
author {mustBeTextScalar}
end
arguments (Output)
out(1,1) listfactory.ListPage
end
out = listfactory.ListPage(title, author);
end
end
end
ListLink.m
classdef ListLink < factory.Link
methods (Access = public)
function obj = ListLink(caption, url)
arguments (Input)
caption {mustBeTextScalar}
url {mustBeTextScalar}
end
arguments (Output)
obj(1,1) listfactory.ListLink
end
obj = obj@factory.Link(caption, url);
end
function out = makeHTML(obj)
arguments (Input)
obj(1,1) listfactory.ListLink
end
arguments (Output)
out {mustBeTextScalar}
end
out = [' <li><a href="', obj.url, '">', obj.caption, '</a></li>', newline];
end
end
end
ListTray.m
classdef ListTray < factory.Tray
methods (Access = public)
function obj = ListTray(caption)
arguments (Input)
caption {mustBeTextScalar}
end
arguments (Output)
obj(1,1) listfactory.ListTray
end
obj = obj@factory.Tray(caption);
end
function out = makeHTML(obj)
arguments (Input)
obj(1,1) listfactory.ListTray
end
arguments (Output)
out {mustBeTextScalar}
end
out = ['<li>', newline];
out = [out, obj.caption, newline];
out = [out, '<ul>', newline];
for k = 1:length(obj.tray)
out = [out, obj.tray{k}.makeHTML()];
end
out = [out, '</ul>', newline];
out = [out, '</li>', newline];
end
end
end
ListPage.m
classdef ListPage < factory.Page
methods (Access = public)
function obj = ListPage(title, author)
arguments (Input)
title {mustBeTextScalar}
author {mustBeTextScalar}
end
arguments (Output)
obj(1,1) listfactory.ListPage
end
obj = obj@factory.Page(title, author);
end
function out = makeHTML(obj)
arguments (Input)
obj(1,1) listfactory.ListPage
end
arguments (Output)
out {mustBeTextScalar}
end
out = ['<html><head><title>', obj.title, '</title></head>', newline];
out = [out, '<body>', newline];
out = [out, '<h1>', obj.title, '</h1>', newline];
out = [out, '<ul>', newline];
for k = 1:length(obj.content)
out = [out, obj.content{k}.makeHTML()];
end
out = [out, '</ul>', newline];
out = [out, '<hr><address>', obj.author, '</address>'];
out = [out, '</body></html>'];
end
end
end
実行結果
>> main tablefactory.TableFactory
LinkPage.html を作成しました。
ListPage.html
<html><head><title>LinkPage</title></head>
<body>
<h1>LinkPage</h1>
<table width="80%" border="3">
<tr><td>
<table width="100%" border="1"><tr><td bgcolor="#cccccc" align="center" colspan="2"><b>新聞</b></td></tr>
<tr>
<td><a href="http://www.asahi.com/">朝日新聞</a></td>
<td><a href="http://www.yomiuri.co.jp/">読売新聞</a></td>
</tr></table>
</td>
</tr><tr><td>
<table width="100%" border="1"><tr><td bgcolor="#cccccc" align="center" colspan="3"><b>サーチエンジン</b></td></tr>
<tr>
<td>
<table width="100%" border="1"><tr><td bgcolor="#cccccc" align="center" colspan="2"><b>Yahoo!</b></td></tr>
<tr>
<td><a href="http://www.yahoo.com/">Yahoo!</a></td>
<td><a href="http://www.yahoo.co.jp/">Yahoo!Japan</a></td>
</tr></table>
</td>
<td><a href="http://www.excite.com/">Excite</a></td>
<td><a href="http://www.google.com/">Google</a></td>
</tr></table>
</td>
</tr></table>
<hr><address>結城 浩</address></body></html>
ソースコード2
TableFactory.m
classdef TableFactory < factory.Factory
methods (Access = public)
function out = createLink(~, caption, url)
arguments (Input)
~ % tablefactory.TableFactory
caption {mustBeTextScalar}
url {mustBeTextScalar}
end
arguments (Output)
out(1,1) tablefactory.TableLink
end
out = tablefactory.TableLink(caption, url);
end
function out = createTray(~, caption)
arguments (Input)
~ % tablefactory.TableFactory
caption {mustBeTextScalar}
end
arguments (Output)
out(1,1) tablefactory.TableTray
end
out = tablefactory.TableTray(caption);
end
function out = createPage(~, title, author)
arguments (Input)
~ % tablefactory.TableFactory
title {mustBeTextScalar}
author {mustBeTextScalar}
end
arguments (Output)
out(1,1) tablefactory.TablePage
end
out = tablefactory.TablePage(title, author);
end
end
end
TableLink.m
classdef TableLink < factory.Link
methods (Access = public)
function obj = TableLink(caption, url)
arguments (Input)
caption {mustBeTextScalar}
url {mustBeTextScalar}
end
arguments (Output)
obj(1,1) tablefactory.TableLink
end
obj = obj@factory.Link(caption, url);
end
function out = makeHTML(obj)
arguments (Input)
obj(1,1) tablefactory.TableLink
end
arguments (Output)
out {mustBeTextScalar}
end
out = ['<td><a href="', obj.url, '">', obj.caption, '</a></td>', newline];
end
end
end
TableTray.m
classdef TableTray < factory.Tray
methods (Access = public)
function obj = TableTray(caption)
arguments (Input)
caption {mustBeTextScalar}
end
arguments (Output)
obj(1,1) tablefactory.TableTray
end
obj = obj@factory.Tray(caption);
end
function out = makeHTML(obj)
arguments (Input)
obj(1,1) tablefactory.TableTray
end
arguments (Output)
out {mustBeTextScalar}
end
out = ['<td>', newline];
out = [out, '<table width="100%%" border="1"><tr>'];
out = [out, '<td bgcolor="#cccccc" align="center" colspan="', num2str(length(obj.tray)), '"><b>', obj.caption, '</b></td>'];
out = [out, '</tr>', newline];
out = [out, '<tr>', newline];
for k = 1:length(obj.tray)
out = [out, obj.tray{k}.makeHTML()];
end
out = [out, '</tr></table>', newline];
out = [out, '</td>', newline];
end
end
end
TablePage.m
classdef TablePage < factory.Page
methods (Access = public)
function obj = TablePage(title, author)
arguments (Input)
title {mustBeTextScalar}
author {mustBeTextScalar}
end
arguments (Output)
obj(1,1) tablefactory.TablePage
end
obj = obj@factory.Page(title, author);
end
function out = makeHTML(obj)
arguments (Input)
obj(1,1) tablefactory.TablePage
end
arguments (Output)
out {mustBeTextScalar}
end
out = ['<html><head><title>', obj.title, '</title></head>', newline];
out = [out, '<body>', newline];
out = [out, '<h1>', obj.title, '</h1>', newline];
out = [out, '<table width="80%%" border="3">', newline];
for k = 1:length(obj.content)
out = [out, '<tr>', obj.content{k}.makeHTML(), '</tr>'];
end
out = [out, '</table>', newline];
out = [out, '<hr><address>', obj.author, '</address>'];
out = [out, '</body></html>'];
end
end
end
実行結果2
>> main listfactory.ListFactory
LinkPage.html を作成しました。
LinkPage.html
<html><head><title>LinkPage</title></head>
<body>
<h1>LinkPage</h1>
<ul>
<li>
新聞
<ul>
<li><a href="http://www.asahi.com/">朝日新聞</a></li>
<li><a href="http://www.yomiuri.co.jp/">読売新聞</a></li>
</ul>
</li>
<li>
サーチエンジン
<ul>
<li>
Yahoo!
<ul>
<li><a href="http://www.yahoo.com/">Yahoo!</a></li>
<li><a href="http://www.yahoo.co.jp/">Yahoo!Japan</a></li>
</ul>
</li>
<li><a href="http://www.excite.com/">Excite</a></li>
<li><a href="http://www.google.com/">Google</a></li>
</ul>
</li>
</ul>
<hr><address>結城 浩</address></body></html>