<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>設計 on okuzawatsの日記</title><link>https://okuzawats.com/categories/%E8%A8%AD%E8%A8%88/</link><description>Recent content in 設計 on okuzawatsの日記</description><generator>Hugo</generator><language>ja</language><copyright>© 2019 okuzawats</copyright><lastBuildDate>Sun, 30 Apr 2023 15:25:53 +0900</lastBuildDate><atom:link href="https://okuzawats.com/categories/%E8%A8%AD%E8%A8%88/index.xml" rel="self" type="application/rss+xml"/><item><title>[設計] リスコフの置換原則（LSP）</title><link>https://okuzawats.com/blog/square-violate-lsp/</link><pubDate>Sun, 30 Apr 2023 15:25:53 +0900</pubDate><guid>https://okuzawats.com/blog/square-violate-lsp/</guid><description>リスコフの置換原則（The Liskov Substitution Principle: LSP） に違反する例として、Rectangleクラスを継承したSquareクラスの例を複数の書籍で目にしました（Robert (2004)、Michael (2009)、Robert (2018)）。何故、Squareクラスはリスコフの置換原則に違反するのでしょうか。
リスコフの置換原則とは、以下のように要約されます。
派生型はその基本型と置換可能でなければならない。（Robert, (2004), p.144）
Rectangleクラスは長方形を表すクラスで、幅（width）と高さ（height）を持ち、幅と高さから面積（area）を計算することができます。
public class Rectangle { public Rectangle(int width, int height) { /* 略 */ } private int width; private int height; public void setWidth(int width) { /* 略 */ } public void setHeight(int height) { /* 略 */ } public int getArea() { /* 略 */ } } Squareクラスは正方形を表すクラスで、リスコフの置換原則に違反する例では、Rectangleを継承します。正方形は長方形の一種、というわけです。正方形の幅と高さは定義により常に等しいです。
public Square(int size) { /* 略 */ } Squareを親クラスのRectangle型としてインスタンス化してみます。</description></item><item><title>[設計] 自己カプセル化</title><link>https://okuzawats.com/blog/self-encapsulation/</link><pubDate>Sun, 05 Jun 2022 06:28:00 +0900</pubDate><guid>https://okuzawats.com/blog/self-encapsulation/</guid><description>自己カプセル化（Self-Encupsulation） は、クラスの持つフィールドに対してクラス内部からアクセスする場合もアクセサメソッドを経由して行うパターンです。
以下のコード（Javaっぽい疑似コードです）は、自己カプセル化のパターンを適用する前のコードです。コンストラクタおよび getUserName で、アクセサメソッドを経由せずに firstName 、 lastName にアクセスしています。
class UserName { private String firstName; private String lastName; public UserName(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getUserName() { return firstName + &amp;#34; &amp;#34; + lastName; } } firstName と lastName に対するアクセサメソッドを追加して、 firstName 、 lastName へのアクセスをアクセサメソッド経由に変更します。
class UserName { private String firstName; private String lastName; public UserName(String firstName, String lastName) { setFirstName(firstName); setLastName(lastName); } public String getUserName() { return getFirstName() + &amp;#34; &amp;#34; + getLastName(); } private void setFirstName(String firstName) { this.</description></item><item><title>[設計] 設計原則</title><link>https://okuzawats.com/blog/design-principle/</link><pubDate>Thu, 31 Mar 2022 05:59:00 +0900</pubDate><guid>https://okuzawats.com/blog/design-principle/</guid><description>ソフトウェアの設計には、「設計原則（Design Principle）」が存在します。ソフトウェアの設計に関して先人たちが考えてきた原則です。設計原則には、例えば、単一責任の原則やオープン・クローズドの原則といったものがあります。
「Head Firstデザインパターン」(Eric他 (2005)) には、設計原則について以下の記述が見つかります。
実際にはどの原則も法則ではなく、すべての原則はそれらが便利になるときと場合に使用すべきものです。すべての設計には（抽象化対速度、空間対時間などの）トレードオフがあります。原則は指針を提供しますが、すべての要因を考慮に入れてからそれらを適用すべきなのです。（Eric他、Head Firstデザインパターン（2005）、p.267）
ここでは、（ある条件のもので）必ず守られなければならない法則という概念に対して、原則という概念はあくまで指針であり、全ての要因を考慮して適用する（あるいは適用しない）ことを決定することのできるものである、ということが述べられています。
つまり、単一責任の原則やオープン・クローズドの原則といった設計原則は、その設計原則がもたらすメリットとデメリットを考えて適用すべきもの、ということです。設計原則は、常に守られなければならない法則ではなく、あくまで原則にすぎないのです。もちろん、むやみやたらに原則から外れてしまうことを許すべきではありませんが、何故原則があるのかを理解した上で、あえて原則から外れることは許容されるものなのです。
Reference Eric Freeman、Elisabeth Freeman、Kathy Sierra、Bert Bates、Head Firstデザインパターン（2005）、オライリー・ジャパン</description></item><item><title>[設計] 依存性注入（DI）</title><link>https://okuzawats.com/blog/dependency-injection/</link><pubDate>Mon, 24 Jan 2022 22:34:00 +0900</pubDate><guid>https://okuzawats.com/blog/dependency-injection/</guid><description>DI（Dependency Injection、依存性注入）とは何かということと、何故DIを行うのかということをここに書きます。
DI（Dependency Injection、依存性注入）とは DIは、理解してしまえばシンプルな考え方です。
まずはDIを行わないパターンのコードを見てみます。プログラミング言語はKotlinですが、DIの考え方についてはプログラミング言語によらないので、コードについては参考程度に考えてください。
以下のコードでは、AwesomeClassがSomeClassを持っています。SomeClassのインスタンスは、AwesomeClassが生成しています。Kotlinの入門書に出てきそうな、普通のコードです。
class AwesomeClass() { val someClass: SomeClass = SomeClass() } 次に、DIを行うパターンのコードを見てみます。あまりKotlinらしくないコードな気はしますが、Kotlinに慣れていない方への説明のためにこうしています。
class AwesomeClass constructor(val someClass: SomeClass) 1個目のパターンではクラスの内部でSomeClassのインスタンスを生成しているのに対して、2個目のパターンではAwesomeClassのコンストラクタでSomeClassのインスタンスを受け取っているのがわかるかと思います。1個目の例の「生成している」に対する2個目の例の「受け取っている」という表現がミソで、これを「SomeClassのインスタンスを外部から注入している」と考えるのがDIです。DIというのは、突き詰めるとこれだけのことです。
補足としては、上記2個目のパターンのようにコンストラクタでインスタンスを渡すことを「コンストラクタインジェクション（Constructor Injection）」と呼びます。その他に、外部からsetterを呼ぶことでインスタンスを渡す場合がありますが、このことは「セッターインジェクション（Setter Injection）」と呼びます。
DIとはこれだけのことなのですが、これだけのことが、プログラムを驚くほど柔軟にしてくれるのです。
DIの活用 こんな感じのinterfaceがあったとします。
interface Greetable { fun greet() } Greetableを使うHelloクラスを定義します。以下のHelloクラスは、Helloクラス自身がGreetableのインスタンスを生成しています。GreetableのインスタンスをDIしないパターンの実装です。
class Hello { private val greetable: Greetable = object : Greetable { override fun greet() { println(&amp;#34;Hello!&amp;#34;) } } fun greet() { greetable.greet() } } コードから想像がつくと思いますが、このクラスは以下のように用います。
fun main(args: Array&amp;lt;String&amp;gt;) { val hello = Hello() hello.</description></item><item><title>[設計] 依存関係逆転の原則</title><link>https://okuzawats.com/blog/dip/</link><pubDate>Sat, 04 Dec 2021 00:00:00 +0900</pubDate><guid>https://okuzawats.com/blog/dip/</guid><description>この記事はフラー株式会社 Advent Calendar 2021の4日目の記事です。
フラー株式会社 Advent Calendar 2021のカレンダー | Advent Calendar 2021 - Qiita 3日目の記事は @masaya82 さんによる「スクリーンリーダー対応の備忘録 - Qiita」でした。
依存関係逆転の原則 書籍「Clean Architecture 達人に学ぶソフトウェアの構造と設計」（以下、Clean Architectureと呼ぶ。本記事でのClean Architectureとは、本書のことを指す）を読んでいると、中盤に差し掛かったところでSOLID原則の話が出てきます。
SOLID原則の話の中で依存関係逆転の原則に触れられていますが、自分は長らくこの原則の意味がよく理解できませんでした。最近になって「もしかしてこういう意味なのかもしらん」というくらいの理解が得られてきましたのでテキストにしてみました、というのがこの記事です。
よく出てくる図 Clean Architectureには、こんな感じの図が出てきます。
Fig-1 よく出てくる図（Robert、p.105より筆者作成） まずはこの図をよく見て&amp;hellip;忘れます。
依存関係とは 依存関係逆転の原則とは、依存関係が逆転するという原則です。では、依存関係とはなんでしょうか。
難しく考える必要はありません。 A というモジュールから B というモジュールを使う、というだけのことを「 A が B に依存する」とお洒落に言い換えているだけです。
具体的なコードにするとこういう状況です。 A から B を使っているので、 A は B に依存している、という状況です。この「 A は B に依存している」という関係を、 A と B の依存関係と呼びます。依存関係とは、つまるところこれだけのことです。
package a; import b.B; public class A { public B b = new B(); public A() { b.</description></item></channel></rss>