0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MATLAB言語で学ぶ「Java言語で学ぶデザインパターン入門」ノート #8 Abstract Factory

Posted at

概要

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>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?